Changeset 793
- Timestamp:
- 01/01/08 09:08:36 (16 years ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/libffado/tests/streaming/teststreaming3.cpp
r792 r793 28 28 */ 29 29 30 #ifdef HAVE_CONFIG_H 31 #include <config.h> 32 #endif 30 #include "config.h" 33 31 34 32 #include <stdio.h> … … 41 39 #include "libffado/ffado.h" 42 40 43 #include "debug tools.h"41 #include "debugmodule/debugmodule.h" 44 42 45 43 #include <math.h> 44 #include <argp.h> 46 45 47 46 int run; 47 48 DECLARE_GLOBAL_DEBUG_MODULE; 49 50 // Program documentation. 51 // Program documentation. 52 static char doc[] = "FFADO -- a driver for Firewire Audio devices (streaming test application)\n\n" 53 "OPERATION: Discover\n" 54 " SetSamplerate samplerate\n" 55 " SetClockSource [id]\n" 56 ; 57 58 // A description of the arguments we accept. 59 static char args_doc[] = "OPERATION"; 60 61 struct arguments 62 { 63 long int verbose; 64 long int test_tone; 65 long int test_tone_freq; 66 long int period; 67 long int slave_mode; 68 long int snoop_mode; 69 long int nb_buffers; 70 long int sample_rate; 71 long int rtprio; 72 char* args[2]; 73 74 }; 75 76 // The options we understand. 77 static struct argp_option options[] = { 78 {"verbose", 'v', "level", 0, "Verbose level" }, 79 {"rtprio", 'P', "prio", 0, "Realtime priority (0 = no RT scheduling)" }, 80 {"test-tone", 't', "bool", 0, "Output test sine" }, 81 {"test-tone-freq", 'f', "hz", 0, "Test sine frequency" }, 82 {"samplerate", 'r', "hz", 0, "Sample rate" }, 83 {"period", 'p', "frames", 0, "Period (buffer) size" }, 84 {"nb_buffers", 'n', "nb", 0, "Nb buffers (periods)" }, 85 {"slave_mode", 's', "bool", 0, "Run in slave mode" }, 86 {"snoop_mode", 'S', "bool", 0, "Run in snoop mode" }, 87 { 0 } 88 }; 89 90 //------------------------------------------------------------- 91 92 // Parse a single option. 93 static error_t 94 parse_opt( int key, char* arg, struct argp_state* state ) 95 { 96 // Get the input argument from `argp_parse', which we 97 // know is a pointer to our arguments structure. 98 struct arguments* arguments = ( struct arguments* ) state->input; 99 char* tail; 100 101 switch (key) { 102 case 'v': 103 if (arg) { 104 arguments->verbose = strtol( arg, &tail, 0 ); 105 if ( errno ) { 106 fprintf( stderr, "Could not parse 'verbose' argument\n" ); 107 return ARGP_ERR_UNKNOWN; 108 } 109 } 110 break; 111 case 'P': 112 if (arg) { 113 arguments->rtprio = strtol( arg, &tail, 0 ); 114 if ( errno ) { 115 fprintf( stderr, "Could not parse 'rtprio' argument\n" ); 116 return ARGP_ERR_UNKNOWN; 117 } 118 } 119 break; 120 case 'p': 121 if (arg) { 122 arguments->period = strtol( arg, &tail, 0 ); 123 if ( errno ) { 124 fprintf( stderr, "Could not parse 'period' argument\n" ); 125 return ARGP_ERR_UNKNOWN; 126 } 127 } 128 break; 129 case 'n': 130 if (arg) { 131 arguments->nb_buffers = strtol( arg, &tail, 0 ); 132 if ( errno ) { 133 fprintf( stderr, "Could not parse 'nb_buffers' argument\n" ); 134 return ARGP_ERR_UNKNOWN; 135 } 136 } 137 break; 138 case 'r': 139 if (arg) { 140 arguments->sample_rate = strtol( arg, &tail, 0 ); 141 if ( errno ) { 142 fprintf( stderr, "Could not parse 'samplerate' argument\n" ); 143 return ARGP_ERR_UNKNOWN; 144 } 145 } 146 break; 147 case 't': 148 if (arg) { 149 arguments->test_tone = strtol( arg, &tail, 0 ); 150 if ( errno ) { 151 fprintf( stderr, "Could not parse 'test-tone' argument\n" ); 152 return ARGP_ERR_UNKNOWN; 153 } 154 } 155 break; 156 case 'f': 157 if (arg) { 158 arguments->test_tone_freq = strtol( arg, &tail, 0 ); 159 if ( errno ) { 160 fprintf( stderr, "Could not parse 'test-tone-freq' argument\n" ); 161 return ARGP_ERR_UNKNOWN; 162 } 163 } 164 break; 165 case 's': 166 if (arg) { 167 arguments->slave_mode = strtol( arg, &tail, 0 ); 168 if ( errno ) { 169 fprintf( stderr, "Could not parse 'slave_mode' argument\n" ); 170 return ARGP_ERR_UNKNOWN; 171 } 172 } 173 break; 174 case 'S': 175 if (arg) { 176 arguments->snoop_mode = strtol( arg, &tail, 0 ); 177 if ( errno ) { 178 fprintf( stderr, "Could not parse 'snoop_mode' argument\n" ); 179 return ARGP_ERR_UNKNOWN; 180 } 181 } 182 break; 183 case ARGP_KEY_ARG: 184 break; 185 case ARGP_KEY_END: 186 break; 187 default: 188 return ARGP_ERR_UNKNOWN; 189 } 190 return 0; 191 } 192 193 // Our argp parser. 194 static struct argp argp = { options, parse_opt, args_doc, doc }; 48 195 49 196 int set_realtime_priority(unsigned int prio) 50 197 { 51 if (prio > 0) { 52 struct sched_param schp; 53 /* 54 * set the process to realtime privs 55 */ 56 memset(&schp, 0, sizeof(schp)); 57 schp.sched_priority = prio; 58 59 if (sched_setscheduler(0, SCHED_FIFO, &schp) != 0) { 60 perror("sched_setscheduler"); 61 exit(1); 62 } 198 debugOutput(DEBUG_LEVEL_NORMAL, "Setting thread prio to %u\n", prio); 199 if (prio > 0) { 200 struct sched_param schp; 201 /* 202 * set the process to realtime privs 203 */ 204 memset(&schp, 0, sizeof(schp)); 205 schp.sched_priority = prio; 206 207 if (sched_setscheduler(0, SCHED_FIFO, &schp) != 0) { 208 perror("sched_setscheduler"); 209 return -1; 210 } 63 211 } else { 64 212 struct sched_param schp; … … 67 215 */ 68 216 memset(&schp, 0, sizeof(schp)); 69 schp.sched_priority = prio;217 schp.sched_priority = 0; 70 218 71 219 if (sched_setscheduler(0, SCHED_OTHER, &schp) != 0) { 72 perror("sched_setscheduler"); 73 exit(1); 74 } 75 220 perror("sched_setscheduler"); 221 return -1; 222 } 76 223 } 77 224 return 0; … … 87 234 { 88 235 89 #define PERIOD_SIZE 1024 90 #define TEST_FREQ 1000.0 91 #define do_test_tone 1 236 struct arguments arguments; 237 238 // Default values. 239 arguments.test_tone = 0; 240 arguments.test_tone_freq = 1000; 241 arguments.verbose = 6; 242 arguments.period = 1024; 243 arguments.slave_mode = 0; 244 arguments.snoop_mode = 0; 245 arguments.nb_buffers = 3; 246 arguments.sample_rate = 44100; 247 arguments.rtprio = 0; 248 249 // Parse our arguments; every option seen by `parse_opt' will 250 // be reflected in `arguments'. 251 if ( argp_parse ( &argp, argc, argv, 0, 0, &arguments ) ) { 252 debugError("Could not parse command line\n" ); 253 return -1; 254 } 255 256 debugOutput(DEBUG_LEVEL_NORMAL, "verbose level = %d\n", arguments.verbose); 257 setDebugLevel(arguments.verbose); 92 258 93 259 int samplesread=0; … … 112 278 run=1; 113 279 114 printf("FFADO streaming test application (3)\n");280 debugOutput(DEBUG_LEVEL_NORMAL, "FFADO streaming test application (3)\n"); 115 281 116 282 signal (SIGINT, sighandler); … … 123 289 memset(&dev_options,0,sizeof(ffado_options_t)); 124 290 125 dev_options.sample_rate =44100;126 dev_options.period_size =PERIOD_SIZE;127 128 dev_options.nb_buffers =3;129 130 dev_options.realtime =1;131 dev_options.packetizer_priority =60;132 133 dev_options.verbose = 6;134 135 dev_options.slave_mode =0;136 dev_options.snoop_mode =0;137 138 sine_advance = 2.0*M_PI* TEST_FREQ/((float)dev_options.sample_rate);291 dev_options.sample_rate = arguments.sample_rate; 292 dev_options.period_size = arguments.period; 293 294 dev_options.nb_buffers = arguments.nb_buffers; 295 296 dev_options.realtime = (arguments.rtprio != 0); 297 dev_options.packetizer_priority = arguments.rtprio + 1; 298 299 dev_options.verbose = arguments.verbose; 300 301 dev_options.slave_mode = arguments.slave_mode; 302 dev_options.snoop_mode = arguments.snoop_mode; 303 304 sine_advance = 2.0*M_PI*arguments.test_tone_freq/((float)dev_options.sample_rate); 139 305 140 306 ffado_device_t *dev=ffado_streaming_init(device_info, dev_options); 141 307 142 308 if (!dev) { 143 fprintf(stderr,"Could not init Ffado Streaming layer\n");309 debugError("Could not init Ffado Streaming layer\n"); 144 310 exit(-1); 145 311 } … … 157 323 audiobuffers_in = (float **)calloc(nb_in_channels, sizeof(float *)); 158 324 for (i=0; i < nb_in_channels; i++) { 159 audiobuffers_in[i] = (float *)calloc( PERIOD_SIZE+1, sizeof(float));325 audiobuffers_in[i] = (float *)calloc(arguments.period+1, sizeof(float)); 160 326 161 327 switch (ffado_streaming_get_capture_stream_type(dev,i)) { … … 175 341 audiobuffers_out = (float **)calloc(nb_out_channels, sizeof(float)); 176 342 for (i=0; i < nb_out_channels; i++) { 177 audiobuffers_out[i] = (float *)calloc( PERIOD_SIZE+1, sizeof(float));343 audiobuffers_out[i] = (float *)calloc(arguments.period+1, sizeof(float)); 178 344 179 345 switch (ffado_streaming_get_playback_stream_type(dev,i)) { … … 191 357 } 192 358 193 nullbuffer = (float *)calloc( PERIOD_SIZE+1, sizeof(float));359 nullbuffer = (float *)calloc(arguments.period+1, sizeof(float)); 194 360 195 361 … … 225 391 start_flag = ffado_streaming_start(dev); 226 392 227 set_realtime_priority( dev_options.packetizer_priority-1);228 fprintf(stderr,"Entering receive loop (IN: %d, OUT: %d)\n", nb_in_channels, nb_out_channels);393 set_realtime_priority(arguments.rtprio); 394 debugOutput(DEBUG_LEVEL_NORMAL, "Entering receive loop (IN: %d, OUT: %d)\n", nb_in_channels, nb_out_channels); 229 395 while(run && start_flag==0) { 230 396 retval = ffado_streaming_wait(dev); 231 397 if (retval < 0) { 232 fprintf(stderr,"Xrun\n");398 debugOutput(DEBUG_LEVEL_NORMAL, "Xrun\n"); 233 399 ffado_streaming_reset(dev); 234 400 continue; … … 237 403 ffado_streaming_transfer_capture_buffers(dev); 238 404 239 if ( do_test_tone) {405 if (arguments.test_tone) { 240 406 // generate the test tone 241 for (i=0; i< PERIOD_SIZE; i++) {407 for (i=0; i<arguments.period; i++) { 242 408 nullbuffer[i] = amplitude * sin(sine_advance * (frame_counter + (float)i)); 243 409 } … … 246 412 for (i=0; i < nb_out_channels; i++) { 247 413 if (ffado_streaming_get_playback_stream_type(dev,i) == ffado_stream_type_audio) { 248 memcpy((char *)(audiobuffers_out[i]), (char *)(nullbuffer), sizeof(float) * PERIOD_SIZE);414 memcpy((char *)(audiobuffers_out[i]), (char *)(nullbuffer), sizeof(float) * arguments.period); 249 415 } 250 416 } … … 255 421 // if both channels are audio channels, copy the buffers 256 422 if (ffado_streaming_get_playback_stream_type(dev,i) == ffado_stream_type_audio) { 257 memcpy((char *)(audiobuffers_out[i]), (char *)(audiobuffers_in[i]), sizeof(float) * PERIOD_SIZE);423 memcpy((char *)(audiobuffers_out[i]), (char *)(audiobuffers_in[i]), sizeof(float) * arguments.period); 258 424 } 259 425 break; … … 269 435 270 436 nb_periods++; 271 frame_counter += PERIOD_SIZE;437 frame_counter += arguments.period; 272 438 273 439 // if((nb_periods % 32)==0) { 274 // // fprintf(stderr,"\r%05d periods",nb_periods);440 // // debugOutput(DEBUG_LEVEL_NORMAL, "\r%05d periods",nb_periods); 275 441 // } 276 442 … … 281 447 // case ffado_stream_type_audio: 282 448 // // no need to get the buffers manually, we have set the API internal buffers to the audiobuffer[i]'s 283 // // //samplesread=freebob_streaming_read(dev, i, audiobuffer[i], PERIOD_SIZE);284 // samplesread= PERIOD_SIZE;449 // // //samplesread=freebob_streaming_read(dev, i, audiobuffer[i], arguments.period); 450 // samplesread=arguments.period; 285 451 // break; 286 452 // case ffado_stream_type_midi: 287 // //samplesread=ffado_streaming_read(dev, i, audiobuffers_out[i], PERIOD_SIZE);453 // //samplesread=ffado_streaming_read(dev, i, audiobuffers_out[i], arguments.period); 288 454 // break; 289 455 // default: break; … … 305 471 // switch (ffado_streaming_get_playback_stream_type(dev,i)) { 306 472 // case ffado_stream_type_audio: 307 // // sampleswritten=freebob_streaming_write(dev, i, buff, PERIOD_SIZE);308 // sampleswritten= PERIOD_SIZE;473 // // sampleswritten=freebob_streaming_write(dev, i, buff, arguments.period); 474 // sampleswritten=arguments.period; 309 475 // break; 310 476 // case ffado_stream_type_midi: 311 // // sampleswritten=freebob_streaming_write(dev, i, buff, PERIOD_SIZE);477 // // sampleswritten=freebob_streaming_write(dev, i, buff, arguments.period); 312 478 // break; 313 479 // default: break; … … 318 484 } 319 485 320 fprintf(stderr,"\n"); 321 322 fprintf(stderr,"Exiting receive loop\n"); 486 debugOutput(DEBUG_LEVEL_NORMAL, "Exiting receive loop\n"); 323 487 324 488 ffado_streaming_stop(dev);