Added dump facility. Continued pcm_multi implementation

This commit is contained in:
Abramo Bagnara 2000-07-17 15:33:29 +00:00
parent d379686996
commit 84cb338f83
9 changed files with 360 additions and 68 deletions

View file

@ -146,6 +146,7 @@ ssize_t snd_pcm_read(snd_pcm_t *handle, void *buffer, size_t size);
ssize_t snd_pcm_writev(snd_pcm_t *handle, const struct iovec *vector, unsigned long count);
ssize_t snd_pcm_readv(snd_pcm_t *handle, const struct iovec *vector, unsigned long count);
int snd_pcm_dump_setup(snd_pcm_t *handle, FILE *fp);
int snd_pcm_dump(snd_pcm_t *handle, FILE *fp);
int snd_pcm_channels_mask(snd_pcm_t *handle, bitset_t *client_vmask);
@ -176,9 +177,9 @@ ssize_t snd_pcm_mmap_read_frames(snd_pcm_t *handle, const void *buffer, size_t f
int snd_pcm_mmap_get_areas(snd_pcm_t *handle, snd_pcm_channel_area_t *areas);
const char *snd_pcm_get_format_name(int format);
const char *snd_pcm_get_format_description(int format);
int snd_pcm_get_format_value(const char* name);
const char *snd_pcm_format_name(int format);
const char *snd_pcm_format_description(int format);
int snd_pcm_format_value(const char* name);
int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_channel, size_t dst_offset,
size_t samples, int format);
@ -274,6 +275,7 @@ struct snd_stru_pcm_plugin {
int (*parameter_get)(snd_pcm_plugin_t *plugin,
const char *name,
unsigned long *value);
void (*dump)(snd_pcm_plugin_t *plugin, FILE *fp);
snd_pcm_plugin_t *prev;
snd_pcm_plugin_t *next;
snd_pcm_plug_t *plug;
@ -290,15 +292,11 @@ struct snd_stru_pcm_plugin {
int snd_pcm_plug_create(snd_pcm_t **handle, snd_pcm_t *slave, int close_slave);
int snd_pcm_plug_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevice, int stream, int mode);
int snd_pcm_plug_open(snd_pcm_t **handle, int card, int device, int stream, int mode);
int snd_pcm_multi_create(snd_pcm_t **handlep, size_t slaves_count,
snd_pcm_t **slaves_handle, size_t *slaves_channels_count,
size_t binds_count, unsigned int *binds_client_channel,
unsigned int *binds_slave, unsigned int *binds_slave_channel,
int close_slaves);
int snd_pcm_plugin_free(snd_pcm_plugin_t *plugin);
int snd_pcm_plugin_insert(snd_pcm_plugin_t *plugin);
int snd_pcm_plugin_append(snd_pcm_plugin_t *plugin);
void snd_pcm_plugin_dump(snd_pcm_plugin_t *plugin, FILE *fp);
int snd_pcm_plug_alloc(snd_pcm_plug_t *plug, size_t frames);
int snd_pcm_plug_clear(snd_pcm_plug_t *plug);
snd_pcm_plugin_t *snd_pcm_plug_first(snd_pcm_plug_t *plug);
@ -371,6 +369,12 @@ int snd_pcm_plugin_build_copy(snd_pcm_plug_t *plug,
snd_pcm_format_t *dst_format,
snd_pcm_plugin_t **r_plugin);
int snd_pcm_multi_create(snd_pcm_t **handlep, size_t slaves_count,
snd_pcm_t **slaves_handle, size_t *slaves_channels_count,
size_t binds_count, unsigned int *binds_client_channel,
unsigned int *binds_slave, unsigned int *binds_slave_channel,
int close_slaves);
#ifdef __cplusplus
}
#endif

View file

