Corrected and completed encapsulation for PCM and rawmidi. Remove SND_PCM_HW_PARAM_* and use functions. Separated rawmidi info between streams

This commit is contained in:
Abramo Bagnara 2001-02-04 17:03:19 +00:00
parent a2426856b3
commit 2121e1576c

View file

@ -61,7 +61,7 @@ static snd_pcm_sframes_t (*writen_func)(snd_pcm_t *handle, void **bufs, snd_pcm_
static char *command; static char *command;
static snd_pcm_t *handle; static snd_pcm_t *handle;
static struct { static struct {
unsigned int format; snd_pcm_format_t format;
unsigned int channels; unsigned int channels;
unsigned int rate; unsigned int rate;
} hwparams, rhwparams; } hwparams, rhwparams;
@ -70,7 +70,7 @@ static int quiet_mode = 0;
static int file_type = FORMAT_DEFAULT; static int file_type = FORMAT_DEFAULT;
static unsigned int sleep_min = 0; static unsigned int sleep_min = 0;
static int open_mode = 0; static int open_mode = 0;
static int stream = SND_PCM_STREAM_PLAYBACK; static snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
static int mmap_flag = 0; static int mmap_flag = 0;
static int interleaved = 1; static int interleaved = 1;
static int nonblock = 0; static int nonblock = 0;
@ -130,7 +130,7 @@ struct fmt_capture {
static void usage(char *command) static void usage(char *command)
{ {
int k; snd_pcm_format_t k;
fprintf(stderr, "\ fprintf(stderr, "\
Usage: %s [OPTION]... [FILE]... Usage: %s [OPTION]... [FILE]...
@ -158,7 +158,7 @@ Usage: %s [OPTION]... [FILE]...
-C, --iec958c AES IEC958 consumer -C, --iec958c AES IEC958 consumer
", command); ", command);
fprintf(stderr, "Recognized sample formats are:"); fprintf(stderr, "Recognized sample formats are:");
for (k = 0; k < 32; ++k) { for (k = 0; k < SND_PCM_FORMAT_LAST; ++(unsigned long) k) {
const char *s = snd_pcm_format_name(k); const char *s = snd_pcm_format_name(k);
if (s) if (s)
fprintf(stderr, " %s", s); fprintf(stderr, " %s", s);
@ -212,16 +212,16 @@ static void device_list(void)
fprintf(stderr, "card %i: %s [%s], device %i: %s [%s]\n", fprintf(stderr, "card %i: %s [%s], device %i: %s [%s]\n",
card, info.id, info.name, card, info.id, info.name,
dev, dev,
snd_pcm_info_device_id(pcminfo), snd_pcm_info_get_id(pcminfo),
snd_pcm_info_device_name(pcminfo)); snd_pcm_info_get_name(pcminfo));
count = snd_pcm_info_subdevices_count(pcminfo); count = snd_pcm_info_get_subdevices_count(pcminfo);
fprintf(stderr, " Subdevices: %i/%i\n", snd_pcm_info_subdevices_avail(pcminfo), count); fprintf(stderr, " Subdevices: %i/%i\n", snd_pcm_info_get_subdevices_avail(pcminfo), count);
for (idx = 0; idx < count; idx++) { for (idx = 0; idx < count; idx++) {
snd_pcm_info_set_subdevice(pcminfo, idx); snd_pcm_info_set_subdevice(pcminfo, idx);
if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) { if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) {
error("control digital audio playback info (%i): %s", card, snd_strerror(err)); error("control digital audio playback info (%i): %s", card, snd_strerror(err));
} else { } else {
fprintf(stderr, " Subdevice #%i: %s\n", idx, snd_pcm_info_subdevice_name(pcminfo)); fprintf(stderr, " Subdevice #%i: %s\n", idx, snd_pcm_info_get_subdevice_name(pcminfo));
} }
} }
} }
@ -454,10 +454,10 @@ int main(int argc, char *argv[])
memset(&ctl, 0, sizeof(ctl)); memset(&ctl, 0, sizeof(ctl));
ctl.id.numid = 0; ctl.id.numid = 0;
ctl.id.iface = SND_CONTROL_IFACE_PCM; ctl.id.iface = SND_CONTROL_IFACE_PCM;
ctl.id.device = snd_pcm_info_device(info); ctl.id.device = snd_pcm_info_get_device(info);
ctl.id.subdevice = snd_pcm_info_subdevice(info); ctl.id.subdevice = snd_pcm_info_get_subdevice(info);
strcpy(ctl.id.name, "IEC958 (S/PDIF) Stream"); strcpy(ctl.id.name, "IEC958 (S/PDIF) Stream");
ctl_card = snd_pcm_info_card(info); ctl_card = snd_pcm_info_get_card(info);
if (ctl_card < 0) { if (ctl_card < 0) {
error("Unable to setup the IEC958 (S/PDIF) interface - PCM has no assigned card"); error("Unable to setup the IEC958 (S/PDIF) interface - PCM has no assigned card");
goto __diga_end; goto __diga_end;
@ -731,56 +731,48 @@ static void set_params(void)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (mmap_flag) { if (mmap_flag) {
snd_mask_t *mask = alloca(snd_mask_sizeof()); snd_pcm_access_mask_t *mask = alloca(snd_pcm_access_mask_sizeof());
snd_mask_none(mask); snd_pcm_access_mask_none(mask);
snd_mask_set(mask, SND_PCM_ACCESS_MMAP_INTERLEAVED); snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_INTERLEAVED);
snd_mask_set(mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED); snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
snd_mask_set(mask, SND_PCM_ACCESS_MMAP_COMPLEX); snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_COMPLEX);
err = snd_pcm_hw_param_mask(handle, params, err = snd_pcm_hw_params_set_access_mask(handle, params,
SND_PCM_HW_PARAM_ACCESS, mask); SND_CHANGE, mask);
} else if (interleaved) } else if (interleaved)
err = snd_pcm_hw_param_set(handle, params, err = snd_pcm_hw_params_set_access(handle, params, SND_CHANGE,
SND_PCM_HW_PARAM_ACCESS, SND_PCM_ACCESS_RW_INTERLEAVED);
SND_PCM_ACCESS_RW_INTERLEAVED, 0);
else else
err = snd_pcm_hw_param_set(handle, params, err = snd_pcm_hw_params_set_access(handle, params, SND_CHANGE,
SND_PCM_HW_PARAM_ACCESS, SND_PCM_ACCESS_RW_NONINTERLEAVED);
SND_PCM_ACCESS_RW_NONINTERLEAVED, 0);
if (err < 0) { if (err < 0) {
error("Access type not available"); error("Access type not available");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
err = snd_pcm_hw_param_set(handle, params, SND_PCM_HW_PARAM_FORMAT, err = snd_pcm_hw_params_set_format(handle, params, SND_CHANGE, hwparams.format);
hwparams.format, 0);
if (err < 0) { if (err < 0) {
error("Sample format non available"); error("Sample format non available");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
err = snd_pcm_hw_param_set(handle, params, SND_PCM_HW_PARAM_CHANNELS, err = snd_pcm_hw_params_set_channels(handle, params, SND_CHANGE, hwparams.channels);
hwparams.channels, 0);
if (err < 0) { if (err < 0) {
error("Channels count non available"); error("Channels count non available");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
#if 0 #if 0
err = snd_pcm_hw_param_min(handle, params, err = snd_pcm_hw_params_set_periods_min(handle, params, SND_CHANGE, 2);
SND_PCM_HW_PARAM_PERIODS, 2);
assert(err >= 0); assert(err >= 0);
#endif #endif
err = snd_pcm_hw_param_near(handle, params, err = snd_pcm_hw_params_set_rate_near(handle, params, hwparams.rate, 0);
SND_PCM_HW_PARAM_RATE, hwparams.rate, 0);
assert(err >= 0); assert(err >= 0);
if (buffer_time < 0) if (buffer_time < 0)
buffer_time = 500000; buffer_time = 500000;
buffer_time = snd_pcm_hw_param_near(handle, params, buffer_time = snd_pcm_hw_params_set_buffer_time_near(handle, params,
SND_PCM_HW_PARAM_BUFFER_TIME,
buffer_time, 0); buffer_time, 0);
assert(buffer_time >= 0); assert(buffer_time >= 0);
if (period_time < 0) if (period_time < 0)
period_time = buffer_time / 4; period_time = buffer_time / 4;
period_time = snd_pcm_hw_param_near(handle, params, period_time = snd_pcm_hw_params_set_period_time_near(handle, params,
SND_PCM_HW_PARAM_PERIOD_TIME,
period_time, 0); period_time, 0);
assert(period_time >= 0); assert(period_time >= 0);
err = snd_pcm_hw_params(handle, params); err = snd_pcm_hw_params(handle, params);
@ -789,34 +781,28 @@ static void set_params(void)
snd_pcm_hw_params_dump(params, log); snd_pcm_hw_params_dump(params, log);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
chunk_size = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_PERIOD_SIZE, 0); chunk_size = snd_pcm_hw_params_get_period_size(params, 0);
buffer_size = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_BUFFER_SIZE, 0); buffer_size = snd_pcm_hw_params_get_buffer_size(params);
snd_pcm_sw_params_current(handle, swparams); snd_pcm_sw_params_current(handle, swparams);
xfer_align = snd_pcm_sw_param_value(swparams, SND_PCM_SW_PARAM_XFER_ALIGN); xfer_align = snd_pcm_sw_params_get_xfer_align(swparams);
if (sleep_min) if (sleep_min)
xfer_align = 1; xfer_align = 1;
err = snd_pcm_sw_param_set(handle, swparams, err = snd_pcm_sw_params_set_sleep_min(handle, swparams,
SND_PCM_SW_PARAM_SLEEP_MIN, sleep_min); sleep_min);
assert(err >= 0); assert(err >= 0);
if (avail_min < 0) if (avail_min < 0)
n = chunk_size; n = chunk_size;
else else
n = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_RATE, 0) * (double) avail_min / 1000000; n = snd_pcm_hw_params_get_rate(params, 0) * (double) avail_min / 1000000;
err = snd_pcm_sw_param_near(handle, swparams, err = snd_pcm_sw_params_set_avail_min(handle, swparams, n);
SND_PCM_SW_PARAM_AVAIL_MIN, n);
err = snd_pcm_sw_param_near(handle, swparams, err = snd_pcm_sw_params_set_xfer_align(handle, swparams, xfer_align);
SND_PCM_SW_PARAM_XFER_ALIGN, xfer_align);
assert(err >= 0); assert(err >= 0);
if (snd_pcm_sw_params(handle, swparams) < 0) { if (snd_pcm_sw_params(handle, swparams) < 0) {
error("unable to install sw params:"); error("unable to install sw params:");
snd_pcm_sw_params_dump(swparams, log); snd_pcm_sw_params_dump(swparams, log);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (snd_pcm_prepare(handle) < 0) {
error("unable to prepare PCM");
exit(EXIT_FAILURE);
}
if (verbose) if (verbose)
snd_pcm_dump(handle, log); snd_pcm_dump(handle, log);
@ -844,10 +830,10 @@ void xrun(void)
error("status error: %s", snd_strerror(res)); error("status error: %s", snd_strerror(res));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if (snd_pcm_status_state(status) == SND_PCM_STATE_XRUN) { if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN) {
struct timeval now, diff, tstamp; struct timeval now, diff, tstamp;
gettimeofday(&now, 0); gettimeofday(&now, 0);
snd_pcm_status_trigger_tstamp(status, &tstamp); snd_pcm_status_get_trigger_tstamp(status, &tstamp);
timersub(&now, &tstamp, &diff); timersub(&now, &tstamp, &diff);
fprintf(stderr, "xrun!!! (at least %.3f ms long)\n", diff.tv_sec * 1000 + diff.tv_usec / 1000.0); fprintf(stderr, "xrun!!! (at least %.3f ms long)\n", diff.tv_sec * 1000 + diff.tv_usec / 1000.0);
if (verbose) { if (verbose) {
@ -1373,7 +1359,7 @@ static void begin_wave(int fd, size_t cnt)
u_short tmp2; u_short tmp2;
bits = 8; bits = 8;
switch (hwparams.format) { switch ((unsigned long) hwparams.format) {
case SND_PCM_FORMAT_U8: case SND_PCM_FORMAT_U8:
bits = 8; bits = 8;
break; break;
@ -1428,7 +1414,7 @@ static void begin_au(int fd, size_t cnt)
ah.magic = AU_MAGIC; ah.magic = AU_MAGIC;
ah.hdr_size = BE_INT(24); ah.hdr_size = BE_INT(24);
ah.data_size = BE_INT(cnt); ah.data_size = BE_INT(cnt);
switch (hwparams.format) { switch ((unsigned long) hwparams.format) {
case SND_PCM_FORMAT_MU_LAW: case SND_PCM_FORMAT_MU_LAW:
ah.encoding = BE_INT(AU_FMT_ULAW); ah.encoding = BE_INT(AU_FMT_ULAW);
break; break;