root/branches/libffado-2.0/tests/test-ffado.cpp

Revision 1184, 14.7 kB (checked in by ppalmers, 13 years ago)

add some extra saffire pro control elements

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