root/trunk/libffado/tests/test-echomixer.cpp

Revision 663, 17.6 kB (checked in by ppalmers, 16 years ago)

- Implement backend for ECHO FireWorks? mixer support

Line 
1 /*
2  * Copyright (C) 2007 by Pieter Palmers
3  * Copyright (C) 2005-2007 by Daniel Wagner
4  *
5  * This file is part of FFADO
6  * FFADO = Free Firewire (pro-)audio drivers for linux
7  *
8  * FFADO is based upon FreeBoB
9  *
10  * FFADO is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  * FFADO is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with FFADO; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
22  * MA 02111-1307 USA.
23  *
24  */
25
26 #include <libraw1394/raw1394.h>
27 #include <libiec61883/iec61883.h>
28
29 #include "debugmodule/debugmodule.h"
30
31 #include "libieee1394/configrom.h"
32 #include "libieee1394/ieee1394service.h"
33 #include "libutil/cmd_serialize.h"
34 #include "libavc/general/avc_generic.h"
35
36 #include "fireworks/efc/efc_avc_cmd.h"
37 #include "fireworks/efc/efc_cmds_mixer.h"
38 #include "fireworks/efc/efc_cmds_monitor.h"
39 #include "fireworks/efc/efc_cmds_hardware.h"
40 using namespace FireWorks;
41
42 #include <argp.h>
43 #include <stdlib.h>
44 #include <iostream>
45
46 using namespace std;
47 using namespace AVC;
48 using namespace Util;
49
50 DECLARE_GLOBAL_DEBUG_MODULE;
51
52 #define MAX_ARGS 1000
53
54 ////////////////////////////////////////////////
55 // arg parsing
56 ////////////////////////////////////////////////
57 const char *argp_program_version = "test-echomixer 0.1";
58 const char *argp_program_bug_address = "<ffado-devel@lists.sf.net>";
59 static char doc[] = "test-avccmd -- test program to examine the echo audio mixer.";
60 static char args_doc[] = "NODE_ID";
61 static struct argp_option options[] = {
62     {"verbose",   'v', 0,           0,  "Produce verbose output" },
63     {"port",      'p', "PORT",      0,  "Set port" },
64     {"node",      'n', "NODE",      0,  "Set node" },
65    { 0 }
66 };
67
68 struct arguments
69 {
70     arguments()
71         : nargs ( 0 )
72         , verbose( false )
73         , test( false )
74         , port( 0 )
75         {
76             args[0] = 0;
77         }
78
79     char* args[MAX_ARGS];
80     int   nargs;
81     bool  verbose;
82     bool  test;
83     int   port;
84     int   node;
85 } arguments;
86
87 // Parse a single option.
88 static error_t
89 parse_opt( int key, char* arg, struct argp_state* state )
90 {
91     // Get the input argument from `argp_parse', which we
92     // know is a pointer to our arguments structure.
93     struct arguments* arguments = ( struct arguments* ) state->input;
94
95     char* tail;
96     switch (key) {
97     case 'v':
98         arguments->verbose = true;
99         break;
100     case 't':
101         arguments->test = true;
102         break;
103     case 'p':
104         errno = 0;
105         arguments->port = strtol(arg, &tail, 0);
106         if (errno) {
107             perror("argument parsing failed:");
108             return errno;
109         }
110         break;
111     case 'n':
112         errno = 0;
113         arguments->node = strtol(arg, &tail, 0);
114         if (errno) {
115             perror("argument parsing failed:");
116             return errno;
117         }
118         break;
119     case ARGP_KEY_ARG:
120         if (state->arg_num >= MAX_ARGS) {
121             // Too many arguments.
122             argp_usage (state);
123         }
124         arguments->args[state->arg_num] = arg;
125         arguments->nargs++;
126         break;
127     case ARGP_KEY_END:
128         if(arguments->nargs<0) {
129             printf("not enough arguments\n");
130             return -1;
131         }
132        
133         break;
134     default:
135         return ARGP_ERR_UNKNOWN;
136     }
137     return 0;
138 }
139
140 static struct argp argp = { options, parse_opt, args_doc, doc };
141
142 bool doEfcOverAVC(Ieee1394Service& m_1394Service, int node, EfcCmd &c)
143 {
144     EfcOverAVCCmd cmd( m_1394Service );
145     cmd.setCommandType( AVC::AVCCommand::eCT_Control );
146     cmd.setNodeId( node );
147     cmd.setSubunitType( AVC::eST_Unit  );
148     cmd.setSubunitId( 0xff );
149
150     cmd.setVerbose( DEBUG_LEVEL_NORMAL );
151
152     cmd.m_cmd = &c;
153
154     if ( !cmd.fire()) {
155         debugError( "EfcOverAVCCmd command failed\n" );
156         c.showEfcCmd();
157         return false;
158     }
159
160     if (   c.m_header.retval != EfcCmd::eERV_Ok
161         && c.m_header.retval != EfcCmd::eERV_FlashBusy) {
162         debugError( "EFC command failed\n" );
163         c.showEfcCmd();
164         return false;
165     }
166
167     return true;
168 }
169
170 ///////////////////////////
171 // main
172 //////////////////////////
173 int
174 main(int argc, char **argv)
175 {
176     // arg parsing
177     if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) {
178         fprintf( stderr, "Could not parse command line\n" );
179         exit(-1);
180     }
181     errno = 0;
182
183     Ieee1394Service *m_1394Service = new Ieee1394Service();
184     if ( !m_1394Service ) {
185         debugFatal( "Could not create Ieee1349Service object\n" );
186         return false;
187     }
188
189     if ( !m_1394Service->initialize( arguments.port ) ) {
190         debugFatal( "Could not initialize Ieee1349Service object\n" );
191         delete m_1394Service;
192         m_1394Service = 0;
193         return false;
194     }
195
196     EfcHardwareInfoCmd  m_HwInfo;
197    
198     if (!doEfcOverAVC(*m_1394Service, arguments.node, m_HwInfo)) {
199         debugFatal("Could not obtain FireWorks device info\n");
200         return false;
201     }
202     m_HwInfo.showEfcCmd();
203    
204 //     uint32_t            m_nb_1394_playback_channels;
205 //     uint32_t            m_nb_1394_record_channels;
206 //
207 //     uint32_t            m_nb_phys_audio_out;
208 //     uint32_t            m_nb_phys_audio_in;
209    
210     unsigned int ch=0;
211    
212     uint32_t pbk_vol[m_HwInfo.m_nb_1394_playback_channels][5];
213     uint32_t rec_vol[m_HwInfo.m_nb_1394_record_channels][5];
214     uint32_t out_vol[m_HwInfo.m_nb_phys_audio_out][5];
215     uint32_t in_vol[m_HwInfo.m_nb_phys_audio_in][5];
216    
217     memset(pbk_vol, 0, sizeof(uint32_t) * 5 * m_HwInfo.m_nb_1394_playback_channels);
218     memset(rec_vol, 0, sizeof(uint32_t) * 5 * m_HwInfo.m_nb_1394_record_channels);
219     memset(out_vol, 0, sizeof(uint32_t) * 5 * m_HwInfo.m_nb_phys_audio_out);
220     memset(in_vol, 0, sizeof(uint32_t) * 5 * m_HwInfo.m_nb_phys_audio_in);
221    
222     for (ch=0;ch<m_HwInfo.m_nb_1394_playback_channels;ch++) {
223         enum eMixerTarget t=eMT_PlaybackMix;
224         {
225             EfcGetGainCmd getCmd(t);
226             getCmd.m_channel=ch;
227             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
228                 debugFatal("Cmd failed\n");
229             }
230             pbk_vol[ch][0]=getCmd.m_value;
231         }
232 //         {
233 //             EfcGetPanCmd getCmd(t);
234 //             getCmd.m_channel=ch;
235 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
236 //                 debugFatal("Cmd failed\n");
237 //             }
238 //             pbk_vol[ch][1]=getCmd.m_value;
239 //         }
240 //         {
241 //             EfcGetSoloCmd getCmd(t);
242 //             getCmd.m_channel=ch;
243 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
244 //                 debugFatal("Cmd failed\n");
245 //             }
246 //             pbk_vol[ch][2]=getCmd.m_value;
247 //         }
248         {
249             EfcGetMuteCmd getCmd(t);
250             getCmd.m_channel=ch;
251             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
252                 debugFatal("Cmd failed\n");
253             }
254             pbk_vol[ch][3]=getCmd.m_value;
255         }
256 //         {
257 //             EfcGetNominalCmd getCmd(t);
258 //             getCmd.m_channel=ch;
259 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
260 //                 debugFatal("Cmd failed\n");
261 //             }
262 //             pbk_vol[ch][4]=getCmd.m_value;
263 //         }
264     }
265    
266 //     for (ch=0;ch<m_HwInfo.m_nb_1394_record_channels;ch++) {
267 //         enum eMixerTarget t=eMT_RecordMix;
268 //         {
269 //             EfcGetGainCmd getCmd(t);
270 //             getCmd.m_channel=ch;
271 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
272 //                 debugFatal("Cmd failed\n");
273 //             }
274 //             rec_vol[ch][0]=getCmd.m_value;
275 //         }
276 //         {
277 //             EfcGetPanCmd getCmd(t);
278 //             getCmd.m_channel=ch;
279 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
280 //                 debugFatal("Cmd failed\n");
281 //             }
282 //             rec_vol[ch][1]=getCmd.m_value;
283 //         }
284 //         {
285 //             EfcGetSoloCmd getCmd(t);
286 //             getCmd.m_channel=ch;
287 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
288 //                 debugFatal("Cmd failed\n");
289 //             }
290 //             rec_vol[ch][2]=getCmd.m_value;
291 //         }
292 //         {
293 //             EfcGetMuteCmd getCmd(t);
294 //             getCmd.m_channel=ch;
295 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
296 //                 debugFatal("Cmd failed\n");
297 //             }
298 //             rec_vol[ch][3]=getCmd.m_value;
299 //         }
300 //         {
301 //             EfcGetNominalCmd getCmd(t);
302 //             getCmd.m_channel=ch;
303 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
304 //                 debugFatal("Cmd failed\n");
305 //             }
306 //             rec_vol[ch][4]=getCmd.m_value;
307 //         }
308 //     }
309
310     for (ch=0;ch<m_HwInfo.m_nb_phys_audio_out;ch++) {
311         enum eMixerTarget t=eMT_PhysicalOutputMix;
312         {
313             EfcGetGainCmd getCmd(t);
314             getCmd.m_channel=ch;
315             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
316                 debugFatal("Cmd failed\n");
317             }
318             out_vol[ch][0]=getCmd.m_value;
319         }
320 //         {
321 //             EfcGetPanCmd getCmd(t);
322 //             getCmd.m_channel=ch;
323 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
324 //                 debugFatal("Cmd failed\n");
325 //             }
326 //             out_vol[ch][1]=getCmd.m_value;
327 //         }
328 //         {
329 //             EfcGetSoloCmd getCmd(t);
330 //             getCmd.m_channel=ch;
331 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
332 //                 debugFatal("Cmd failed\n");
333 //             }
334 //             out_vol[ch][2]=getCmd.m_value;
335 //         }
336         {
337             EfcGetMuteCmd getCmd(t);
338             getCmd.m_channel=ch;
339             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
340                 debugFatal("Cmd failed\n");
341             }
342             out_vol[ch][3]=getCmd.m_value;
343         }
344         {
345             EfcGetNominalCmd getCmd(t);
346             getCmd.m_channel=ch;
347             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
348                 debugFatal("Cmd failed\n");
349             }
350             out_vol[ch][4]=getCmd.m_value;
351         }
352     }
353
354 //     for (ch=0;ch<m_HwInfo.m_nb_phys_audio_in;ch++) {
355 //         enum eMixerTarget t=eMT_PhysicalInputMix;
356 //         {
357 //             EfcGetGainCmd getCmd(t);
358 //             getCmd.m_channel=ch;
359 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
360 //                 debugFatal("Cmd failed\n");
361 //             }
362 //             in_vol[ch][0]=getCmd.m_value;
363 //         }
364 //         {
365 //             EfcGetPanCmd getCmd(t);
366 //             getCmd.m_channel=ch;
367 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
368 //                 debugFatal("Cmd failed\n");
369 //             }
370 //             in_vol[ch][1]=getCmd.m_value;
371 //         }
372 //         {
373 //             EfcGetSoloCmd getCmd(t);
374 //             getCmd.m_channel=ch;
375 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
376 //                 debugFatal("Cmd failed\n");
377 //             }
378 //             in_vol[ch][2]=getCmd.m_value;
379 //         }
380 //         {
381 //             EfcGetMuteCmd getCmd(t);
382 //             getCmd.m_channel=ch;
383 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
384 //                 debugFatal("Cmd failed\n");
385 //             }
386 //             in_vol[ch][3]=getCmd.m_value;
387 //         }
388 //         {
389 //             EfcGetNominalCmd getCmd(t);
390 //             getCmd.m_channel=ch;
391 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
392 //                 debugFatal("Cmd failed\n");
393 //             }
394 //             in_vol[ch][4]=getCmd.m_value;
395 //         }
396 //     }
397
398     uint32_t monitor_gain[m_HwInfo.m_nb_phys_audio_in][m_HwInfo.m_nb_phys_audio_out];
399     for (unsigned int ch_in=0;ch_in<m_HwInfo.m_nb_phys_audio_in;ch_in++) {
400         for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
401             {
402                 EfcGetMonitorGainCmd getCmd;
403                 getCmd.m_input=ch_in;
404                 getCmd.m_output=ch_out;
405                 if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
406                     debugFatal("Cmd failed\n");
407                 }
408                 monitor_gain[ch_in][ch_out]=getCmd.m_value;
409             }
410         }
411     }
412     uint32_t monitor_pan[m_HwInfo.m_nb_phys_audio_in][m_HwInfo.m_nb_phys_audio_out];
413     for (unsigned int ch_in=0;ch_in<m_HwInfo.m_nb_phys_audio_in;ch_in++) {
414         for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
415             {
416                 EfcGetMonitorPanCmd getCmd;
417                 getCmd.m_input=ch_in;
418                 getCmd.m_output=ch_out;
419                 if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
420                     debugFatal("Cmd failed\n");
421                 }
422                 monitor_pan[ch_in][ch_out]=getCmd.m_value;
423             }
424         }
425     }
426     uint32_t monitor_mute[m_HwInfo.m_nb_phys_audio_in][m_HwInfo.m_nb_phys_audio_out];
427     for (unsigned int ch_in=0;ch_in<m_HwInfo.m_nb_phys_audio_in;ch_in++) {
428         for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
429             {
430                 EfcGetMonitorMuteCmd getCmd;
431                 getCmd.m_input=ch_in;
432                 getCmd.m_output=ch_out;
433                 if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
434                     debugFatal("Cmd failed\n");
435                 }
436                 monitor_mute[ch_in][ch_out]=getCmd.m_value;
437             }
438         }
439     }
440
441     uint32_t monitor_solo[m_HwInfo.m_nb_phys_audio_in][m_HwInfo.m_nb_phys_audio_out];
442     for (unsigned int ch_in=0;ch_in<m_HwInfo.m_nb_phys_audio_in;ch_in++) {
443         for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
444             {
445                 EfcGetMonitorSoloCmd getCmd;
446                 getCmd.m_input=ch_in;
447                 getCmd.m_output=ch_out;
448                 if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
449                     debugFatal("Cmd failed\n");
450                 }
451                 monitor_solo[ch_in][ch_out]=getCmd.m_value;
452             }
453         }
454     }
455
456     printf("Mixer state info\n");
457     printf("================\n");
458     printf("        %10s %10s %10s %10s %10s\n","GAIN","PAN","SOLO","MUTE","NOMINAL");
459     printf("Playback mixer state:\n");
460     for (ch=0;ch<m_HwInfo.m_nb_1394_playback_channels;ch++) {
461         printf(" ch %2d: ", ch);
462         int j;
463         for (j=0;j<5;j++) {
464             printf("%10u ", pbk_vol[ch][j]);
465         }
466         printf("\n");
467     }
468    
469     printf("Record mixer state:\n");
470     for (ch=0;ch<m_HwInfo.m_nb_1394_record_channels;ch++) {
471         printf(" ch %2d: ", ch);
472         int j;
473         for (j=0;j<5;j++) {
474             printf("%10u ", rec_vol[ch][j]);
475         }
476         printf("\n");
477     }   
478
479     printf("Output mixer state:\n");
480     for (ch=0;ch<m_HwInfo.m_nb_phys_audio_out;ch++) {
481         printf(" ch %2d: ", ch);
482         int j;
483         for (j=0;j<5;j++) {
484             printf("%10u ", out_vol[ch][j]);
485         }
486         printf("\n");
487     }
488    
489     printf("Input mixer state:\n");
490     for (ch=0;ch<m_HwInfo.m_nb_phys_audio_in;ch++) {
491         printf(" ch %2d: ", ch);
492         int j;
493         for (j=0;j<5;j++) {
494             printf("%10u ", in_vol[ch][j]);
495         }
496         printf("\n");
497     }
498    
499     printf("\nMonitor state info\n");
500     printf("==================\n");
501    
502     printf("GAIN  ");
503     for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
504         printf("      OUT%02u",ch_out);
505     }
506     printf("\n");
507    
508     for (unsigned int ch_in=0;ch_in<m_HwInfo.m_nb_phys_audio_in;ch_in++) {
509         printf("ch %2u:", ch_in);
510         for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
511             printf(" %10u", monitor_gain[ch_in][ch_out]);
512         }
513         printf("\n");
514     }
515     printf("\n");
516    
517     printf("PAN   ");
518     for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
519         printf("      OUT%02u",ch_out);
520     }
521     printf("\n");
522    
523     for (unsigned int ch_in=0;ch_in<m_HwInfo.m_nb_phys_audio_in;ch_in++) {
524         printf("ch %2u:", ch_in);
525         for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
526             printf(" %10u", monitor_pan[ch_in][ch_out]);
527         }
528         printf("\n");
529     }
530     printf("\n");
531
532     printf("MUTE  ");
533     for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
534         printf("      OUT%02u",ch_out);
535     }
536     printf("\n");
537    
538     for (unsigned int ch_in=0;ch_in<m_HwInfo.m_nb_phys_audio_in;ch_in++) {
539         printf("ch %2u:", ch_in);
540         for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
541             printf(" %10u", monitor_mute[ch_in][ch_out]);
542         }
543         printf("\n");
544     }
545     printf("\n");
546
547     printf("SOLO  ");
548     for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
549         printf("      OUT%02u",ch_out);
550     }
551     printf("\n");
552    
553     for (unsigned int ch_in=0;ch_in<m_HwInfo.m_nb_phys_audio_in;ch_in++) {
554         printf("ch %2u:", ch_in);
555         for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
556             printf(" %10u", monitor_solo[ch_in][ch_out]);
557         }
558         printf("\n");
559     }
560     printf("\n");
561
562
563     delete m_1394Service;
564
565     return 0;
566 }
567
Note: See TracBrowser for help on using the browser.