3
TiMidity++ -- MIDI to WAVE converter and player
4
Copyright (C) 1999 Masanao Izumo <mo@goice.co.jp>
5
Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
Functions to play sound on the VoxWare audio driver (Linux or FreeBSD)
32
#endif /* HAVE_CONFIG_H */
51
#include <sys/asoundlib.h>
55
#include <sys/asoundlib.h>
67
/* #include "timer.h" */
70
/* #include "miditrace.h" */
72
static int open_output(void); /* 0=success, 1=warning, -1=fatal error */
73
static void close_output(void);
75
static int output_data(char *buf, int32 nbytes);
76
static int acntl(int request, void *arg);
78
static void output_data(int32 *buf, uint32 count);
79
static int driver_output_data(unsigned char *buf, uint32 count);
80
static void flush_output(void);
81
static void purge_output(void);
82
static int output_count(uint32 ct);
84
static int total_bytes, output_counter;
86
/* export the playback mode */
88
#define dpm alsa_play_mode
92
DEFAULT_RATE, PE_16BIT|PE_SIGNED, PF_PCM_STREAM|PF_CAN_TRACE,
94
{0}, /* default: get all the buffer fragments you can */
95
"ALSA pcm device", 's',
105
DEFAULT_RATE, PE_16BIT|PE_SIGNED,
107
{0}, /* default: get all the buffer fragments you can */
108
"ALSA pcm device", 's',
120
/*************************************************************************/
121
/* We currently only honor the PE_MONO bit, the sample rate, and the
122
number of buffer fragments. We try 16-bit signed data first, and
123
then 8-bit unsigned if it fails. If you have a sound device that
124
can't handle either, let me know. */
128
static snd_pcm_t* handle = NULL;
130
static int device = 0;
131
static int setup_frags = 0;
132
static int setup_frag_size = 0;
134
void alsa_tell(int *fragsize, int *fragstotal)
136
*fragsize = setup_frag_size;
137
*fragstotal = setup_frags;
140
static void error_report (int snd_error)
142
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
143
dpm.name, snd_strerror (snd_error));
146
/*return value == 0 sucess
149
static int check_sound_cards (int* card__, int* device__,
150
const int32 extra_param[5])
152
/*Search sound cards*/
153
struct snd_ctl_hw_info ctl_hw_info;
154
snd_pcm_info_t pcm_info;
155
snd_ctl_t* ctl_handle;
156
const char* env_sound_card = getenv ("TIMIDITY_SOUND_CARD");
157
const char* env_pcm_device = getenv ("TIMIDITY_PCM_DEVICE");
162
if (env_sound_card != NULL)
163
*card__ = atoi (env_sound_card);
166
if (env_pcm_device != NULL)
167
*device__ = atoi (env_pcm_device);
172
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "No sound card found.");
181
if (*card__ < 0 || *card__ >= tmp)
183
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "There is %d sound cards."
184
" %d is invalid sound card. assuming 0.",
189
tmp = snd_ctl_open (&ctl_handle, *card__);
196
/*check whether sound card has pcm device(s)*/
197
tmp = snd_ctl_hw_info (ctl_handle, & ctl_hw_info);
198
if (ctl_hw_info.pcmdevs == 0)
200
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
201
"%d-th sound card(%s) has no pcm device",
202
ctl_hw_info.longname, *card__);
203
snd_ctl_close (ctl_handle);
207
if (*device__ < 0 || *device__ >= ctl_hw_info.pcmdevs)
209
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
210
"%d-th sound cards(%s) has %d pcm device(s)."
211
" %d is invalid pcm device. assuming 0.",
212
*card__, ctl_hw_info.longname, ctl_hw_info.pcmdevs, *device__);
215
if (ctl_hw_info.pcmdevs == 0)
216
{/*sound card has no pcm devices*/
217
snd_ctl_close (ctl_handle);
222
/*check whether pcm device is able to playback*/
223
tmp = snd_ctl_pcm_info(ctl_handle, *device__, &pcm_info);
227
snd_ctl_close (ctl_handle);
231
if ((pcm_info.flags & SND_PCM_INFO_PLAYBACK) == 0)
233
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
234
"%d-th sound cards(%s), device=%d, "
235
"type=%d, flags=%d, id=%s, name=%s,"
236
" does not support playback",
237
*card__, ctl_hw_info.longname, ctl_hw_info.pcmdevs,
238
pcm_info.type, pcm_info.flags, pcm_info.id, pcm_info.name);
239
snd_ctl_close (ctl_handle);
243
tmp = snd_ctl_close (ctl_handle);
253
/*return value == 0 sucess
257
static int set_playback_info (void* handle__,
258
uint32* encoding__, uint32* rate__,
259
const int32 extra_param[5])
262
const uint32 orig_encoding = *encoding__;
263
const uint32 orig_rate = *rate__;
264
/* snd_pcm_playback_info_t playback_info; */
265
snd_pcm_channel_info_t playback_info;
266
snd_pcm_format_t pcm_format;
268
struct snd_pcm_playback_params playback_params;
269
struct snd_pcm_playback_status playback_status;
271
struct snd_pcm_channel_params playback_params;
272
struct snd_pcm_channel_status playback_status;
273
struct snd_pcm_channel_setup setup;
276
//fprintf(stderr,"setting playback info\n");
277
memset (&pcm_format, 0, sizeof (pcm_format));
278
pcm_format.interleave = 1;
280
memset (&playback_params, 0, sizeof (playback_params));
281
playback_params.channel = SND_PCM_CHANNEL_PLAYBACK;
282
playback_params.mode = SND_PCM_MODE_BLOCK;
284
memset(&playback_info, 0, sizeof(playback_info));
285
playback_info.channel = SND_PCM_CHANNEL_PLAYBACK;
287
tmp = snd_pcm_plugin_info (handle__, &playback_info);
288
//fprintf(stderr,"tmp = %d from snd_pcm_channel_info\n",tmp);
297
if ((playback_info.flags & SND_PCM_PINFO_8BITONLY) != 0)
298
*encoding__ &= ~PE_16BIT;/*force 8bit samles*/
299
if ((playback_info.flags & SND_PCM_PINFO_16BITONLY) != 0)
300
*encoding__ |= PE_16BIT;/*force 16bit samples*/
304
if (playback_info.min_rate > *rate__)
305
*rate__ = playback_info.min_rate;
306
if (playback_info.max_rate < *rate__)
307
*rate__ = playback_info.max_rate;
308
pcm_format.rate = *rate__;
311
if ((*encoding__ & PE_MONO) != 0 && playback_info.min_voices > 1)
312
*encoding__ &= ~PE_MONO;
313
if ((*encoding__ & PE_MONO) == 0 && playback_info.max_voices < 2)
314
*encoding__ |= PE_MONO;
316
if ((*encoding__ & PE_MONO) != 0)
317
pcm_format.voices = 1;/*mono*/
319
pcm_format.voices = 2;/*stereo*/
323
if ((*encoding__ & PE_16BIT) != 0)
325
if ((playback_info.formats & SND_PCM_FMT_S16_LE) != 0)
327
pcm_format.format = SND_PCM_SFMT_S16_LE;
328
*encoding__ |= PE_SIGNED;
330
else if ((playback_info.formats & SND_PCM_FMT_U16_LE) != 0)
332
pcm_format.format = SND_PCM_SFMT_U16_LE;
333
*encoding__ &= ~PE_SIGNED;
335
else if ((playback_info.formats & SND_PCM_FMT_S16_BE) != 0)
337
pcm_format.format = SND_PCM_SFMT_S16_BE;
338
*encoding__ |= PE_SIGNED;
340
else if ((playback_info.formats & SND_PCM_FMT_U16_BE) != 0)
342
pcm_format.format = SND_PCM_SFMT_U16_LE;
343
*encoding__ &= ~PE_SIGNED;
347
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
348
"%s doesn't support 16 bit sample width",
355
if ((playback_info.formats & SND_PCM_FMT_U8) != 0)
357
pcm_format.format = SND_PCM_SFMT_U8;
358
*encoding__ &= ~PE_SIGNED;
360
else if ((playback_info.formats & SND_PCM_FMT_S8) != 0)
362
pcm_format.format = SND_PCM_SFMT_U16_LE;
363
*encoding__ |= PE_SIGNED;
367
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
368
"%s doesn't support 8 bit sample width",
373
memcpy(&playback_params.format, &pcm_format, sizeof(pcm_format));
376
tmp = snd_pcm_channel_format (handle__, &pcm_format);
384
/*check result of snd_pcm_channel_format*/
385
if ((*encoding__ & PE_16BIT) != (orig_encoding & PE_16BIT ))
387
ctl->cmsg (CMSG_WARNING, VERB_VERBOSE,
388
"Sample width adjusted to %d bits",
389
((*encoding__ & PE_16BIT) != 0)? 16:8);
392
if (((pcm_format.voices == 1)? PE_MONO:0) != (orig_encoding & PE_MONO))
394
ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "Sound adjusted to %sphonic",
395
((*encoding__ & PE_MONO) != 0)? "mono" : "stereo");
399
/* Set buffer fragments (in extra_param[0]) */
401
tmp = AUDIO_BUFFER_BITS;
402
if (!(*encoding__ & PE_MONO))
404
if (*encoding__ & PE_16BIT)
407
playback_params.buf.block.frag_size = (1 << tmp);
409
tmp = AUDIO_BUFFER_SIZE;
410
if (!(*encoding__ & PE_MONO))
412
if (*encoding__ & PE_16BIT)
414
playback_params.buf.block.frag_size = tmp;
415
//fprintf(stderr,"frag_size %d\n", playback_params.buf.block.frag_size);
417
if (extra_param[0] == 0)
418
playback_params.buf.block.frags_max = 7;/*default value. What's value is apporpriate?*/
420
playback_params.buf.block.frags_max = extra_param[0];
423
if (extra_param[0] == 0)
424
playback_params.fragments_max = 15;/*default value. What's value is apporpriate?*/
426
playback_params.fragments_max = extra_param[0];
428
playback_params.buf.block.frags_min = 1;
429
snd_pcm_plugin_flush(handle__, SND_PCM_CHANNEL_PLAYBACK);
431
playback_params.start_mode = SND_PCM_START_FULL;
432
playback_params.stop_mode = SND_PCM_STOP_STOP;
433
//playback_params.stop_mode = SND_PCM_STOP_ROLLOVER;
435
tmp = snd_pcm_channel_params (handle__, &playback_params);
437
//fprintf(stderr,"tmp = %d from snd_pcm_channel_params\n",tmp);
440
ctl->cmsg(CMSG_WARNING, VERB_NORMAL,
441
"%s doesn't support buffer fragments"
442
":request size=%d, max=%d, room=%d\n",
444
playback_params.buf.block.frag_size,
445
playback_params.buf.block.frags_max,
446
playback_params.buf.block.frags_min);
451
if (snd_pcm_plugin_prepare(handle__, SND_PCM_CHANNEL_PLAYBACK) < 0) {
452
fprintf(stderr, "unable to prepare channel\n");
456
memset(&setup, 0, sizeof(setup));
457
setup.channel = SND_PCM_CHANNEL_PLAYBACK;
458
setup.mode = SND_PCM_MODE_BLOCK;
459
if (snd_pcm_plugin_setup(handle__, &setup) < 0) {
460
fprintf(stderr, "unable to obtain setup\n");
463
setup_frags = setup.buf.block.frags;
464
setup_frag_size = setup.buf.block.frag_size;
466
//fprintf(stderr, "setup frags = %d\n", setup.buf.block.frags);
467
//fprintf(stderr, "setup frag_size = %d\n", setup.buf.block.frag_size);
469
if(snd_pcm_plugin_status(handle__, &playback_status) == 0)
471
if (setup.format.rate != orig_rate)
473
ctl->cmsg(CMSG_WARNING, VERB_VERBOSE,
474
"Output rate adjusted to %d Hz (requested %d Hz)",
475
setup.format.rate, orig_rate);
476
dpm.rate = setup.format.rate;
479
total_bytes = playback_status.count;
482
total_bytes = -1; /* snd_pcm_channel_status fails */
487
static int open_output(void)
492
tmp = check_sound_cards (&card, &device, dpm.extra_param);
496
//fprintf(stderr,"using card %d, device %d\n", card, device);
497
/* Open the audio device */
498
ret = snd_pcm_open (&handle, card, device,
499
SND_PCM_OPEN_PLAYBACK|SND_PCM_OPEN_NONBLOCK);
500
// ret = snd_pcm_open (&handle, card, device, SND_PCM_OPEN_PLAYBACK);
501
//fprintf(stderr,"ret was %d\n", ret);
505
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "%s: %s",
506
dpm.name, snd_strerror (ret));
510
/* They can't mean these */
511
dpm.encoding &= ~(PE_ULAW|PE_ALAW|PE_BYTESWAP);
512
warnings = set_playback_info (handle, &dpm.encoding, &dpm.rate,
520
dpm.fd = snd_pcm_file_descriptor (handle, SND_PCM_CHANNEL_PLAYBACK);
525
static void close_output(void)
532
ret = snd_pcm_close (handle);
541
static int output_data(char *buf, int32 nbytes)
547
n = snd_pcm_plugin_write(handle, buf, nbytes);
550
ctl->cmsg(CMSG_WARNING, VERB_DEBUG,
551
"%s: %s", dpm.name, strerror(errno));
552
if(errno == EWOULDBLOCK)
565
void playback_write_error(void)
567
snd_pcm_channel_status_t status;
569
memset(&status, 0, sizeof(status));
570
status.channel = SND_PCM_CHANNEL_PLAYBACK;
571
if (snd_pcm_plugin_status(handle, &status)<0) {
572
fprintf(stderr, "playback channel status error\n");
575
if (status.status == SND_PCM_STATUS_UNDERRUN) {
576
//printf("underrun at position %u!!!\n", status.scount);
577
if (snd_pcm_plugin_prepare(handle, SND_PCM_CHANNEL_PLAYBACK)<0) {
578
fprintf(stderr, "underrun: playback channel prepare error\n");
581
return; /* ok, data should be accepted again */
583
if (status.status == SND_PCM_STATUS_READY) {
584
if (snd_pcm_plugin_prepare(handle, SND_PCM_CHANNEL_PLAYBACK)<0) {
585
fprintf(stderr, "ready: playback channel prepare error\n");
588
return; /* ok, data should be accepted again */
590
if (status.status == SND_PCM_STATUS_RUNNING) return;
591
fprintf(stderr, "write error: status %d\n", status.status);
597
static int driver_output_data(unsigned char *buf, uint32 count) {
599
//fprintf(stderr,"write %d bytes with buffer size %d\n",
600
// count, AUDIO_BUFFER_SIZE);
601
if (count < (uint32)setup_frag_size ) return 0;
602
ret_value = snd_pcm_plugin_write(handle, buf, setup_frag_size);
604
//fprintf(stderr,"ret_value = %d\n", ret_value);
605
playback_write_error();
612
static int output_count(uint32 ct)
614
struct snd_pcm_channel_status playback_status;
616
int samples_queued, samples_sent = (int)ct;
618
samples = samples_sent = b_out_count();
621
if(snd_pcm_plugin_status(handle, &playback_status) != 0)
623
/* samples_queued is PM_REQ_GETFILLED */
624
/* if (snd_pcm_channel_status(handle, &playback_status) == 0) */
625
samples_queued = playback_status.count;
626
samples -= samples_queued;
628
if (!(dpm.encoding & PE_MONO)) samples >>= 1;
629
if (dpm.encoding & PE_16BIT) samples >>= 1;
634
static void output_data(int32 *buf, uint32 count)
638
if (!(dpm.encoding & PE_MONO)) count*=2; /* Stereo samples */
642
if (dpm.encoding & PE_16BIT)
644
/* Convert data to signed 16-bit PCM */
645
s32tos16(buf, count);
650
/* Convert to 8-bit unsigned and write out. */
655
b_out(dpm.id_character, dpm.fd, (int *)buf, ocount);
659
static void flush_output(void)
662
snd_pcm_plugin_flush(handle, SND_PCM_CHANNEL_PLAYBACK);
665
static void purge_output(void)
667
b_out(dpm.id_character, dpm.fd, 0, -1);
668
snd_pcm_plugin_playback_drain(handle);
670
if (snd_pcm_plugin_prepare(handle, SND_PCM_CHANNEL_PLAYBACK) < 0) {
671
fprintf(stderr, "unable to prepare channel\n");
675
//fprintf(stderr, "setup frags = %d\n", setup.buf.block.frags);
681
static int acntl(int request, void *arg)
683
struct snd_pcm_playback_status playback_status;
689
if(total_bytes == -1)
691
*((int *)arg) = total_bytes;
694
case PM_REQ_GETFILLABLE:
695
if(total_bytes == -1)
697
if(snd_pcm_playback_status(handle, &playback_status) != 0)
699
*((int *)arg) = playback_status.count;
702
case PM_REQ_GETFILLED:
703
if(total_bytes == -1)
705
if(snd_pcm_playback_status(handle, &playback_status) != 0)
707
*((int *)arg) = playback_status.queue;
710
case PM_REQ_GETSAMPLES:
711
if(total_bytes == -1)
713
if(snd_pcm_playback_status(handle, &playback_status) != 0)
715
i = output_counter - playback_status.queue;
716
if(!(dpm.encoding & PE_MONO)) i >>= 1;
717
if(dpm.encoding & PE_16BIT) i >>= 1;
722
if(snd_pcm_drain_playback (handle) != 0)
723
return -1; /* error */
728
if(snd_pcm_flush_playback(handle) != 0)
729
return -1; /* error */