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

Revision 1254, 14.7 kB (checked in by ppalmers, 16 years ago)

split config.h into config/version/debug_config to allow for faster compilation (splits dependencies)

Line 
1 /*
2  * Copyright (C) 2005-2008 by Daniel Wagner
3  * Copyright (C) 2005-2008 by Pieter Palmers
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 /*
26  * This version uses the CPP API
27  */
28
29 #include "version.h"
30
31 #include "libffado/ffado.h"
32
33 #include "debugmodule/debugmodule.h"
34 #include "fbtypes.h"
35 #include "devicemanager.h"
36 #include "ffadodevice.h"
37
38 #include <signal.h>
39
40 #include <argp.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44
45 #include <vector>
46 #include <string>
47 #include <iostream>
48 #include <sstream>
49
50 #include "libieee1394/cycletimer.h"
51
52 using namespace std;
53
54 DECLARE_GLOBAL_DEBUG_MODULE;
55
56 #define MAX_ARGS 5
57
58 // global's
59 const char *argp_program_version = PACKAGE_STRING;
60 const char *argp_program_bug_address = PACKAGE_BUGREPORT;
61
62 // Program documentation.
63 static char doc[] = "FFADO -- a driver for Firewire Audio devices (test application)\n\n"
64                     "OPERATION: Discover\n"
65                     "           SetSamplerate samplerate\n"
66                     "           SetClockSource [id]\n"
67                     "           BusReset\n"
68                     "           ListDevices\n"
69                     ;
70
71 // A description of the arguments we accept.
72 static char args_doc[] = "OPERATION";
73
74 struct arguments
75 {
76     unsigned int nargs;
77     short    silent;
78     long int verbose;
79     long int port;
80     long int use_cache;
81     long int node_id;
82     long int node_id_set;
83     const char* args[MAX_ARGS];
84 };
85
86 // The options we understand.
87 static struct argp_option options[] = {
88     {"quiet",    'q',       0,    0,  "Don't produce any output" },
89     {"silent",   's',       0,    OPTION_ALIAS },
90
91     {"verbose",  'v', "level",    0,  "Produce verbose output" },
92 #if ENABLE_DISCOVERY_CACHE
93     {"cache",    'c', "enable",   0,  "Use AVC model cache" },
94 #endif
95
96     {"node",     'n',    "id",    0,  "Node to use" },
97     {"port",     'p',    "nr",    0,  "IEEE1394 Port to use" },
98     { 0 }
99 };
100
101 //-------------------------------------------------------------
102
103 // Parse a single option.
104 static error_t
105 parse_opt( int key, char* arg, struct argp_state* state )
106 {
107     // Get the input argument from `argp_parse', which we
108     // know is a pointer to our arguments structure.
109     struct arguments* arguments = ( struct arguments* ) state->input;
110     char* tail;
111
112     errno = 0;
113     switch (key) {
114     case 'q': case 's':
115         arguments->silent = 1;
116         break;
117     case 'v':
118         if (arg) {
119             arguments->verbose = strtol( arg, &tail, 0 );
120             if ( errno ) {
121                 fprintf( stderr,  "Could not parse 'verbose' argument\n" );
122                 return ARGP_ERR_UNKNOWN;
123             }
124         }
125         break;
126     case 'c':
127         if (arg) {
128             arguments->use_cache = strtol( arg, &tail, 0 );
129             if ( errno ) {
130                 fprintf( stderr,  "Could not parse 'cache' argument\n" );
131                 return ARGP_ERR_UNKNOWN;
132             }
133         }
134         break;
135     case 'p':
136         if (arg) {
137             arguments->port = strtol( arg, &tail, 0 );
138             if ( errno ) {
139                 fprintf( stderr,  "Could not parse 'port' argument\n" );
140                 return ARGP_ERR_UNKNOWN;
141             }
142         } else {
143             if ( errno ) {
144                 fprintf( stderr, "Could not parse 'port' argumen\n" );
145                 return ARGP_ERR_UNKNOWN;
146             }
147         }
148         break;
149     case 'n':
150         if (arg) {
151             arguments->node_id = strtol( arg, &tail, 0 );
152             if ( errno ) {
153                 fprintf( stderr,  "Could not parse 'node' argument\n" );
154                 return ARGP_ERR_UNKNOWN;
155             }
156             arguments->node_id_set=1;
157         } else {
158             if ( errno ) {
159                 fprintf( stderr, "Could not parse 'node' argumen\n" );
160                 return ARGP_ERR_UNKNOWN;
161             }
162         }
163         break;
164     case ARGP_KEY_ARG:
165         if (state->arg_num >= MAX_ARGS) {
166             // Too many arguments.
167             argp_usage( state );
168         }
169         arguments->args[state->arg_num] = arg;
170         arguments->nargs++;
171         break;
172     case ARGP_KEY_END:
173         if (state->arg_num < 1) {
174         // Not enough arguments.
175         argp_usage( state );
176         }
177         break;
178     default:
179         return ARGP_ERR_UNKNOWN;
180     }
181     return 0;
182 }
183
184 // Our argp parser.
185 static struct argp argp = { options, parse_opt, args_doc, doc };
186
187 int exitfunction( int retval ) {
188     debugOutput( DEBUG_LEVEL_NORMAL, "Debug output flushed...\n" );
189     flushDebugOutput();
190
191     return retval;
192 }
193
194 void
195 printDeviceList(unsigned int port)
196 {
197     Ieee1394Service service;
198     // switch off all messages since they mess up the list
199     service.setVerboseLevel(0);
200     if ( !service.initialize( port ) ) {
201         printf("Could not initialize IEEE 1394 service on port %d\n", port);
202         exit(-1);
203     }
204
205     printf("=== 1394 PORT %d ===\n", port);
206     printf("  Node id  GUID                  VendorId     ModelId   Vendor - Model\n");
207     for (int i = 0; i < service.getNodeCount(); i++) {
208         ConfigRom crom(service, i);
209         if (!crom.initialize())
210             break;
211
212         printf("  %2d       0x%s  0x%08X  0x%08X   %s - %s\n",
213                i, crom.getGuidString().c_str(),
214                crom.getNodeVendorId(), crom.getModelId(),
215                crom.getVendorName().c_str(),
216                crom.getModelName().c_str());
217     }
218 }
219
220 void
221 busreset(unsigned int port)
222 {
223     Ieee1394Service service;
224     // switch off all messages since they mess up the list
225     service.setVerboseLevel(0);
226     if ( !service.initialize( port ) ) {
227         printf("Could not initialize IEEE 1394 service on port %d\n", port);
228         exit(-1);
229     }
230
231     printf("Doing busreset on port %d\n", port);
232     service.doBusReset();
233 }
234
235 int
236 main( int argc, char **argv )
237 {
238     struct arguments arguments;
239
240     // Default values.
241     arguments.nargs       = 0;
242     arguments.silent      = 0;
243     arguments.verbose     = 0;
244     arguments.use_cache   = 1;
245     arguments.port        = 0;
246     arguments.node_id     = 0;
247     arguments.node_id_set = 0; // if we don't specify a node, discover all
248     arguments.args[0]     = "";
249     arguments.args[1]     = "";
250
251     // Parse our arguments; every option seen by `parse_opt' will
252     // be reflected in `arguments'.
253     if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) {
254         fprintf( stderr, "Could not parse command line\n" );
255         return exitfunction(-1);
256     }
257
258     printf("verbose level = %ld\n", arguments.verbose);
259     setDebugLevel(arguments.verbose);
260
261     printf( "Using ffado library version: %s\n\n", ffado_get_version() );
262
263     if ( strcmp( arguments.args[0], "Discover" ) == 0 ) {
264         DeviceManager *m_deviceManager = new DeviceManager();
265         if ( !m_deviceManager ) {
266             fprintf( stderr, "Could not allocate device manager\n" );
267             return exitfunction(-1);
268         }
269         if ( arguments.verbose ) {
270             m_deviceManager->setVerboseLevel(arguments.verbose);
271         }
272         if ( !m_deviceManager->initialize() ) {
273             fprintf( stderr, "Could not initialize device manager\n" );
274             delete m_deviceManager;
275             return exitfunction(-1);
276         }
277         if ( arguments.verbose ) {
278             m_deviceManager->setVerboseLevel(arguments.verbose);
279         }
280         if ( !m_deviceManager->discover(arguments.use_cache) ) {
281             fprintf( stderr, "Could not discover devices\n" );
282             delete m_deviceManager;
283             return exitfunction(-1);
284         }
285         delete m_deviceManager;
286         return exitfunction(0);
287     } else if ( strcmp( arguments.args[0], "BusReset" ) == 0 ) {
288         busreset(arguments.port);
289     } else if ( strcmp( arguments.args[0], "ListDevices" ) == 0 ) {
290         unsigned int nb_ports = Ieee1394Service::detectNbPorts();
291         for (unsigned int i=0;i<nb_ports;i++) {
292             printDeviceList(i);
293         }
294     } else if ( strcmp( arguments.args[0], "SetSamplerate" ) == 0 ) {
295         char* tail;
296         int samplerate = strtol( arguments.args[1], &tail, 0 );
297         if ( errno ) {
298             fprintf( stderr,  "Could not parse samplerate argument\n" );
299             return exitfunction(-1);
300         }
301
302         DeviceManager *m_deviceManager = new DeviceManager();
303         if ( !m_deviceManager ) {
304             fprintf( stderr, "Could not allocate device manager\n" );
305             return exitfunction(-1);
306         }
307         if ( arguments.verbose ) {
308             m_deviceManager->setVerboseLevel(arguments.verbose);
309         }
310         if ( !m_deviceManager->initialize() ) {
311             fprintf( stderr, "Could not initialize device manager\n" );
312             delete m_deviceManager;
313             return exitfunction(-1);
314         }
315         if ( arguments.verbose ) {
316             m_deviceManager->setVerboseLevel(arguments.verbose);
317         }
318         if ( !m_deviceManager->discover(arguments.use_cache) ) {
319             fprintf( stderr, "Could not discover devices\n" );
320             delete m_deviceManager;
321             return exitfunction(-1);
322         }
323
324         if(arguments.node_id_set) {
325             FFADODevice* avDevice = m_deviceManager->getAvDevice( arguments.node_id );
326             if ( avDevice ) {
327                 avDevice->setVerboseLevel(arguments.verbose);
328                 if ( ! avDevice->setSamplingFrequency( samplerate ) ) {
329                     fprintf( stderr, "Could not set samplerate\n" );
330                 }
331             }
332         } else {
333             int i=0;
334
335             int devices_on_bus = m_deviceManager->getNbDevices();
336             printf("  port = %ld, devices_on_bus = %d\n", arguments.port, devices_on_bus);
337
338             for(i=0;i<devices_on_bus;i++) {
339                 int node_id=m_deviceManager->getDeviceNodeId(i);
340                 printf("  set samplerate for device = %d, node = %d\n", i, node_id);
341                 FFADODevice* avDevice = m_deviceManager->getAvDevice( node_id );
342                 if ( avDevice ) {
343                     avDevice->setVerboseLevel(arguments.verbose);
344                     if ( !avDevice->setSamplingFrequency( samplerate ) ) {
345                         fprintf( stderr, "Could not set samplerate\n" );
346                     }
347                 }
348             }
349         }
350         delete m_deviceManager;
351         return exitfunction(0);
352     } else if ( strcmp( arguments.args[0], "SetClockSource" ) == 0 ) {
353         char* tail;
354         unsigned int targetid = (unsigned int)strtol( arguments.args[1], &tail, 0 );
355         if ( errno ) {
356             fprintf( stderr,  "Could not parse clock source argument\n" );
357             targetid=0xFFFF;
358         }
359         DeviceManager *m_deviceManager = new DeviceManager();
360         if ( !m_deviceManager ) {
361             fprintf( stderr, "Could not allocate device manager\n" );
362             return exitfunction(-1);
363         }
364         if ( arguments.verbose ) {
365             m_deviceManager->setVerboseLevel(arguments.verbose);
366         }
367         if ( !m_deviceManager->initialize() ) {
368             fprintf( stderr, "Could not initialize device manager\n" );
369             delete m_deviceManager;
370             return exitfunction(-1);
371         }
372         if ( arguments.verbose ) {
373             m_deviceManager->setVerboseLevel(arguments.verbose);
374         }
375         if ( !m_deviceManager->discover(arguments.use_cache) ) {
376             fprintf( stderr, "Could not discover devices\n" );
377             delete m_deviceManager;
378             return exitfunction(-1);
379         }
380
381         if(arguments.node_id_set) {
382             FFADODevice* avDevice = m_deviceManager->getAvDevice( arguments.node_id );
383             if ( avDevice ) {
384                 FFADODevice::ClockSource s;
385            
386                 avDevice->setVerboseLevel(arguments.verbose);
387                 FFADODevice::ClockSourceVector sources=avDevice->getSupportedClockSources();
388                 for ( FFADODevice::ClockSourceVector::const_iterator it
389                         = sources.begin();
390                     it != sources.end();
391                     ++it )
392                 {
393                     FFADODevice::ClockSource c=*it;
394                     printf( " Type: %s, Id: %d, Valid: %d, Active: %d, Description: %s\n",
395                         FFADODevice::ClockSourceTypeToString(c.type), c.id, c.valid, c.active, c.description.c_str());
396                    
397                     if (c.id==targetid) {
398                         s=*it;
399                     }
400                 }
401                
402                 if (s.type != FFADODevice::eCT_Invalid) {
403                     printf("  set clock source to %d\n", s.id);
404                     if ( ! avDevice->setActiveClockSource( s ) ) {
405                         fprintf( stderr, "Could not set clock source\n" );
406                     }
407                 } else {
408                     printf("  no clock source with id %d found\n", targetid);
409                 }
410             }
411         } else {
412             fprintf( stderr, "please specify a node\n" );
413         }
414         delete m_deviceManager;
415         return exitfunction(0);
416     } else if ( strcmp( arguments.args[0], "SytCalcTest" ) == 0 ) {
417         if (arguments.nargs < 4) {
418             fprintf( stderr,"Not enough arguments\n");
419             return -1;
420         }
421         uint64_t syt_timestamp = strtol(arguments.args[1], NULL, 0);
422         if (errno) {
423             fprintf( stderr,"syt_timestamp parsing failed: %s\n",
424                      strerror(errno));
425             return errno;
426         }
427         uint32_t rcv_cycle = strtol(arguments.args[2], NULL, 0);
428         if (errno) {
429             fprintf( stderr,"rcv_cycle parsing failed: %s\n",
430                      strerror(errno));
431             return errno;
432         }
433         uint64_t ctr_now = strtoll(arguments.args[3], NULL, 0);
434         if (errno) {
435             fprintf( stderr,"ctr_now parsing failed: %s\n",
436                      strerror(errno));
437             return errno;
438         }
439         uint64_t result_rcv = sytRecvToFullTicks(syt_timestamp, rcv_cycle, ctr_now);
440         uint64_t result_xmt = sytXmitToFullTicks(syt_timestamp, rcv_cycle, ctr_now);
441         printf("RCV: 0x%010llX %010llu  XMT: 0x%010llX %010llu CTR: %010llu\n",
442                result_rcv, result_rcv, result_xmt, result_xmt, CYCLE_TIMER_TO_TICKS(ctr_now));
443
444     } else {
445         fprintf( stderr, "please specify a command\n" );
446     }
447 }
Note: See TracBrowser for help on using the browser.