@ -249,6 +249,8 @@ ssize_t snd_pcm_writev(snd_pcm_t *handle, const struct iovec *vector, unsigned l
assert(handle);
assert(count == 0 || vector);
assert(handle->valid_setup);
assert(handle->setup.format.interleave ||
count % handle->setup.format.channels == 0);
return handle->ops->writev(handle->op_arg, -1, vector, count);
}
@ -366,6 +368,7 @@ int snd_pcm_dump_setup(snd_pcm_t *handle, FILE *fp)
{
snd_pcm_setup_t *setup;
assert(handle);
assert(fp);
assert(handle->valid_setup);
setup = &handle->setup;
fprintf(fp, "stream: %s\n", assoc(handle->stream, streams));
@ -392,7 +395,15 @@ int snd_pcm_dump_setup(snd_pcm_t *handle, FILE *fp)
return 0;
}
const char *snd_pcm_get_format_name(int format)
int snd_pcm_dump(snd_pcm_t *handle, FILE *fp)
{
assert(handle);
assert(fp);
handle->ops->dump(handle->op_arg, fp);
return 0;
}
const char *snd_pcm_format_name(int format)
{
assoc_t *a = assoc_value(format, fmts);
if (a)
@ -400,7 +411,7 @@ const char *snd_pcm_get_format_name(int format)
return 0;
}
const char *snd_pcm_get_format_description(int format)
const char *snd_pcm_format_description(int format)
{
assoc_t *a = assoc_value(format, fmts);
if (a)
@ -408,7 +419,7 @@ const char *snd_pcm_get_format_description(int format)
return "Unknown";
}
int snd_pcm_get_format_value(const char* name)
int snd_pcm_format_value(const char* name)
{
assoc_t *a = assoc_name(name, fmts);
if (a)

View file

@ -32,6 +32,7 @@
typedef struct {
snd_pcm_t *handle;
int fd;
int card, device, subdevice;
} snd_pcm_hw_t;
#define SND_FILE_PCM_STREAM_PLAYBACK "/dev/snd/pcmC%iD%ip"
@ -330,6 +331,21 @@ static int snd_pcm_hw_channels_mask(void *private UNUSED,
return 0;
}
static void snd_pcm_hw_dump(void *private, FILE *fp)
{
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) private;
snd_pcm_t *handle = hw->handle;
char *name = "Unknown";
snd_card_get_name(hw->card, &name);
fprintf(fp, "Hardware PCM card %d '%s' device %d subdevice %d\n",
hw->card, name, hw->device, hw->subdevice);
free(name);
if (handle->valid_setup) {
fprintf(fp, "\nIts setup is:\n");
snd_pcm_dump_setup(handle, fp);
}
}
struct snd_pcm_ops snd_pcm_hw_ops = {
close: snd_pcm_hw_close,
nonblock: snd_pcm_hw_nonblock,
@ -359,6 +375,7 @@ struct snd_pcm_ops snd_pcm_hw_ops = {
munmap_data: snd_pcm_hw_munmap_data,
file_descriptor: snd_pcm_hw_file_descriptor,
channels_mask: snd_pcm_hw_channels_mask,
dump: snd_pcm_hw_dump,
};
int snd_pcm_hw_open_subdevice(snd_pcm_t **handlep, int card, int device, int subdevice, int stream, int mode)
@ -436,6 +453,9 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **handlep, int card, int device, int sub
goto __end;
}
hw->handle = handle;
hw->card = card;
hw->device = device;
hw->subdevice = subdevice;
hw->fd = fd;
handle->type = SND_PCM_TYPE_HW;
handle->stream = stream;

View file

