@@ -129,6 +129,7 @@ static struct adev_s {
129
129
int outbuf_len ;
130
130
131
131
enum audio_in_type_e g_audio_in_type ;
132
+ enum audio_out_type_e g_audio_out_type ;
132
133
133
134
int udp_sock ; /* UDP socket for receiving data */
134
135
@@ -453,52 +454,63 @@ int audio_open (struct audio_s *pa)
453
454
}
454
455
455
456
/*
456
- * Output device. Only "soundcard" is supported at this time.
457
+ * Output device. Only "soundcard" and "stdout" are supported at this time.
457
458
*/
459
+ if (strcasecmp (pa -> adev [a ].adevice_out , "stdout" ) == 0 || strcmp (pa -> adev [a ].adevice_out , "-" ) == 0 ) {
460
+ adev [a ].g_audio_out_type = AUDIO_OUT_TYPE_STDOUT ;
461
+ } else {
462
+ adev [a ].g_audio_out_type = AUDIO_OUT_TYPE_SOUNDCARD ;
463
+ }
464
+
465
+ switch (adev [a ].g_audio_out_type ) {
466
+ case AUDIO_OUT_TYPE_STDOUT :
467
+ adev [a ].outbuf_size_in_bytes = 1024 ;
468
+ break ;
458
469
470
+ case AUDIO_OUT_TYPE_SOUNDCARD :
459
471
#if USE_ALSA
460
- err = snd_pcm_open (& (adev [a ].audio_out_handle ), audio_out_name , SND_PCM_STREAM_PLAYBACK , 0 );
472
+ err = snd_pcm_open (& (adev [a ].audio_out_handle ), audio_out_name , SND_PCM_STREAM_PLAYBACK , 0 );
461
473
462
- if (err < 0 ) {
463
- text_color_set (DW_COLOR_ERROR );
464
- dw_printf ("Could not open audio device %s for output\n%s\n" ,
465
- audio_out_name , snd_strerror (err ));
466
- if (err == - EBUSY ) {
467
- dw_printf ("This means that some other application is using that device.\n" );
468
- dw_printf ("The solution is to identify that other application and stop it.\n" );
469
- }
470
- return (-1 );
471
- }
474
+ if (err < 0 ) {
475
+ text_color_set (DW_COLOR_ERROR );
476
+ dw_printf ("Could not open audio device %s for output\n%s\n" ,
477
+ audio_out_name , snd_strerror (err ));
478
+ if (err == - EBUSY ) {
479
+ dw_printf ("This means that some other application is using that device.\n" );
480
+ dw_printf ("The solution is to identify that other application and stop it.\n" );
481
+ }
482
+ return (-1 );
483
+ }
472
484
473
- adev [a ].outbuf_size_in_bytes = set_alsa_params (a , adev [a ].audio_out_handle , pa , audio_out_name , "output" );
485
+ adev [a ].outbuf_size_in_bytes = set_alsa_params (a , adev [a ].audio_out_handle , pa , audio_out_name , "output" );
474
486
475
- if (adev [a ].inbuf_size_in_bytes <= 0 || adev [a ].outbuf_size_in_bytes <= 0 ) {
476
- return (-1 );
477
- }
487
+ if (adev [a ].inbuf_size_in_bytes <= 0 || adev [a ].outbuf_size_in_bytes <= 0 ) {
488
+ return (-1 );
489
+ }
478
490
479
491
#elif USE_SNDIO
480
- adev [a ].sndio_out_handle = sio_open (audio_out_name , SIO_PLAY , 0 );
481
- if (adev [a ].sndio_out_handle == NULL ) {
482
- text_color_set (DW_COLOR_ERROR );
483
- dw_printf ("Could not open audio device %s for output\n" ,
484
- audio_out_name );
485
- return (-1 );
486
- }
492
+ adev [a ].sndio_out_handle = sio_open (audio_out_name , SIO_PLAY , 0 );
493
+ if (adev [a ].sndio_out_handle == NULL ) {
494
+ text_color_set (DW_COLOR_ERROR );
495
+ dw_printf ("Could not open audio device %s for output\n" ,
496
+ audio_out_name );
497
+ return (-1 );
498
+ }
487
499
488
- adev [a ].outbuf_size_in_bytes = set_sndio_params (a , adev [a ].sndio_out_handle , pa , audio_out_name , "output" );
500
+ adev [a ].outbuf_size_in_bytes = set_sndio_params (a , adev [a ].sndio_out_handle , pa , audio_out_name , "output" );
489
501
490
- if (adev [a ].inbuf_size_in_bytes <= 0 || adev [a ].outbuf_size_in_bytes <= 0 ) {
491
- return (-1 );
492
- }
502
+ if (adev [a ].inbuf_size_in_bytes <= 0 || adev [a ].outbuf_size_in_bytes <= 0 ) {
503
+ return (-1 );
504
+ }
493
505
494
- if (!sio_start (adev [a ].sndio_out_handle )) {
495
- text_color_set (DW_COLOR_ERROR );
496
- dw_printf ("Could not start audio device %s for output\n" ,
497
- audio_out_name );
498
- return (-1 );
499
- }
506
+ if (!sio_start (adev [a ].sndio_out_handle )) {
507
+ text_color_set (DW_COLOR_ERROR );
508
+ dw_printf ("Could not start audio device %s for output\n" ,
509
+ audio_out_name );
510
+ return (-1 );
511
+ }
500
512
#endif
501
-
513
+ }
502
514
/*
503
515
* Finally allocate buffer for each direction.
504
516
*/
@@ -1333,13 +1345,36 @@ int audio_put (int a, int c)
1333
1345
1334
1346
int audio_flush (int a )
1335
1347
{
1348
+ switch (adev [a ].g_audio_out_type ) {
1349
+ case AUDIO_OUT_TYPE_STDOUT :;
1350
+ int res ;
1351
+ unsigned char * ptr ;
1352
+ int len ;
1353
+
1354
+ ptr = adev [a ].outbuf_ptr ;
1355
+ len = adev [a ].outbuf_len ;
1356
+
1357
+ while (len > 0 ) {
1358
+ res = write (STDOUT_FILENO , ptr , (size_t ) len );
1359
+ if (res <= 0 ) {
1360
+ text_color_set (DW_COLOR_INFO );
1361
+ dw_printf ("\nError writing to stdout. Exiting.\n" );
1362
+ exit (0 );
1363
+ }
1364
+ ptr += res ;
1365
+ len -= res ;
1366
+ }
1367
+ adev [a ].outbuf_len = 0 ;
1368
+ return 0 ;
1369
+
1370
+ case AUDIO_OUT_TYPE_SOUNDCARD :;
1336
1371
#if USE_ALSA
1337
- int k ;
1338
- unsigned char * psound ;
1339
- int retries = 10 ;
1340
- snd_pcm_status_t * status ;
1372
+ int k ;
1373
+ unsigned char * psound ;
1374
+ int retries = 10 ;
1375
+ snd_pcm_status_t * status ;
1341
1376
1342
- assert (adev [a ].audio_out_handle != NULL );
1377
+ assert (adev [a ].audio_out_handle != NULL );
1343
1378
1344
1379
1345
1380
/*
@@ -1352,159 +1387,160 @@ int audio_flush (int a)
1352
1387
*/
1353
1388
1354
1389
1355
- snd_pcm_status_alloca (& status );
1390
+ snd_pcm_status_alloca (& status );
1356
1391
1357
- k = snd_pcm_status (adev [a ].audio_out_handle , status );
1358
- if (k != 0 ) {
1359
- text_color_set (DW_COLOR_ERROR );
1360
- dw_printf ("Audio output get status error.\n%s\n" , snd_strerror (k ));
1361
- }
1392
+ k = snd_pcm_status (adev [a ].audio_out_handle , status );
1393
+ if (k != 0 ) {
1394
+ text_color_set (DW_COLOR_ERROR );
1395
+ dw_printf ("Audio output get status error.\n%s\n" , snd_strerror (k ));
1396
+ }
1362
1397
1363
- if ((k = snd_pcm_status_get_state (status )) != SND_PCM_STATE_RUNNING ) {
1398
+ if ((k = snd_pcm_status_get_state (status )) != SND_PCM_STATE_RUNNING ) {
1364
1399
1365
- //text_color_set(DW_COLOR_DEBUG);
1366
- //dw_printf ("Audio output state = %d. Try to start.\n", k);
1400
+ //text_color_set(DW_COLOR_DEBUG);
1401
+ //dw_printf ("Audio output state = %d. Try to start.\n", k);
1367
1402
1368
- k = snd_pcm_prepare (adev [a ].audio_out_handle );
1403
+ k = snd_pcm_prepare (adev [a ].audio_out_handle );
1369
1404
1370
- if (k != 0 ) {
1371
- text_color_set (DW_COLOR_ERROR );
1372
- dw_printf ("Audio output start error.\n%s\n" , snd_strerror (k ));
1373
- }
1374
- }
1405
+ if (k != 0 ) {
1406
+ text_color_set (DW_COLOR_ERROR );
1407
+ dw_printf ("Audio output start error.\n%s\n" , snd_strerror (k ));
1408
+ }
1409
+ }
1375
1410
1376
1411
1377
- psound = adev [a ].outbuf_ptr ;
1412
+ psound = adev [a ].outbuf_ptr ;
1378
1413
1379
- while (retries -- > 0 ) {
1414
+ while (retries -- > 0 ) {
1380
1415
1381
- k = snd_pcm_writei (adev [a ].audio_out_handle , psound , adev [a ].outbuf_len / adev [a ].bytes_per_frame );
1416
+ k = snd_pcm_writei (adev [a ].audio_out_handle , psound , adev [a ].outbuf_len / adev [a ].bytes_per_frame );
1382
1417
#if DEBUGx
1383
- text_color_set (DW_COLOR_DEBUG );
1384
- dw_printf ("audio_flush(): snd_pcm_writei %d frames returns %d\n" ,
1385
- adev [a ].outbuf_len / adev [a ].bytes_per_frame , k );
1386
- fflush (stdout );
1418
+ text_color_set (DW_COLOR_DEBUG );
1419
+ dw_printf ("audio_flush(): snd_pcm_writei %d frames returns %d\n" ,
1420
+ adev [a ].outbuf_len / adev [a ].bytes_per_frame , k );
1421
+ fflush (stdout );
1387
1422
#endif
1388
- if (k == - EPIPE ) {
1389
- text_color_set (DW_COLOR_ERROR );
1390
- dw_printf ("Audio output data underrun.\n" );
1423
+ if (k == - EPIPE ) {
1424
+ text_color_set (DW_COLOR_ERROR );
1425
+ dw_printf ("Audio output data underrun.\n" );
1391
1426
1392
- /* No problemo. Recover and go around again. */
1427
+ /* No problemo. Recover and go around again. */
1393
1428
1394
- snd_pcm_recover (adev [a ].audio_out_handle , k , 1 );
1395
- }
1396
- else if (k == - ESTRPIPE ) {
1397
- text_color_set (DW_COLOR_ERROR );
1398
- dw_printf ("Driver suspended, recovering\n" );
1399
- snd_pcm_recover (adev [a ].audio_out_handle , k , 1 );
1400
- }
1401
- else if (k == - EBADFD ) {
1402
- k = snd_pcm_prepare (adev [a ].audio_out_handle );
1403
- if (k < 0 ) {
1404
- dw_printf ("Error preparing after bad state: %s\n" , snd_strerror (k ));
1405
- }
1406
- }
1407
- else if (k < 0 ) {
1408
- text_color_set (DW_COLOR_ERROR );
1409
- dw_printf ("Audio write error: %s\n" , snd_strerror (k ));
1429
+ snd_pcm_recover (adev [a ].audio_out_handle , k , 1 );
1430
+ }
1431
+ else if (k == - ESTRPIPE ) {
1432
+ text_color_set (DW_COLOR_ERROR );
1433
+ dw_printf ("Driver suspended, recovering\n" );
1434
+ snd_pcm_recover (adev [a ].audio_out_handle , k , 1 );
1435
+ }
1436
+ else if (k == - EBADFD ) {
1437
+ k = snd_pcm_prepare (adev [a ].audio_out_handle );
1438
+ if (k < 0 ) {
1439
+ dw_printf ("Error preparing after bad state: %s\n" , snd_strerror (k ));
1440
+ }
1441
+ }
1442
+ else if (k < 0 ) {
1443
+ text_color_set (DW_COLOR_ERROR );
1444
+ dw_printf ("Audio write error: %s\n" , snd_strerror (k ));
1410
1445
1411
- /* Some other error condition. */
1412
- /* Try again. What do we have to lose? */
1446
+ /* Some other error condition. */
1447
+ /* Try again. What do we have to lose? */
1413
1448
1414
- k = snd_pcm_prepare (adev [a ].audio_out_handle );
1415
- if (k < 0 ) {
1416
- dw_printf ("Error preparing after error: %s\n" , snd_strerror (k ));
1417
- }
1418
- }
1419
- else if (k != adev [a ].outbuf_len / adev [a ].bytes_per_frame ) {
1420
- text_color_set (DW_COLOR_ERROR );
1421
- dw_printf ("Audio write took %d frames rather than %d.\n" ,
1422
- k , adev [a ].outbuf_len / adev [a ].bytes_per_frame );
1423
-
1424
- /* Go around again with the rest of it. */
1449
+ k = snd_pcm_prepare (adev [a ].audio_out_handle );
1450
+ if (k < 0 ) {
1451
+ dw_printf ("Error preparing after error: %s\n" , snd_strerror (k ));
1452
+ }
1453
+ }
1454
+ else if (k != adev [a ].outbuf_len / adev [a ].bytes_per_frame ) {
1455
+ text_color_set (DW_COLOR_ERROR );
1456
+ dw_printf ("Audio write took %d frames rather than %d.\n" ,
1457
+ k , adev [a ].outbuf_len / adev [a ].bytes_per_frame );
1425
1458
1426
- psound += k * adev [a ].bytes_per_frame ;
1427
- adev [a ].outbuf_len -= k * adev [a ].bytes_per_frame ;
1428
- }
1429
- else {
1430
- /* Success! */
1431
- adev [a ].outbuf_len = 0 ;
1432
- return (0 );
1433
- }
1434
- }
1459
+ /* Go around again with the rest of it. */
1460
+
1461
+ psound += k * adev [a ].bytes_per_frame ;
1462
+ adev [a ].outbuf_len -= k * adev [a ].bytes_per_frame ;
1463
+ }
1464
+ else {
1465
+ /* Success! */
1466
+ adev [a ].outbuf_len = 0 ;
1467
+ return (0 );
1468
+ }
1469
+ }
1435
1470
1436
- text_color_set (DW_COLOR_ERROR );
1437
- dw_printf ("Audio write error retry count exceeded.\n" );
1471
+ text_color_set (DW_COLOR_ERROR );
1472
+ dw_printf ("Audio write error retry count exceeded.\n" );
1438
1473
1439
- adev [a ].outbuf_len = 0 ;
1440
- return (-1 );
1474
+ adev [a ].outbuf_len = 0 ;
1475
+ return (-1 );
1441
1476
1442
1477
#elif USE_SNDIO
1443
1478
1444
- int k ;
1445
- unsigned char * ptr ;
1446
- int len ;
1479
+ int k ;
1480
+ unsigned char * ptr ;
1481
+ int len ;
1447
1482
1448
- ptr = adev [a ].outbuf_ptr ;
1449
- len = adev [a ].outbuf_len ;
1483
+ ptr = adev [a ].outbuf_ptr ;
1484
+ len = adev [a ].outbuf_len ;
1450
1485
1451
- while (len > 0 ) {
1452
- assert (adev [a ].sndio_out_handle != NULL );
1453
- if (poll_sndio (adev [a ].sndio_out_handle , POLLOUT ) < 0 ) {
1454
- text_color_set (DW_COLOR_ERROR );
1455
- perror ("Can't write to audio device" );
1456
- adev [a ].outbuf_len = 0 ;
1457
- return (-1 );
1458
- }
1486
+ while (len > 0 ) {
1487
+ assert (adev [a ].sndio_out_handle != NULL );
1488
+ if (poll_sndio (adev [a ].sndio_out_handle , POLLOUT ) < 0 ) {
1489
+ text_color_set (DW_COLOR_ERROR );
1490
+ perror ("Can't write to audio device" );
1491
+ adev [a ].outbuf_len = 0 ;
1492
+ return (-1 );
1493
+ }
1459
1494
1460
- k = sio_write (adev [a ].sndio_out_handle , ptr , len );
1495
+ k = sio_write (adev [a ].sndio_out_handle , ptr , len );
1461
1496
#if DEBUGx
1462
- text_color_set (DW_COLOR_DEBUG );
1463
- dw_printf ("audio_flush(): write %d returns %d\n" , len , k );
1464
- fflush (stdout );
1497
+ text_color_set (DW_COLOR_DEBUG );
1498
+ dw_printf ("audio_flush(): write %d returns %d\n" , len , k );
1499
+ fflush (stdout );
1465
1500
#endif
1466
- ptr += k ;
1467
- len -= k ;
1468
- }
1501
+ ptr += k ;
1502
+ len -= k ;
1503
+ }
1469
1504
1470
- adev [a ].outbuf_len = 0 ;
1471
- return (0 );
1505
+ adev [a ].outbuf_len = 0 ;
1506
+ return (0 );
1472
1507
1473
1508
#else /* OSS */
1474
1509
1475
- int k ;
1476
- unsigned char * ptr ;
1477
- int len ;
1510
+ int k ;
1511
+ unsigned char * ptr ;
1512
+ int len ;
1478
1513
1479
- ptr = adev [a ].outbuf_ptr ;
1480
- len = adev [a ].outbuf_len ;
1514
+ ptr = adev [a ].outbuf_ptr ;
1515
+ len = adev [a ].outbuf_len ;
1481
1516
1482
- while (len > 0 ) {
1483
- assert (adev [a ].oss_audio_device_fd > 0 );
1484
- k = write (adev [a ].oss_audio_device_fd , ptr , len );
1517
+ while (len > 0 ) {
1518
+ assert (adev [a ].oss_audio_device_fd > 0 );
1519
+ k = write (adev [a ].oss_audio_device_fd , ptr , len );
1485
1520
#if DEBUGx
1486
- text_color_set (DW_COLOR_DEBUG );
1487
- dw_printf ("audio_flush(): write %d returns %d\n" , len , k );
1488
- fflush (stdout );
1521
+ text_color_set (DW_COLOR_DEBUG );
1522
+ dw_printf ("audio_flush(): write %d returns %d\n" , len , k );
1523
+ fflush (stdout );
1489
1524
#endif
1490
- if (k < 0 ) {
1491
- text_color_set (DW_COLOR_ERROR );
1492
- perror ("Can't write to audio device" );
1525
+ if (k < 0 ) {
1526
+ text_color_set (DW_COLOR_ERROR );
1527
+ perror ("Can't write to audio device" );
1528
+ adev [a ].outbuf_len = 0 ;
1529
+ return (-1 );
1530
+ }
1531
+ if (k < len ) {
1532
+ /* presumably full but didn't block. */
1533
+ usleep (10000 );
1534
+ }
1535
+ ptr += k ;
1536
+ len -= k ;
1537
+ }
1538
+
1493
1539
adev [a ].outbuf_len = 0 ;
1494
- return (-1 );
1495
- }
1496
- if (k < len ) {
1497
- /* presumably full but didn't block. */
1498
- usleep (10000 );
1499
- }
1500
- ptr += k ;
1501
- len -= k ;
1540
+ return (0 );
1541
+ #endif
1502
1542
}
1503
-
1504
- adev [a ].outbuf_len = 0 ;
1505
1543
return (0 );
1506
- #endif
1507
-
1508
1544
} /* end audio_flush */
1509
1545
1510
1546
@@ -1546,9 +1582,12 @@ int audio_flush (int a)
1546
1582
1547
1583
void audio_wait (int a )
1548
1584
{
1549
-
1550
1585
audio_flush (a );
1551
1586
1587
+ if (adev [a ].g_audio_out_type == AUDIO_OUT_TYPE_STDOUT ) {
1588
+ return ;
1589
+ }
1590
+
1552
1591
#if USE_ALSA
1553
1592
1554
1593
/* For playback, this should wait for all pending frames */
0 commit comments