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

Revision 1234, 17.7 kB (checked in by holin, 16 years ago)

fix gcc 4.3 compile errors and some warnings (largely from Adrian Knoth)

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  * Copyright (C) 2005-2008 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  * This program 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) version 3 of the License.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #include <libraw1394/raw1394.h>
26 #include <libiec61883/iec61883.h>
27
28 #include "debugmodule/debugmodule.h"
29
30 #include "libieee1394/configrom.h"
31 #include "libieee1394/ieee1394service.h"
32 #include "libutil/cmd_serialize.h"
33 #include "libavc/general/avc_generic.h"
34
35 #include "fireworks/efc/efc_avc_cmd.h"
36 #include "fireworks/efc/efc_cmds_mixer.h"
37 #include "fireworks/efc/efc_cmds_monitor.h"
38 #include "fireworks/efc/efc_cmds_hardware.h"
39 using namespace FireWorks;
40
41 #include <argp.h>
42 #include <iostream>
43 #include <cstdlib>
44 #include <cstring>
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     errno = 0;
97     switch (key) {
98     case 'v':
99         arguments->verbose = true;
100         break;
101     case 't':
102         arguments->test = true;
103         break;
104     case 'p':
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         arguments->node = strtol(arg, &tail, 0);
113         if (errno) {
114             perror("argument parsing failed:");
115             return errno;
116         }
117         break;
118     case ARGP_KEY_ARG:
119         if (state->arg_num >= MAX_ARGS) {
120             // Too many arguments.
121             argp_usage (state);
122         }
123         arguments->args[state->arg_num] = arg;
124         arguments->nargs++;
125         break;
126     case ARGP_KEY_END:
127         if(arguments->nargs<0) {
128             printf("not enough arguments\n");
129             return -1;
130         }
131        
132         break;
133     default:
134         return ARGP_ERR_UNKNOWN;
135     }
136     return 0;
137 }
138
139 static struct argp argp = { options, parse_opt, args_doc, doc };
140
141 bool doEfcOverAVC(Ieee1394Service& m_1394Service, int node, EfcCmd &c)
142 {
143     EfcOverAVCCmd cmd( m_1394Service );
144     cmd.setCommandType( AVC::AVCCommand::eCT_Control );
145     cmd.setNodeId( node );
146     cmd.setSubunitType( AVC::eST_Unit  );
147     cmd.setSubunitId( 0xff );
148
149     cmd.setVerbose( DEBUG_LEVEL_NORMAL );
150
151     cmd.m_cmd = &c;
152
153     if ( !cmd.fire()) {
154         debugError( "EfcOverAVCCmd command failed\n" );
155         c.showEfcCmd();
156         return false;
157     }
158
159     if (   c.m_header.retval != EfcCmd::eERV_Ok
160         && c.m_header.retval != EfcCmd::eERV_FlashBusy) {
161         debugError( "EFC command failed\n" );
162         c.showEfcCmd();
163         return false;
164     }
165
166     return true;
167 }
168
169 ///////////////////////////
170 // main
171 //////////////////////////
172 int
173 main(int argc, char **argv)
174 {
175     // arg parsing
176     if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) {
177         fprintf( stderr, "Could not parse command line\n" );
178         exit(-1);
179     }
180     errno = 0;
181
182     Ieee1394Service *m_1394Service = new Ieee1394Service();
183     if ( !m_1394Service ) {
184         debugFatal( "Could not create Ieee1349Service object\n" );
185         return false;
186     }
187
188     if ( !m_1394Service->initialize( arguments.port ) ) {
189         debugFatal( "Could not initialize Ieee1349Service object\n" );
190         delete m_1394Service;
191         m_1394Service = 0;
192         return false;
193     }
194
195     EfcHardwareInfoCmd  m_HwInfo;
196    
197     if (!doEfcOverAVC(*m_1394Service, arguments.node, m_HwInfo)) {
198         debugFatal("Could not obtain FireWorks device info\n");
199         return false;
200     }
201     m_HwInfo.showEfcCmd();
202
203     unsigned int ch=0;
204    
205     uint32_t pbk_vol[m_HwInfo.m_nb_1394_playback_channels][5];
206     uint32_t rec_vol[m_HwInfo.m_nb_1394_record_channels][5];
207     uint32_t out_vol[m_HwInfo.m_nb_phys_audio_out][5];
208     uint32_t in_vol[m_HwInfo.m_nb_phys_audio_in][5];
209    
210     memset(pbk_vol, 0, sizeof(uint32_t) * 5 * m_HwInfo.m_nb_1394_playback_channels);
211     memset(rec_vol, 0, sizeof(uint32_t) * 5 * m_HwInfo.m_nb_1394_record_channels);
212     memset(out_vol, 0, sizeof(uint32_t) * 5 * m_HwInfo.m_nb_phys_audio_out);
213     memset(in_vol, 0, sizeof(uint32_t) * 5 * m_HwInfo.m_nb_phys_audio_in);
214    
215     enum eMixerTarget t=eMT_PlaybackMix;
216     enum eMixerCommand c = eMC_Gain;
217     enum eCmdType type = eCT_Get;
218     EfcGenericMixerCmd cmd(t,c);
219     cmd.setType(type);
220
221 #define DO_PLAYBACK_MIX
222 // #define DO_RECORD_MIX
223 #define DO_PHYS_OUT_MIX
224 #define DO_PHYS_IN_MIX
225
226 #ifdef DO_PLAYBACK_MIX
227     cmd.setTarget(eMT_PlaybackMix);
228     for (ch=0;ch<m_HwInfo.m_nb_1394_playback_channels;ch++) {
229 //     for (ch=0;ch<1;ch++) {
230         {
231             cmd.setCommand(eMC_Gain);
232             cmd.m_channel=ch;
233             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
234                 debugFatal("Cmd failed\n");
235             }
236             pbk_vol[ch][0]=cmd.m_value;
237         }
238 //         {
239 //             cmd.setCommand(eMC_Solo);
240 //             cmd.m_channel=ch;
241 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
242 //                 debugFatal("Cmd failed\n");
243 //             }
244 //             pbk_vol[ch][1]=cmd.m_value;
245 //         }
246         {
247             cmd.setCommand(eMC_Mute);
248             cmd.m_channel=ch;
249             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
250                 debugFatal("Cmd failed\n");
251             }
252             pbk_vol[ch][2]=cmd.m_value;
253         }
254 //         {
255 //             cmd.setCommand(eMC_Pan);
256 //             cmd.m_channel=ch;
257 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
258 //                 debugFatal("Cmd failed\n");
259 //             }
260 //             pbk_vol[ch][3]=cmd.m_value;
261 //         }
262 //         {
263 //             cmd.setCommand(eMC_Nominal);
264 //             cmd.m_channel=ch;
265 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
266 //                 debugFatal("Cmd failed\n");
267 //             }
268 //             pbk_vol[ch][4]=cmd.m_value;
269 //         }
270     }
271 #endif
272
273 #ifdef DO_RECORD_MIX
274     cmd.setTarget(eMT_RecordMix);
275     for (ch=0;ch<m_HwInfo.m_nb_1394_record_channels;ch++) {
276 //     for (ch=0;ch<1;ch++) {
277         {
278             cmd.setCommand(eMC_Gain);
279             cmd.m_channel=ch;
280             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
281                 debugFatal("Cmd failed\n");
282             }
283             rec_vol[ch][0]=cmd.m_value;
284         }
285         {
286             cmd.setCommand(eMC_Solo);
287             cmd.m_channel=ch;
288             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
289                 debugFatal("Cmd failed\n");
290             }
291             rec_vol[ch][1]=cmd.m_value;
292         }
293         {
294             cmd.setCommand(eMC_Mute);
295             cmd.m_channel=ch;
296             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
297                 debugFatal("Cmd failed\n");
298             }
299             rec_vol[ch][2]=cmd.m_value;
300         }
301         {
302             cmd.setCommand(eMC_Pan);
303             cmd.m_channel=ch;
304             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
305                 debugFatal("Cmd failed\n");
306             }
307             rec_vol[ch][3]=cmd.m_value;
308         }
309         {
310             cmd.setCommand(eMC_Nominal);
311             cmd.m_channel=ch;
312             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
313                 debugFatal("Cmd failed\n");
314             }
315             rec_vol[ch][4]=cmd.m_value;
316         }
317     }
318 #endif
319
320 #ifdef DO_PHYS_OUT_MIX
321     cmd.setTarget(eMT_PhysicalOutputMix);
322     for (ch=0;ch<m_HwInfo.m_nb_phys_audio_out;ch++) {
323 //     for (ch=0;ch<1;ch++) {
324         {
325             cmd.setCommand(eMC_Gain);
326             cmd.m_channel=ch;
327             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
328                 debugFatal("Cmd failed\n");
329             }
330             out_vol[ch][0]=cmd.m_value;
331         }
332 //         {
333 //             cmd.setCommand(eMC_Solo);
334 //             cmd.m_channel=ch;
335 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
336 //                 debugFatal("Cmd failed\n");
337 //             }
338 //             out_vol[ch][1]=cmd.m_value;
339 //         }
340         {
341             cmd.setCommand(eMC_Mute);
342             cmd.m_channel=ch;
343             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
344                 debugFatal("Cmd failed\n");
345             }
346             out_vol[ch][2]=cmd.m_value;
347         }
348 //         {
349 //             cmd.setCommand(eMC_Pan);
350 //             cmd.m_channel=ch;
351 //             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
352 //                 debugFatal("Cmd failed\n");
353 //             }
354 //             out_vol[ch][3]=cmd.m_value;
355 //         }
356         {
357             cmd.setCommand(eMC_Nominal);
358             cmd.m_channel=ch;
359             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
360                 debugFatal("Cmd failed\n");
361             }
362             out_vol[ch][4]=cmd.m_value;
363         }
364     }
365 #endif
366
367 #ifdef DO_PHYS_IN_MIX
368     cmd.setTarget(eMT_PhysicalInputMix);
369     for (ch=0;ch<m_HwInfo.m_nb_phys_audio_in;ch++) {
370 //     for (ch=0;ch<1;ch++) {
371         {
372             cmd.setCommand(eMC_Gain);
373             cmd.m_channel=ch;
374             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
375                 debugFatal("Cmd failed\n");
376             }
377             in_vol[ch][0]=cmd.m_value;
378         }
379         {
380             cmd.setCommand(eMC_Solo);
381             cmd.m_channel=ch;
382             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
383                 debugFatal("Cmd failed\n");
384             }
385             in_vol[ch][1]=cmd.m_value;
386         }
387         {
388             cmd.setCommand(eMC_Mute);
389             cmd.m_channel=ch;
390             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
391                 debugFatal("Cmd failed\n");
392             }
393             in_vol[ch][2]=cmd.m_value;
394         }
395         {
396             cmd.setCommand(eMC_Pan);
397             cmd.m_channel=ch;
398             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
399                 debugFatal("Cmd failed\n");
400             }
401             in_vol[ch][3]=cmd.m_value;
402         }
403         {
404             cmd.setCommand(eMC_Nominal);
405             cmd.m_channel=ch;
406             if (!doEfcOverAVC(*m_1394Service, arguments.node, cmd)) {
407                 debugFatal("Cmd failed\n");
408             }
409             in_vol[ch][4]=cmd.m_value;
410         }
411     }
412 #endif
413
414     uint32_t monitor_gain[m_HwInfo.m_nb_phys_audio_in][m_HwInfo.m_nb_phys_audio_out];
415     for (unsigned int ch_in=0;ch_in<m_HwInfo.m_nb_phys_audio_in;ch_in++) {
416         for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
417             {
418                 EfcGetMonitorGainCmd getCmd;
419                 getCmd.m_input=ch_in;
420                 getCmd.m_output=ch_out;
421                 if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
422                     debugFatal("Cmd failed\n");
423                 }
424                 monitor_gain[ch_in][ch_out]=getCmd.m_value;
425             }
426         }
427     }
428     uint32_t monitor_pan[m_HwInfo.m_nb_phys_audio_in][m_HwInfo.m_nb_phys_audio_out];
429     for (unsigned int ch_in=0;ch_in<m_HwInfo.m_nb_phys_audio_in;ch_in++) {
430         for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
431             {
432                 EfcGetMonitorPanCmd getCmd;
433                 getCmd.m_input=ch_in;
434                 getCmd.m_output=ch_out;
435                 if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
436                     debugFatal("Cmd failed\n");
437                 }
438                 monitor_pan[ch_in][ch_out]=getCmd.m_value;
439             }
440         }
441     }
442     uint32_t monitor_mute[m_HwInfo.m_nb_phys_audio_in][m_HwInfo.m_nb_phys_audio_out];
443     for (unsigned int ch_in=0;ch_in<m_HwInfo.m_nb_phys_audio_in;ch_in++) {
444         for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
445             {
446                 EfcGetMonitorMuteCmd getCmd;
447                 getCmd.m_input=ch_in;
448                 getCmd.m_output=ch_out;
449                 if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
450                     debugFatal("Cmd failed\n");
451                 }
452                 monitor_mute[ch_in][ch_out]=getCmd.m_value;
453             }
454         }
455     }
456
457     uint32_t monitor_solo[m_HwInfo.m_nb_phys_audio_in][m_HwInfo.m_nb_phys_audio_out];
458     for (unsigned int ch_in=0;ch_in<m_HwInfo.m_nb_phys_audio_in;ch_in++) {
459         for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
460             {
461                 EfcGetMonitorSoloCmd getCmd;
462                 getCmd.m_input=ch_in;
463                 getCmd.m_output=ch_out;
464                 if (!doEfcOverAVC(*m_1394Service, arguments.node, getCmd)) {
465                     debugFatal("Cmd failed\n");
466                 }
467                 monitor_solo[ch_in][ch_out]=getCmd.m_value;
468             }
469         }
470     }
471
472     printf("Mixer state info\n");
473     printf("================\n");
474     printf("        %10s %10s %10s %10s %10s\n","GAIN","PAN","SOLO","MUTE","NOMINAL");
475 #ifdef DO_PLAYBACK_MIX
476     printf("Playback mixer state:\n");
477     for (ch=0;ch<m_HwInfo.m_nb_1394_playback_channels;ch++) {
478         printf(" ch %2d: ", ch);
479         int j;
480         for (j=0;j<5;j++) {
481             if (j==0 || j==2)
482                 printf("%10u ", pbk_vol[ch][j]);
483             else
484                 printf("%10s ", "*");
485         }
486         printf("\n");
487     }
488 #endif
489
490 #ifdef DO_RECORD_MIX
491     printf("Record mixer state:\n");
492     for (ch=0;ch<m_HwInfo.m_nb_1394_record_channels;ch++) {
493         printf(" ch %2d: ", ch);
494         int j;
495         for (j=0;j<5;j++) {
496             printf("%10u ", rec_vol[ch][j]);
497         }
498         printf("\n");
499     }   
500 #endif
501
502 #ifdef DO_PHYS_OUT_MIX
503     printf("Output mixer state:\n");
504     for (ch=0;ch<m_HwInfo.m_nb_phys_audio_out;ch++) {
505         printf(" ch %2d: ", ch);
506         int j;
507         for (j=0;j<5;j++) {
508            if (j==0 || j==2 || j==4)
509                 printf("%10u ", out_vol[ch][j]);
510             else
511                 printf("%10s ", "*");
512         }
513         printf("\n");
514     }
515 #endif
516    
517 #ifdef DO_PHYS_IN_MIX
518     printf("Input mixer state:\n");
519     for (ch=0;ch<m_HwInfo.m_nb_phys_audio_in;ch++) {
520         printf(" ch %2d: ", ch);
521         int j;
522         for (j=0;j<5;j++) {
523             printf("%10u ", in_vol[ch][j]);
524         }
525         printf("\n");
526     }
527 #endif
528    
529     printf("\nMonitor state info\n");
530     printf("==================\n");
531    
532     printf("GAIN  ");
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_gain[ch_in][ch_out]);
542         }
543         printf("\n");
544     }
545     printf("\n");
546    
547     printf("PAN   ");
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_pan[ch_in][ch_out]);
557         }
558         printf("\n");
559     }
560     printf("\n");
561
562     printf("MUTE  ");
563     for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
564         printf("      OUT%02u",ch_out);
565     }
566     printf("\n");
567    
568     for (unsigned int ch_in=0;ch_in<m_HwInfo.m_nb_phys_audio_in;ch_in++) {
569         printf("ch %2u:", ch_in);
570         for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
571             printf(" %10u", monitor_mute[ch_in][ch_out]);
572         }
573         printf("\n");
574     }
575     printf("\n");
576
577     printf("SOLO  ");
578     for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
579         printf("      OUT%02u",ch_out);
580     }
581     printf("\n");
582    
583     for (unsigned int ch_in=0;ch_in<m_HwInfo.m_nb_phys_audio_in;ch_in++) {
584         printf("ch %2u:", ch_in);
585         for (unsigned int ch_out=0;ch_out<m_HwInfo.m_nb_phys_audio_out;ch_out++) {
586             printf(" %10u", monitor_solo[ch_in][ch_out]);
587         }
588         printf("\n");
589     }
590     printf("\n");
591
592     delete m_1394Service;
593
594     return 0;
595 }
596
Note: See TracBrowser for help on using the browser.