@ -51,6 +51,7 @@ struct snd_pcm_ops {
int (*munmap_data)(void *private, void *buffer, size_t bsize);
int (*file_descriptor)(void *private);
int (*channels_mask)(void *private, bitset_t *client_vmask);
void (*dump)(void *private, FILE *fp);
};
struct snd_pcm {

View file

@ -50,6 +50,7 @@ typedef struct {
size_t binds_count;
snd_pcm_multi_bind_t *binds;
size_t channels_count;
size_t frames_alloc;
int interleave;
int one_to_many;
} snd_pcm_multi_t;
@ -99,6 +100,7 @@ static int snd_pcm_multi_info(void *private, snd_pcm_info_t *info)
for (i = 1; i < multi->slaves_count; ++i) {
snd_pcm_t *handle_i = multi->slaves[i].handle;
snd_pcm_info_t info_i;
memset(&info_i, 0, sizeof(info_i));
err = snd_pcm_info(handle_i, &info_i);
if (err < 0)
return err;
@ -115,12 +117,17 @@ static int snd_pcm_multi_params_info(void *private, snd_pcm_params_info_t *info)
unsigned int i;
int err;
snd_pcm_t *handle_0 = multi->slaves[0].handle;
unsigned int old_mask = info->req_mask;
info->req_mask &= ~SND_PCM_PARAMS_CHANNELS;
err = snd_pcm_params_info(handle_0, info);
if (err < 0)
return err;
info->min_channels = multi->channels_count;
info->max_channels = multi->channels_count;
for (i = 1; i < multi->slaves_count; ++i) {
snd_pcm_t *handle_i = multi->slaves[i].handle;
snd_pcm_params_info_t info_i;
info_i = *info;
err = snd_pcm_params_info(handle_i, &info_i);
if (err < 0)
return err;
@ -141,6 +148,7 @@ static int snd_pcm_multi_params_info(void *private, snd_pcm_params_info_t *info)
if (info_i.max_fragments < info->max_fragments)
info->max_fragments = info_i.max_fragments;
}
info->req_mask = old_mask;
return 0;
}
@ -166,6 +174,9 @@ static int snd_pcm_multi_params(void *private, snd_pcm_params_t *params)
else if (!(info.flags & SND_PCM_INFO_NONINTERLEAVE))
p.format.interleave = 1;
p.format.channels = multi->slaves[i].channels_total;
#if 1
p.frames_xrun_max = ~0;
#endif
err = snd_pcm_params(handle, &p);
if (err < 0)
return err;
@ -186,9 +197,12 @@ static int snd_pcm_multi_setup(void *private, snd_pcm_setup_t *setup)
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
unsigned int i;
int err;
size_t frames_alloc;
err = snd_pcm_setup(multi->slaves[0].handle, setup);
if (err < 0)
return err;
frames_alloc = multi->slaves[0].handle->setup.frag_size;
multi->frames_alloc = 0;
for (i = 1; i < multi->slaves_count; ++i) {
snd_pcm_setup_t s;
snd_pcm_t *sh = multi->slaves[i].handle;
@ -219,7 +233,7 @@ static int snd_pcm_multi_setup(void *private, snd_pcm_setup_t *setup)
if (!multi->handle->setup.format.interleave)
continue;
}
s->buf = malloc(sh->setup.frag_size * sh->bits_per_frame / 8);
s->buf = malloc(frames_alloc * sh->bits_per_frame / 8);
if (!s->buf)
return -ENOMEM;
snd_pcm_format_set_silence(sh->setup.format.format, s->buf,
@ -237,9 +251,11 @@ static int snd_pcm_multi_setup(void *private, snd_pcm_setup_t *setup)
a->addr = s->buf + sh->setup.frag_size * sh->bits_per_sample / 8;
a->first = 0;
a->step = sh->bits_per_sample;
s->iovec[c].iov_base = a->addr;
}
}
}
multi->frames_alloc = frames_alloc;
/* Loaded with a value != 0 if mmap is feasible */
setup->mmap_bytes = !multi->one_to_many;
return 0;
@ -376,14 +392,14 @@ static ssize_t snd_pcm_multi_frame_data(void *private, off_t offset)
}
return newpos;
}
ssize_t snd_pcm_multi_write(void *private, snd_timestamp_t timestamp UNUSED, const void *buf, size_t count)
static int snd_pcm_multi_write_copy(snd_pcm_multi_t *multi, const void *buf,
size_t offset, size_t count)
{
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
snd_pcm_t *handle = multi->handle;
unsigned int i;
snd_pcm_channel_area_t area;
area.addr = (void *) buf;
snd_pcm_t *handle = multi->handle;
area.addr = (void *) buf + offset * handle->bits_per_frame;
area.step = handle->bits_per_frame;
for (i = 0; i < multi->binds_count; ++i) {
snd_pcm_multi_bind_t *bind = &multi->binds[i];
@ -394,41 +410,147 @@ ssize_t snd_pcm_multi_write(void *private, snd_timestamp_t timestamp UNUSED, con
err = snd_pcm_area_copy(&area, 0, &slave->areas[bind->slave_channel], 0, count, handle->setup.format.format);
if (err < 0)
return err;
if (!slave->handle->setup.format.interleave)
slave->iovec[bind->slave_channel].iov_base = slave->areas[bind->slave_channel].addr;
if (!slave->handle->setup.format.interleave) {
struct iovec *vec = &slave->iovec[bind->slave_channel];
vec->iov_len = count;
}
}
return 0;
}
static int snd_pcm_multi_writev_copy(snd_pcm_multi_t *multi, const struct iovec *vec,
size_t offset, size_t count)
{
unsigned int i;
snd_pcm_channel_area_t area;
snd_pcm_t *handle = multi->handle;
area.first = 0;
area.step = handle->bits_per_sample;
for (i = 0; i < multi->binds_count; ++i) {
snd_pcm_multi_bind_t *bind = &multi->binds[i];
snd_pcm_multi_slave_t *slave = &multi->slaves[bind->slave];
int err;
area.addr = vec[bind->client_channel].iov_base +
offset * handle->bits_per_sample;
if (slave->handle->setup.format.interleave) {
assert(slave->buf);
err = snd_pcm_area_copy(&area, 0, &slave->areas[bind->slave_channel], 0, count, handle->setup.format.format);
if (err < 0)
return err;
} else {
struct iovec *vec = &slave->iovec[bind->slave_channel];
vec->iov_base = area.addr;
vec->iov_len = count;
}
}
return 0;
}
static ssize_t snd_pcm_multi_write_io(snd_pcm_multi_t *multi, size_t count)
{
unsigned int i;
ssize_t frames = count;
for (i = 0; i < multi->slaves_count; ++i) {
snd_pcm_multi_slave_t *slave = &multi->slaves[i];
snd_pcm_t *sh = slave->handle;
if (sh->setup.format.interleave) {
count = snd_pcm_write(sh, slave->buf, count);
frames = snd_pcm_write(sh, slave->buf, frames);
} else {
int channels = sh->setup.format.channels;
struct iovec vec[channels];
int c;
for (c = 0; c < channels; ++c)
vec[c].iov_len = count;
count = snd_pcm_writev(sh, vec, channels);
frames = snd_pcm_writev(sh, slave->iovec, channels);
}
if (count <= 0)
if (frames <= 0)
break;
}
return count;
return frames;
}
ssize_t snd_pcm_multi_read(void *private, snd_timestamp_t timestamp UNUSED, void *buf, size_t count)
static ssize_t snd_pcm_multi_write(void *private, snd_timestamp_t timestamp UNUSED, const void *buf, size_t count)
{
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
size_t result = 0;
while (count > 0) {
int err;
ssize_t ret;
size_t frames = count;
if (frames > multi->frames_alloc)
frames = multi->frames_alloc;
err = snd_pcm_multi_write_copy(multi, buf, result, frames);
if (err < 0)
return err;
ret = snd_pcm_multi_write_io(multi, frames);
if (ret > 0)
result += ret;
if (ret != (ssize_t)frames) {
if (result > 0)
return result;
return ret;
}
count -= ret;
}
return result;
}
static ssize_t snd_pcm_multi_writev1(snd_pcm_multi_t *multi, const struct iovec *vector, size_t count)
{
size_t result = 0;
while (count > 0) {
int err;
ssize_t ret;
size_t frames = count;
if (frames > multi->frames_alloc)
frames = multi->frames_alloc;
err = snd_pcm_multi_writev_copy(multi, vector, result, frames);
if (err < 0)
return err;
ret = snd_pcm_multi_write_io(multi, frames);
if (ret > 0)
result += ret;
if (ret != (ssize_t) frames) {
if (result > 0)
return result;
return ret;
}
count -= ret;
}
return result;
}
static ssize_t snd_pcm_multi_writev(void *private, snd_timestamp_t timestamp UNUSED, const struct iovec *vector, unsigned long count)
{
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
snd_pcm_t *handle = multi->handle;
unsigned int k, step;
size_t result = 0;
if (handle->setup.format.interleave)
step = 1;
else
step = handle->setup.format.channels;
for (k = 0; k < count; k += step) {
ssize_t ret;
if (handle->setup.format.interleave)
ret = snd_pcm_multi_write(private, timestamp, vector->iov_base, vector->iov_len);
else
ret = snd_pcm_multi_writev1(multi, vector, vector->iov_len);
if (ret > 0)
result += ret;
if (ret != (ssize_t) vector->iov_len) {
if (result > 0)
return result;
return ret;
}
vector += step;
}
return result;
}
static ssize_t snd_pcm_multi_read(void *private, snd_timestamp_t timestamp UNUSED, void *buf, size_t count)
{
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
return -ENOSYS;
}
ssize_t snd_pcm_multi_writev(void *private, snd_timestamp_t timestamp UNUSED, const struct iovec *vector, unsigned long count)
{
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
return -ENOSYS;
}
ssize_t snd_pcm_multi_readv(void *private, snd_timestamp_t timestamp UNUSED, const struct iovec *vector, unsigned long count)
static ssize_t snd_pcm_multi_readv(void *private, snd_timestamp_t timestamp UNUSED, const struct iovec *vector, unsigned long count)
{
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
return -ENOSYS;
@ -577,6 +699,29 @@ int snd_pcm_multi_file_descriptor(void *private)
return snd_pcm_file_descriptor(handle);
}
static void snd_pcm_multi_dump(void *private, FILE *fp)
{
snd_pcm_multi_t *multi = (snd_pcm_multi_t*) private;
snd_pcm_t *handle = multi->handle;
unsigned int k;
fprintf(fp, "Multi PCM\n");
if (handle->valid_setup) {
fprintf(fp, "\nIts setup is:\n");
snd_pcm_dump_setup(handle, fp);
}
for (k = 0; k < multi->slaves_count; ++k) {
fprintf(fp, "\nSlave #%d: ", k);
snd_pcm_dump(multi->slaves[k].handle, fp);
}
fprintf(fp, "\nBindings:\n");
for (k = 0; k < multi->binds_count; ++k) {
fprintf(fp, "Channel #%d: slave %d[%d]\n",
multi->binds[k].client_channel,
multi->binds[k].slave,
multi->binds[k].slave_channel);
}
}
struct snd_pcm_ops snd_pcm_multi_ops = {
close: snd_pcm_multi_close,
nonblock: snd_pcm_multi_nonblock,
@ -606,6 +751,7 @@ struct snd_pcm_ops snd_pcm_multi_ops = {
munmap_data: snd_pcm_multi_munmap_data,
file_descriptor: snd_pcm_multi_file_descriptor,
channels_mask: snd_pcm_multi_channels_mask,
dump: snd_pcm_multi_dump,
};
int snd_pcm_multi_create(snd_pcm_t **handlep, size_t slaves_count,

View file

@ -65,6 +65,35 @@ int snd_pcm_plugin_append(snd_pcm_plugin_t *plugin)
return 0;
}
void snd_pcm_plugin_dump(snd_pcm_plugin_t *plugin, FILE *fp)
{
fprintf(fp, "----------- %s\n", plugin->name);
fprintf(fp, "Buffer: %d frames\n", plugin->buf_frames);
if (plugin->src_format.interleave != plugin->dst_format.interleave) {
if (plugin->src_format.interleave)
fprintf(fp, "Interleaved -> Non interleaved\n");
else
fprintf(fp, "Non interleaved -> Interleaved\n");
}
if (plugin->src_format.channels != plugin->dst_format.channels) {
fprintf(fp, "Channels: %d -> %d\n",
plugin->src_format.channels,
plugin->dst_format.channels);
}
if (plugin->src_format.format != plugin->dst_format.format) {
fprintf(fp, "Format: %s -> %s\n",
snd_pcm_format_name(plugin->src_format.format),
snd_pcm_format_name(plugin->dst_format.format));
}
if (plugin->src_format.rate != plugin->dst_format.rate) {
fprintf(fp, "Rate: %d -> %d\n",
plugin->src_format.rate,
plugin->dst_format.rate);
}
if (plugin->dump)
plugin->dump(plugin, fp);
}
/* snd_pcm_plug externs */
int snd_pcm_plug_clear(snd_pcm_plug_t *plug)
@ -378,22 +407,22 @@ ssize_t snd_pcm_plug_writev(void *private, snd_timestamp_t tstamp UNUSED, const
{
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
snd_pcm_t *handle = plug->handle;
unsigned int k, step, channels;
size_t size = 0;
unsigned int k, step;
size_t result = 0;
assert(plug->frames_alloc);
channels = handle->setup.format.channels;
if (handle->setup.format.interleave)
step = 1;
else {
step = channels;
assert(count % channels == 0);
}
else
step = handle->setup.format.channels;
for (k = 0; k < count; k += step) {
snd_pcm_plugin_channel_t *channels;
ssize_t frames;
frames = snd_pcm_plug_client_channels_iovec(plug, vector, count, &channels);
if (frames < 0)
frames = snd_pcm_plug_client_channels_iovec(plug, vector, step, &channels);
if (frames < 0) {
if (result > 0)
return result;
return frames;
}
while (1) {
unsigned int c;
ssize_t ret;
@ -402,41 +431,42 @@ ssize_t snd_pcm_plug_writev(void *private, snd_timestamp_t tstamp UNUSED, const
frames1 = plug->frames_alloc;
ret = snd_pcm_plug_write_transfer(plug, channels, frames1);
if (ret < 0) {
if (size > 0)
return size;
if (result > 0)
return result;
return ret;
}
size += ret;
result += ret;
frames -= ret;
if (frames == 0)
break;
for (c = 0; c < handle->setup.format.channels; ++c)
channels[c].area.addr += ret * channels[c].area.step / 8;
}
vector += step;
}
return size;
return result;
}
ssize_t snd_pcm_plug_readv(void *private, snd_timestamp_t tstamp UNUSED, const struct iovec *vector, unsigned long count)
{
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
snd_pcm_t *handle = plug->handle;
unsigned int k, step, channels;
size_t size = 0;
unsigned int k, step;
size_t result = 0;
assert(plug->frames_alloc);
channels = handle->setup.format.channels;
if (handle->setup.format.interleave)
step = 1;
else {
step = channels;
assert(count % channels == 0);
}
else
step = handle->setup.format.channels;
for (k = 0; k < count; k += step) {
snd_pcm_plugin_channel_t *channels;
ssize_t frames;
frames = snd_pcm_plug_client_channels_iovec(plug, vector, count, &channels);
if (frames < 0)
frames = snd_pcm_plug_client_channels_iovec(plug, vector, step, &channels);
if (frames < 0) {
if (result > 0)
return result;
return frames;
}
while (1) {
unsigned int c;
ssize_t ret;
@ -445,19 +475,20 @@ ssize_t snd_pcm_plug_readv(void *private, snd_timestamp_t tstamp UNUSED, const s
frames1 = plug->frames_alloc;
ret = snd_pcm_plug_read_transfer(plug, channels, frames1);
if (ret < 0) {
if (size > 0)
return size;
if (result > 0)
return result;
return ret;
}
size += ret;
result += ret;
frames -= ret;
if (frames == 0)
break;
for (c = 0; c < handle->setup.format.channels; ++c)
channels[c].area.addr += ret * channels[c].area.step / 8;
}
vector += step;
}
return size;
return result;
}
ssize_t snd_pcm_plug_write(void *private, snd_timestamp_t tstamp UNUSED, const void *buf, size_t count)
@ -574,6 +605,25 @@ int snd_pcm_plug_file_descriptor(void *private)
return snd_pcm_file_descriptor(plug->slave);
}
static void snd_pcm_plug_dump(void *private, FILE *fp)
{
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
snd_pcm_t *handle = plug->handle;
snd_pcm_plugin_t *plugin;
fprintf(fp, "Plug PCM\n");
if (handle->valid_setup) {
fprintf(fp, "\nIts setup is:\n");
snd_pcm_dump_setup(handle, fp);
}
fprintf(fp, "\nPlugins:\n");
plugin = plug->first;
while (plugin) {
snd_pcm_plugin_dump(plugin, fp);
plugin = plugin->next;
}
fprintf(fp, "\n");
}
static int snd_pcm_plug_params(void *private, snd_pcm_params_t *params);
struct snd_pcm_ops snd_pcm_plug_ops = {
@ -605,6 +655,7 @@ struct snd_pcm_ops snd_pcm_plug_ops = {
munmap_data: snd_pcm_plug_munmap_data,
file_descriptor: snd_pcm_plug_file_descriptor,
channels_mask: snd_pcm_plug_channels_mask,
dump: snd_pcm_plug_dump,
};
static void snd_pcm_plug_slave_params(snd_pcm_plug_t *plug,

View file

@ -118,6 +118,17 @@ static ssize_t io_src_channels(snd_pcm_plugin_t *plugin,
return frames;
}
#ifndef __KERNEL__
static void io_dump(snd_pcm_plugin_t *plugin, FILE *fp)
{
snd_pcm_t *slave = plugin->plug->slave;
if (slave->valid_setup) {
fprintf(fp, "Slave: ");
snd_pcm_dump(slave, fp);
}
}
#endif
int snd_pcm_plugin_build_io(snd_pcm_plug_t *plug,
snd_pcm_format_t *format,
snd_pcm_plugin_t **r_plugin)
@ -141,6 +152,9 @@ int snd_pcm_plugin_build_io(snd_pcm_plug_t *plug,
} else {
plugin->transfer = io_capture_transfer;
}
#ifndef __KERNEL__
plugin->dump = io_dump;
#endif
*r_plugin = plugin;
return 0;

View file

@ -42,8 +42,8 @@ typedef struct mmap_private_data {
static ssize_t mmap_src_channels(snd_pcm_plugin_t *plugin,
size_t frames,
snd_pcm_plugin_channel_t **channels)
size_t frames,
snd_pcm_plugin_channel_t **channels)
{
mmap_t *data;
snd_pcm_plugin_channel_t *sv;
@ -272,7 +272,16 @@ static void mmap_free(snd_pcm_plugin_t *plugin, void *private_data UNUSED)
if (data->buffer)
snd_pcm_munmap(plugin->plug->slave);
}
static void mmap_dump(snd_pcm_plugin_t *plugin, FILE *fp)
{
snd_pcm_t *slave = plugin->plug->slave;
if (slave->valid_setup) {
fprintf(fp, "Slave: ");
snd_pcm_dump(slave, fp);
}
}
int snd_pcm_plugin_build_mmap(snd_pcm_plug_t *plug,
snd_pcm_format_t *format,
snd_pcm_plugin_t **r_plugin)
@ -300,6 +309,7 @@ int snd_pcm_plugin_build_mmap(snd_pcm_plug_t *plug,
}
plugin->action = mmap_action;
plugin->private_free = mmap_free;
plugin->dump = mmap_dump;
*r_plugin = plugin;
return 0;
}

View file

@ -61,7 +61,7 @@ typedef struct {
struct ttable_dst {
int att; /* Attenuated */
int nsrcs;
unsigned int nsrcs;
ttable_src_t* srcs;
route_channel_f func;
};
@ -104,7 +104,7 @@ static void route_to_channel_from_one(snd_pcm_plugin_t *plugin,
route_t *data = (route_t *)plugin->extra_data;
void *conv;
const snd_pcm_plugin_channel_t *src_channel = 0;
int srcidx;
unsigned int srcidx;
char *src, *dst;
int src_step, dst_step;
for (srcidx = 0; srcidx < ttable->nsrcs; ++srcidx) {
@ -373,7 +373,7 @@ int route_src_channels_mask(snd_pcm_plugin_t *plugin,
ttable_dst_t *dp = data->ttable;
bitset_zero(vmask, schannels);
for (channel = 0; channel < dchannels; channel++, dp++) {
int src;
unsigned int src;
ttable_src_t *sp;
if (!bitset_get(dst_vmask, channel))
continue;
@ -396,7 +396,7 @@ int route_dst_channels_mask(snd_pcm_plugin_t *plugin,
ttable_dst_t *dp = data->ttable;
bitset_zero(vmask, dchannels);
for (channel = 0; channel < dchannels; channel++, dp++) {
int src;
unsigned int src;
ttable_src_t *sp;
sp = dp->srcs;
for (src = 0; src < dp->nsrcs; src++, sp++) {
@ -535,6 +535,38 @@ int getput_index(int format)
return width * 4 + endian * 2 + sign;
}
#ifndef __KERNEL__
static void route_dump(snd_pcm_plugin_t *plugin, FILE *fp)
{
route_t *data;
ttable_dst_t *tdp;
unsigned int dst_channel, dst_nchannels;
data = (route_t *)plugin->extra_data;
tdp = data->ttable;
dst_nchannels = plugin->dst_format.channels;
for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) {
unsigned int k;
ttable_src_t *tsp = tdp->srcs;
fprintf(fp, "Channel %d = ", dst_channel);
for (k = 0; k < tdp->nsrcs; ++k) {
if (k > 0)
fprintf(fp, " + ");
fprintf(fp, "[%d]", tsp->channel);
if (tdp->att) {
#if ROUTE_PLUGIN_USE_FLOAT
fprintf(fp, "*%g", tsp->as_float);
#else
fprintf(fp, "*%d/%d", tsp->as_int, ROUTE_PLUGIN_RESOLUTION);
#endif
}
++tsp;
}
fprintf(fp, "\n");
++tdp;
}
}
#endif
int snd_pcm_plugin_build_route(snd_pcm_plug_t *plug,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
@ -581,6 +613,9 @@ int snd_pcm_plugin_build_route(snd_pcm_plug_t *plug,
plugin->transfer = route_transfer;
plugin->src_channels_mask = route_src_channels_mask;
plugin->dst_channels_mask = route_dst_channels_mask;
#ifndef __KERNEL__
plugin->dump = route_dump;
#endif
*r_plugin = plugin;
return 0;
}