From c410bf9a629ad967ed8a465680f4c9804a7df288 Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Wed, 21 Jun 2000 15:05:06 +0000 Subject: [PATCH] Reorganized options and added support for pcm_multi --- aplay/aplay.c | 525 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 333 insertions(+), 192 deletions(-) diff --git a/aplay/aplay.c b/aplay/aplay.c index aaf5542..708c766 100644 --- a/aplay/aplay.c +++ b/aplay/aplay.c @@ -59,28 +59,27 @@ static ssize_t (*readv_func)(snd_pcm_t *handle, const struct iovec *vector, unsi static ssize_t (*writev_func)(snd_pcm_t *handle, const struct iovec *vector, unsigned long count); static char *command; -static snd_pcm_t *pcm_handle; -static snd_pcm_stream_info_t cinfo; +static snd_pcm_t *handle; +static snd_pcm_info_t cinfo; static snd_pcm_format_t rformat, format; -static snd_pcm_stream_setup_t setup; +static snd_pcm_setup_t setup; static int timelimit = 0; static int quiet_mode = 0; -static int verbose_mode = 0; -static int active_format = FORMAT_DEFAULT; +static int file_type = FORMAT_DEFAULT; static int mode = SND_PCM_MODE_FRAGMENT; -static int direction = SND_PCM_OPEN_PLAYBACK; +static int open_mode = 0; static int stream = SND_PCM_STREAM_PLAYBACK; static int mmap_flag = 0; static snd_pcm_mmap_control_t *mmap_control = NULL; static snd_pcm_mmap_status_t *mmap_status = NULL; static char *mmap_data = NULL; -static int noplugin = 0; static int nonblock = 0; static char *audiobuf = NULL; static int align = 1; static int buffer_size = -1; -/* 250 ms */ -static int frag_length = 250; +static int frag_length = 125; +static int buffer_length = 500; +static int min_avail = 50; static int show_setup = 0; static int buffer_pos = 0; static size_t bits_per_sample, bits_per_frame; @@ -152,11 +151,11 @@ static void check_new_format(snd_pcm_format_t * format) } if (format->channels > 1) { if (format->interleave) { - if (!(cinfo.flags & SND_PCM_STREAM_INFO_INTERLEAVE)) { + if (!(cinfo.flags & SND_PCM_INFO_INTERLEAVE)) { fprintf(stderr, "%s: unsupported interleaved format\n", command); exit(EXIT_FAILURE); } - } else if (!(cinfo.flags & SND_PCM_STREAM_INFO_NONINTERLEAVE)) { + } else if (!(cinfo.flags & SND_PCM_INFO_NONINTERLEAVE)) { fprintf(stderr, "%s: unsupported non interleaved format\n", command); exit(EXIT_FAILURE); } @@ -166,40 +165,41 @@ static void check_new_format(snd_pcm_format_t * format) static void usage(char *command) { int k; - fprintf(stderr, - "Usage: %s [switches] [filename] ...\n" - "Available switches:\n" - "\n" - " -h,--help help\n" - " -V,--version print current version\n" - " -l list all soundcards and digital audio devices\n" - " -c select card # or card id (0-%i), defaults to 0\n" - " -d select device #, defaults to 0\n" - " -q quiet mode\n" - " -v file format Voc\n" - " -w file format Wave\n" - " -r file format Raw\n" - " -o channels (1-N)\n" - " -s speed (Hz)\n" - " -f data format\n" - " -F fragment length\n" - " -m set CD-ROM quality (44100Hz,stereo,16-bit linear,little endian)\n" - " -M set DAT quality (48000Hz,stereo,16-bit linear,little endian)\n" - " -t timelimit (seconds)\n" - " -e frames mode\n" - " -E mmap mode\n" - " -N Don't use plugins\n" - " -B Nonblocking mode\n" - " -I Noninterleaved mode\n" - " -S Show setup\n" - ,command, snd_cards()-1); - fprintf(stderr, "\nRecognized data formats are:"); + fprintf(stderr, "\ +Usage: %s [OPTION]... [FILE]... + +--help help +--version print current version +--list-devices list all soundcards and digital audio devices +-C, --card=# select card # or card id (0-%i), defaults to 0 +-D, --device=# select device #, defaults to 0 +-S, --subdevice=# select subdevice #, defaults to first available +-P, --direct don't use plugins for this PCM +-H, --pcm-channels=# channels for last specified PCM +-h, --bind-channel=C,S bind stream channel C to PCM channel S +-q, --quiet quiet mode +-t, --file-type TYPE file type (voc, wav or raw) +-c, --channels=# channels +-f, --format=FORMAT sample format (case insensitive) +-r, --rate=# sample rate +-d, --duration=# interrupt after # seconds +-e, --frame-mode use frame mode instead of default fragment mode +-M, --mmap mmap stream +-Q, --multi-direct don't use plugins on top of multi +-N, --nonblock nonblocking mode +-F, --fragment-length=# fragment length is # milliseconds +-B, --buffer-length=# buffer length is # milliseconds +-A, --min-avail=# min available space for wakeup is # milliseconds +-v, --show-setup show actual setup +-I, --separate-channels one file for each channel\ +", command, snd_cards()-1); + fprintf(stderr, "\nRecognized sample formats are:"); for (k = 0; k < 32; ++k) { const char *s = snd_pcm_get_format_name(k); if (s) fprintf(stderr, " %s", s); } - fprintf(stderr, " (some of these may not be available on selected hardware)\n"); + fprintf(stderr, "\nSome of these may not be available on selected hardware\n"); } static void device_list(void) @@ -209,7 +209,6 @@ static void device_list(void) unsigned int mask; snd_ctl_hw_info_t info; snd_pcm_info_t pcminfo; - snd_pcm_stream_info_t stream_info; mask = snd_cards_mask(); if (!mask) { @@ -229,7 +228,10 @@ static void device_list(void) continue; } for (dev = 0; dev < info.pcmdevs; dev++) { - if ((err = snd_ctl_pcm_info(handle, dev, &pcminfo)) < 0) { + pcminfo.device = dev; + pcminfo.stream = stream; + pcminfo.subdevice = -1; + if ((err = snd_ctl_pcm_info(handle, &pcminfo)) < 0) { fprintf(stderr, "Error: control digital audio info (%i): %s\n", card, snd_strerror(err)); continue; } @@ -239,32 +241,13 @@ static void device_list(void) info.id, dev, pcminfo.name); - fprintf(stderr, " Directions: %s%s%s\n", - pcminfo.flags & SND_PCM_INFO_PLAYBACK ? "playback " : "", - pcminfo.flags & SND_PCM_INFO_CAPTURE ? "capture " : "", - pcminfo.flags & SND_PCM_INFO_DUPLEX ? "duplex " : ""); - fprintf(stderr, " Playback subdevices: %i\n", pcminfo.playback + 1); - fprintf(stderr, " Capture subdevices: %i\n", pcminfo.capture + 1); - if (pcminfo.flags & SND_PCM_INFO_PLAYBACK) { - for (idx = 0; idx <= pcminfo.playback; idx++) { - memset(&stream_info, 0, sizeof(stream_info)); - stream_info.stream = SND_PCM_STREAM_PLAYBACK; - if ((err = snd_ctl_pcm_stream_info(handle, dev, SND_PCM_STREAM_PLAYBACK, idx, &stream_info)) < 0) { - fprintf(stderr, "Error: control digital audio playback info (%i): %s\n", card, snd_strerror(err)); - } else { - fprintf(stderr, " Playback subdevice #%i: %s\n", idx, stream_info.subname); - } - } - } - if (pcminfo.flags & SND_PCM_INFO_CAPTURE) { - for (idx = 0; idx <= pcminfo.capture; idx++) { - memset(&stream_info, 0, sizeof(stream_info)); - stream_info.stream = SND_PCM_STREAM_CAPTURE; - if ((err = snd_ctl_pcm_stream_info(handle, dev, SND_PCM_STREAM_CAPTURE, 0, &stream_info)) < 0) { - fprintf(stderr, "Error: control digital audio capture info (%i): %s\n", card, snd_strerror(err)); - } else { - fprintf(stderr, " Capture subdevice #%i: %s\n", idx, stream_info.subname); - } + fprintf(stderr, " Subdevices: %i/%i\n", pcminfo.subdevices_avail, pcminfo.subdevices_count); + for (idx = 0; idx < pcminfo.subdevices_count; idx++) { + pcminfo.subdevice = idx; + if ((err = snd_ctl_pcm_info(handle, &pcminfo)) < 0) { + fprintf(stderr, "Error: control digital audio playback info (%i): %s\n", card, snd_strerror(err)); + } else { + fprintf(stderr, " Subdevice #%i: %s\n", idx, pcminfo.subname); } } } @@ -277,23 +260,92 @@ static void version(void) fprintf(stderr, "%s: version " SND_UTIL_VERSION_STR " by Jaroslav Kysela \n", command); } +#define OPT_HELP 1 +#define OPT_VERSION 2 + int main(int argc, char *argv[]) { - int card, dev, tmp, err, c; + int option_index; + char *short_options = "lC:D:S:H:h:qt:c:f:r:d:eMPQA:B:F:NvI"; + static struct option long_options[] = { + {"help", 0, 0, OPT_HELP}, + {"version", 0, 0, OPT_VERSION}, + {"list-devices", 0, 0, 'l'}, + {"card", 1, 0, 'C'}, + {"device", 1, 0, 'D'}, + {"subdevice", 1, 0, 'S'}, + {"pcm-channels", 1, 0, 'H'}, + {"bind-channel", 1, 0, 'h'}, + {"quiet", 0, 0, 'q'}, + {"file-type", 1, 0, 't'}, + {"channels", 1, 0, 'c'}, + {"format", 1, 0, 'f'}, + {"rate", 1, 0, 'r'}, + {"duration", 1, 0 ,'d'}, + {"frame-mode", 0, 0, 'e'}, + {"mmap", 0, 0, 'M'}, + {"direct", 0, 0, 'P'}, + {"multi-direct", 0, 0, 'Q'}, + {"nonblock", 0, 0, 'N'}, + {"fragment-length", 1, 0, 'F'}, + {"buffer-length", 1, 0, 'B'}, + {"min-avail", 1, 0, 'A'}, + {"show-setup", 0, 0, 'v'}, + {"separate-channels", 0, 0, 'I'}, + {0, 0, 0, 0} + }; + int binds_pcm[32]; + int binds_client_channel[32]; + int binds_slave_channel[32]; + int pcms_card[32]; + int pcms_dev[32]; + int pcms_subdev[32]; + int pcms_channels[32]; + int pcms_direct[32]; + int direct = 0; + int multi_direct = 0; + + int pcm_card = 0, pcm_dev = 0, pcm_subdev = -1, pcm_channels = -1; + int tmp, err, c, client_channel, slave_channel; + int pcm; + int pcms_count = 0, binds_count = 0; + int multi; + char *ptr, *beg; + + int get_pcm() { + int pcm; + if (pcm_channels < 0) + pcm_channels = rformat.channels; + for (pcm = 0; pcm < pcms_count; ++pcm) { + if (pcms_card[pcm] == pcm_card && + pcms_dev[pcm] == pcm_dev && + pcms_subdev[pcm] == pcm_subdev) + break; + } + if (pcm == pcms_count) { + pcms_card[pcm] = pcm_card; + pcms_dev[pcm] = pcm_dev; + pcms_subdev[pcm] = pcm_subdev; + pcms_channels[pcm] = pcm_channels; + pcms_direct[pcm] = direct; + direct = 0; + pcms_count++; + } else if (pcm_channels != pcms_channels[pcm]) { + fprintf(stderr, "Error: different channels count specified for the same pcm\n"); + exit(1); + } + return pcm; + } - card = 0; - dev = 0; command = argv[0]; - active_format = FORMAT_DEFAULT; + file_type = FORMAT_DEFAULT; if (strstr(argv[0], "arecord")) { - direction = SND_PCM_OPEN_CAPTURE; stream = SND_PCM_STREAM_CAPTURE; - active_format = FORMAT_WAVE; - command = "Arecord"; + file_type = FORMAT_WAVE; + command = "arecord"; } else if (strstr(argv[0], "aplay")) { - direction = SND_PCM_OPEN_PLAYBACK; stream = SND_PCM_STREAM_PLAYBACK; - command = "Aplay"; + command = "aplay"; } else { fprintf(stderr, "Error: command should be named either arecord or aplay\n"); return 1; @@ -306,57 +358,101 @@ int main(int argc, char *argv[]) rformat.rate = DEFAULT_SPEED; rformat.channels = 1; - if (argc > 1 && !strcmp(argv[1], "--help")) { - usage(command); - return 0; - } - if (argc > 1 && !strcmp(argv[1], "--version")) { - version(); - return 0; - } - while ((c = getopt(argc, argv, "hlc:d:qs:o:t:vrwxc:p:mMVeEf:NBF:SI")) != EOF) + while ((c = getopt_long(argc, argv, short_options, long_options, &option_index)) != -1) { switch (c) { - case 'h': + case OPT_HELP: usage(command); return 0; + case OPT_VERSION: + version(); + return 0; case 'l': device_list(); return 0; - case 'c': - card = snd_card_name(optarg); - if (card < 0) { + case 'C': + pcm_card = snd_card_name(optarg); + if (pcm_card < 0) { fprintf(stderr, "Error: soundcard '%s' not found\n", optarg); return 1; } break; - case 'd': - dev = atoi(optarg); - if (dev < 0 || dev > 32) { - fprintf(stderr, "Error: device %i is invalid\n", dev); + case 'D': + pcm_dev = atoi(optarg); + if (pcm_dev < 0 || pcm_dev > 32) { + fprintf(stderr, "Error: device %i is invalid\n", pcm_dev); return 1; } break; - case 'o': - tmp = atoi(optarg); - if (tmp < 1 || tmp > 32) { - fprintf(stderr, "Error: value %i for channels is invalid\n", tmp); + case 'S': + pcm_subdev = atoi(optarg); + if (pcm_subdev < 0 || pcm_subdev > 32) { + fprintf(stderr, "Error: subdevice %i is invalid\n", pcm_subdev); return 1; } - rformat.channels = tmp; + break; + case 'H': + pcm_channels = atoi(optarg); + if (pcm_channels < 1 || pcm_channels > 32) { + fprintf(stderr, "Error: value %i for channels is invalid\n", pcm_channels); + return 1; + } + break; + case 'h': + client_channel = strtol(optarg, &ptr, 10); + if (*ptr != ',' || ptr == optarg) { + fprintf(stderr, "Error: invalid channel binding syntax\n"); + return 1; + } + beg = ptr + 1; + slave_channel = strtol(beg, &ptr, 10); + if (*ptr || ptr == optarg) { + fprintf(stderr, "Error: invalid channel binding syntax\n"); + return 1; + } + if (client_channel >= rformat.channels) { + fprintf(stderr, "Error: attempt to bind unavailable stream channel %d\n", client_channel); + return 1; + } + if (slave_channel >= pcm_channels) { + fprintf(stderr, "Error: attempt to bind to an unavailable PCM channel %d\n", slave_channel); + return 1; + } + pcm = get_pcm(); + binds_pcm[binds_count] = pcm; + binds_client_channel[binds_count] = client_channel; + binds_slave_channel[binds_count] = slave_channel; + ++binds_count; break; case 'q': quiet_mode = 1; break; + case 't': + if (strcasecmp(optarg, "raw") == 0) + file_type = FORMAT_RAW; + else if (strcasecmp(optarg, "voc") == 0) + file_type = FORMAT_VOC; + else if (strcasecmp(optarg, "wav") == 0) + file_type = FORMAT_WAVE; + else { + fprintf(stderr, "Error: unrecognized file format %s\n", optarg); + return 1; + } + break; + case 'c': + rformat.channels = atoi(optarg); + if (rformat.channels < 1 || rformat.channels > 32) { + fprintf(stderr, "Error: value %i for channels is invalid\n", rformat.channels); + return 1; + } + break; + case 'f': + rformat.format = snd_pcm_get_format_value(optarg); + if (rformat.format < 0) { + fprintf(stderr, "Error: wrong extended format '%s'\n", optarg); + exit(EXIT_FAILURE); + } + break; case 'r': - active_format = FORMAT_RAW; - break; - case 'v': - active_format = FORMAT_VOC; - break; - case 'w': - active_format = FORMAT_WAVE; - break; - case 's': tmp = atoi(optarg); if (tmp < 300) tmp *= 1000; @@ -366,79 +462,128 @@ int main(int argc, char *argv[]) return 1; } break; - case 't': + case 'd': timelimit = atoi(optarg); break; - case 'x': - verbose_mode = 1; - quiet_mode = 0; - break; - case 'f': - rformat.format = snd_pcm_get_format_value(optarg); - if (rformat.format < 0) { - fprintf(stderr, "Error: wrong extended format '%s'\n", optarg); - exit(EXIT_FAILURE); - } - break; - case 'm': - case 'M': - rformat.format = SND_PCM_SFMT_S16_LE; - rformat.rate = c == 'M' ? 48000 : 44100; - rformat.channels = 2; - break; - case 'V': - version(); - return 0; case 'e': mode = SND_PCM_MODE_FRAME; break; - case 'E': + case 'M': mmap_flag = 1; break; - case 'N': - noplugin = 1; + case 'P': + direct = 1; break; - case 'B': + case 'Q': + multi_direct = 1; + break; + case 'N': nonblock = 1; + open_mode |= SND_PCM_NONBLOCK; break; case 'F': frag_length = atoi(optarg); break; - case 'S': + case 'B': + buffer_length = atoi(optarg); + break; + case 'A': + min_avail = atoi(optarg); + break; + case 'v': show_setup = 1; break; case 'I': rformat.interleave = 0; break; default: - usage(command); + fprintf(stderr, "Try `%s --help' for more information.\n", command); return 1; } + } + + if (binds_count == 0) { + pcm = get_pcm(); + for (c = 0; c < rformat.channels; ++c) { + if (c > pcm_channels) { + fprintf(stderr, "Error: attempt to bind to an unavailable PCM channel %d\n", c); + return 1; + } + binds_pcm[binds_count] = pcm; + binds_client_channel[binds_count] = c; + binds_slave_channel[binds_count] = c; + binds_count++; + } + } if (!quiet_mode) version(); - if (!quiet_mode) { - char *cardname; - - if ((err = snd_card_get_longname(card, &cardname)) < 0) { - fprintf(stderr, "Error: unable to obtain longname: %s\n", snd_strerror(err)); - return 1; + assert(pcms_count > 0); + + multi = 0; + if (pcms_count != 1 || rformat.channels != binds_count || + pcm_channels != binds_count) + multi = 1; + else { + char mask[binds_count]; + memset(mask, 0, sizeof(mask)); + for (c = 0; c < binds_count; ++c) { + if (binds_client_channel[c] != binds_slave_channel[c]) { + multi = 1; + break; + } + if (mask[c]) { + multi = 1; + break; + } + mask[c] = 1; + } + } + if (!quiet_mode) { + for (pcm = 0; pcm < pcms_count; ++pcm) { + char *cardname; + if ((err = snd_card_get_longname(pcms_card[pcm], &cardname)) < 0) { + fprintf(stderr, "Error: unable to obtain longname: %s\n", snd_strerror(err)); + return 1; + } + fprintf(stderr, "Using soundcard '%s'\n", cardname); + free(cardname); } - fprintf(stderr, "Using soundcard '%s'\n", cardname); - free(cardname); } - if (noplugin) - err = snd_pcm_open(&pcm_handle, card, dev, direction); - else - err = snd_pcm_plug_open(&pcm_handle, card, dev, direction); - if (err < 0) { - fprintf(stderr, "Error: audio open error: %s\n", snd_strerror(err)); - return 1; + { + snd_pcm_t *handles[pcms_count]; + for (pcm = 0; pcm < pcms_count; ++pcm) { + if (pcms_direct[pcm]) + err = snd_pcm_hw_open_subdevice(&handles[pcm], pcms_card[pcm], pcms_dev[pcm], pcms_subdev[pcm], stream, open_mode); + else + err = snd_pcm_plug_open_subdevice(&handles[pcm], pcms_card[pcm], pcms_dev[pcm], pcms_subdev[pcm], stream, open_mode); + if (err < 0) { + fprintf(stderr, "Error: audio open error: %s\n", snd_strerror(err)); + return 1; + } + } + if (multi) { + err = snd_pcm_multi_create(&handle, pcms_count, handles, pcms_channels, binds_count, binds_client_channel, binds_pcm, binds_slave_channel, 1); + if (err < 0) { + fprintf(stderr, "Error: audio open error: %s\n", snd_strerror(err)); + return 1; + } + if (!multi_direct) { + snd_pcm_t *h = handle; + err = snd_pcm_plug_create(&handle, h, 1); + if (err < 0) { + fprintf(stderr, "Error: audio open error: %s\n", snd_strerror(err)); + return 1; + } + } + } else { + handle = handles[0]; + } } if (nonblock) { - err = snd_pcm_stream_nonblock(pcm_handle, stream, 1); + err = snd_pcm_nonblock(handle, 1); if (err < 0) { fprintf(stderr, "nonblock setting error: %s\n", snd_strerror(err)); return 1; @@ -446,7 +591,7 @@ int main(int argc, char *argv[]) } memset(&cinfo, 0, sizeof(cinfo)); cinfo.stream = stream; - if ((err = snd_pcm_stream_info(pcm_handle, &cinfo)) < 0) { + if ((err = snd_pcm_info(handle, &cinfo)) < 0) { fprintf(stderr, "Error: stream info error: %s\n", snd_strerror(err)); return 1; } @@ -492,7 +637,7 @@ int main(int argc, char *argv[]) else capturev(&argv[optind], argc - optind); } - snd_pcm_close(pcm_handle); + snd_pcm_close(handle); return EXIT_SUCCESS; } @@ -614,19 +759,18 @@ static int test_au(int fd, void *buffer) static void set_params(void) { - snd_pcm_stream_params_t params; + snd_pcm_params_t params; align = (snd_pcm_format_physical_width(format.format) + 7) / 8; #if 0 if (mmap_flag) - snd_pcm_munmap(pcm_handle, stream); + snd_pcm_munmap(handle, stream); #endif - snd_pcm_stream_flush(pcm_handle, stream); /* to be in right state */ + snd_pcm_flush(handle); /* to be in right state */ memset(¶ms, 0, sizeof(params)); params.mode = mode; - params.stream = stream; params.format = format; if (stream == SND_PCM_STREAM_PLAYBACK) { params.start_mode = SND_PCM_START_FULL; @@ -635,35 +779,34 @@ static void set_params(void) } params.xrun_mode = SND_PCM_XRUN_FLUSH; params.frag_size = format.rate * frag_length / 1000; - params.buffer_size = params.frag_size * 4; - params.frames_min = format.rate / 16; + params.buffer_size = format.rate * buffer_length / 1000; + params.frames_min = format.rate * min_avail / 1000; params.frames_xrun_max = 0; params.fill_mode = SND_PCM_FILL_SILENCE; params.frames_fill_max = 1024; params.frames_xrun_max = 0; - if (snd_pcm_stream_params(pcm_handle, ¶ms) < 0) { + if (snd_pcm_params(handle, ¶ms) < 0) { fprintf(stderr, "%s: unable to set stream params\n", command); exit(EXIT_FAILURE); } if (mmap_flag) { - if (snd_pcm_mmap(pcm_handle, stream, &mmap_status, &mmap_control, (void **)&mmap_data)<0) { + if (snd_pcm_mmap(handle, &mmap_status, &mmap_control, (void **)&mmap_data)<0) { fprintf(stderr, "%s: unable to mmap memory\n", command); exit(EXIT_FAILURE); } } - if (snd_pcm_stream_prepare(pcm_handle, stream) < 0) { + if (snd_pcm_prepare(handle) < 0) { fprintf(stderr, "%s: unable to prepare stream\n", command); exit(EXIT_FAILURE); } memset(&setup, 0, sizeof(setup)); - setup.stream = stream; - if (snd_pcm_stream_setup(pcm_handle, &setup) < 0) { + if (snd_pcm_setup(handle, &setup) < 0) { fprintf(stderr, "%s: unable to obtain setup\n", command); exit(EXIT_FAILURE); } if (show_setup) - snd_pcm_dump_setup(pcm_handle, stream, stderr); + snd_pcm_dump_setup(handle, stderr); buffer_size = setup.frag_size; bits_per_sample = snd_pcm_format_physical_width(setup.format.format); @@ -681,17 +824,16 @@ static void set_params(void) void playback_underrun(void) { - snd_pcm_stream_status_t status; + snd_pcm_status_t status; memset(&status, 0, sizeof(status)); - status.stream = stream; - if (snd_pcm_stream_status(pcm_handle, &status)<0) { + if (snd_pcm_status(handle, &status)<0) { fprintf(stderr, "playback stream status error\n"); exit(EXIT_FAILURE); } if (status.state == SND_PCM_STATE_XRUN) { fprintf(stderr, "underrun at position %u!!!\n", status.frame_io); - if (snd_pcm_stream_prepare(pcm_handle, SND_PCM_STREAM_PLAYBACK)<0) { + if (snd_pcm_prepare(handle)<0) { fprintf(stderr, "underrun: playback stream prepare error\n"); exit(EXIT_FAILURE); } @@ -705,11 +847,10 @@ void playback_underrun(void) void capture_overrun(void) { - snd_pcm_stream_status_t status; + snd_pcm_status_t status; memset(&status, 0, sizeof(status)); - status.stream = stream; - if (snd_pcm_stream_status(pcm_handle, &status)<0) { + if (snd_pcm_status(handle, &status)<0) { fprintf(stderr, "capture stream status error\n"); exit(EXIT_FAILURE); } @@ -717,7 +858,7 @@ void capture_overrun(void) return; /* everything is ok, but the driver is waiting for data */ if (status.state == SND_PCM_STATE_XRUN) { fprintf(stderr, "overrun at position %u!!!\n", status.frame_io); - if (snd_pcm_stream_prepare(pcm_handle, SND_PCM_STREAM_CAPTURE)<0) { + if (snd_pcm_prepare(handle)<0) { fprintf(stderr, "overrun: capture stream prepare error\n"); exit(EXIT_FAILURE); } @@ -742,10 +883,10 @@ static ssize_t pcm_write(u_char *data, size_t count) count = buffer_size; } while (count > 0) { - r = write_func(pcm_handle, data, count); + r = write_func(handle, data, count); if (r == -EAGAIN || (r >= 0 && r < count)) { struct pollfd pfd; - pfd.fd = snd_pcm_file_descriptor(pcm_handle, SND_PCM_STREAM_PLAYBACK); + pfd.fd = snd_pcm_file_descriptor(handle); pfd.events = POLLOUT | POLLERR; poll(&pfd, 1, 1000); } else if (r == -EPIPE) { @@ -786,10 +927,10 @@ static ssize_t pcm_writev(u_char **data, unsigned int channels, size_t count) vec[channel].iov_base = data[channel] + offset * bits_per_sample / 8; vec[channel].iov_len = remaining; } - r = writev_func(pcm_handle, vec, channels); + r = writev_func(handle, vec, channels); if (r == -EAGAIN || (r >= 0 && r < count)) { struct pollfd pfd; - pfd.fd = snd_pcm_file_descriptor(pcm_handle, SND_PCM_STREAM_PLAYBACK); + pfd.fd = snd_pcm_file_descriptor(handle); pfd.events = POLLOUT | POLLERR; poll(&pfd, 1, 1000); } else if (r == -EPIPE) { @@ -816,10 +957,10 @@ static ssize_t pcm_read(u_char *data, size_t count) size_t result = 0; while (count > 0) { - r = read_func(pcm_handle, data, count); + r = read_func(handle, data, count); if (r == -EAGAIN || (r >= 0 && r < count)) { struct pollfd pfd; - pfd.fd = snd_pcm_file_descriptor(pcm_handle, SND_PCM_STREAM_CAPTURE); + pfd.fd = snd_pcm_file_descriptor(handle); pfd.events = POLLIN | POLLERR; poll(&pfd, 1, 1000); } else if (r == -EPIPE) { @@ -851,10 +992,10 @@ static ssize_t pcm_readv(u_char **data, unsigned int channels, size_t count) vec[channel].iov_base = data[channel] + offset * bits_per_sample / 8; vec[channel].iov_len = remaining; } - r = readv_func(pcm_handle, vec, channels); + r = readv_func(handle, vec, channels); if (r == -EAGAIN || (r >= 0 && r < count)) { struct pollfd pfd; - pfd.fd = snd_pcm_file_descriptor(pcm_handle, SND_PCM_STREAM_CAPTURE); + pfd.fd = snd_pcm_file_descriptor(handle); pfd.events = POLLIN | POLLERR; poll(&pfd, 1, 1000); } else if (r == -EPIPE) { @@ -934,7 +1075,7 @@ static void voc_pcm_flush(void) if (pcm_write(audiobuf, b) != b) fprintf(stderr, "voc_pcm_flush error\n"); } - snd_pcm_stream_flush(pcm_handle, SND_PCM_STREAM_PLAYBACK); + snd_pcm_flush(handle); } static void voc_play(int fd, int ofs, char *name) @@ -1403,7 +1544,7 @@ void playback_go(int fd, size_t loaded, size_t count, int rtype, char *name) written += r; l = 0; } - snd_pcm_stream_flush(pcm_handle, SND_PCM_STREAM_PLAYBACK); + snd_pcm_flush(handle); } /* captureing raw data, this proc handels WAVE files and .VOCs (as one block) */ @@ -1440,7 +1581,7 @@ static void playback(char *name) { int fd, ofs; - snd_pcm_stream_flush(pcm_handle, SND_PCM_STREAM_PLAYBACK); + snd_pcm_flush(handle); if (!name || !strcmp(name, "-")) { fd = 0; name = "stdin"; @@ -1496,7 +1637,7 @@ static void capture(char *name) { int fd; - snd_pcm_stream_flush(pcm_handle, SND_PCM_STREAM_CAPTURE); + snd_pcm_flush(handle); if (!name || !strcmp(name, "-")) { fd = 1; name = "stdout"; @@ -1510,11 +1651,11 @@ static void capture(char *name) count = calc_count() & 0xFFFFFFFE; /* WAVE-file should be even (I'm not sure), but wasting one byte isn't a problem (this can only be in 8 bit mono) */ - if (fmt_rec_table[active_format].start) - fmt_rec_table[active_format].start(fd, count); + if (fmt_rec_table[file_type].start) + fmt_rec_table[file_type].start(fd, count); check_new_format(&rformat); - capture_go(fd, count, active_format, name); - fmt_rec_table[active_format].end(fd); + capture_go(fd, count, file_type, name); + fmt_rec_table[file_type].end(fd); } void playbackv_go(int* fds, unsigned int channels, size_t loaded, size_t count, int rtype, char **names) @@ -1563,7 +1704,7 @@ void playbackv_go(int* fds, unsigned int channels, size_t loaded, size_t count, r = r * bits_per_frame / 8; count -= r; } - snd_pcm_stream_flush(pcm_handle, SND_PCM_STREAM_PLAYBACK); + snd_pcm_flush(handle); } void capturev_go(int* fds, unsigned int channels, size_t count, int rtype, char **names) @@ -1612,7 +1753,7 @@ static void playbackv(char **names, unsigned int count) for (channel = 0; channel < channels; ++channel) fds[channel] = -1; - snd_pcm_stream_flush(pcm_handle, SND_PCM_STREAM_PLAYBACK); + snd_pcm_flush(handle); if (count == 1) { size_t len = strlen(names[0]); char format[1024]; @@ -1667,7 +1808,7 @@ static void capturev(char **names, unsigned int count) for (channel = 0; channel < channels; ++channel) fds[channel] = -1; - snd_pcm_stream_flush(pcm_handle, SND_PCM_STREAM_CAPTURE); + snd_pcm_flush(handle); if (count == 1) { size_t len = strlen(names[0]); char format[1024];