#ifdef __KERNEL__
#include "../../include/driver.h"
#include "../../include/pcm.h"
-#define snd_pcm_plug_first(handle, stream) ((handle)->runtime->oss.plugin_first)
-#define snd_pcm_plug_last(handle, stream) ((handle)->runtime->oss.plugin_last)
+#define snd_pcm_plug_first(plug) ((plug)->runtime->oss.plugin_first)
+#define snd_pcm_plug_last(plug) ((plug)->runtime->oss.plugin_last)
+#define vmalloc snd_vmalloc
+#define vfree snd_vfree
#else
#include <malloc.h>
#include <errno.h>
#include <string.h>
#include <sys/uio.h>
#include "pcm_local.h"
+#define snd_pcm_plug_first(plug) ((plug)->first)
+#define snd_pcm_plug_last(plug) ((plug)->last)
+#define vmalloc malloc
+#define vfree free
#endif
static int snd_pcm_plugin_src_channels_mask(snd_pcm_plugin_t *plugin,
- bitset_t *dst_vmask,
- bitset_t **src_vmask)
+ bitset_t *dst_vmask,
+ bitset_t **src_vmask)
{
bitset_t *vmask = plugin->src_vmask;
bitset_copy(vmask, dst_vmask, plugin->src_format.channels);
}
static int snd_pcm_plugin_dst_channels_mask(snd_pcm_plugin_t *plugin,
- bitset_t *src_vmask,
- bitset_t **dst_vmask)
+ bitset_t *src_vmask,
+ bitset_t **dst_vmask)
{
bitset_t *vmask = plugin->dst_vmask;
bitset_copy(vmask, src_vmask, plugin->dst_format.channels);
return 0;
}
-static ssize_t snd_pcm_plugin_side_channels(snd_pcm_plugin_t *plugin,
- int client_side,
- size_t frames,
- snd_pcm_plugin_channel_t **channels)
+static int snd_pcm_plugin_alloc(snd_pcm_plugin_t *plugin, size_t frames)
{
- char *ptr;
- int width;
- unsigned int channel;
- long size;
- snd_pcm_plugin_channel_t *v;
snd_pcm_format_t *format;
- if ((plugin->stream == SND_PCM_STREAM_PLAYBACK && client_side) ||
- (plugin->stream == SND_PCM_STREAM_CAPTURE && !client_side)) {
+ ssize_t width;
+ size_t size;
+ unsigned int channel;
+ snd_pcm_plugin_channel_t *c;
+ if (plugin->stream == SND_PCM_STREAM_PLAYBACK)
format = &plugin->src_format;
- v = plugin->src_channels;
- } else {
+ else
format = &plugin->dst_format;
- v = plugin->dst_channels;
- }
-
- *channels = v;
if ((width = snd_pcm_format_physical_width(format->format)) < 0)
- return width;
+ return width;
size = frames * format->channels * width;
assert(size % 8 == 0);
size /= 8;
- ptr = (char *)snd_pcm_plug_buf_alloc(plugin->handle, plugin->stream, size);
- if (ptr == NULL)
+ if (plugin->buf_frames < frames) {
+ if (plugin->buf)
+ vfree(plugin->buf);
+ plugin->buf = vmalloc(size);
+ plugin->buf_frames = frames;
+ }
+ if (!plugin->buf)
return -ENOMEM;
- assert(size % format->channels == 0);
- size /= format->channels;
- for (channel = 0; channel < format->channels; channel++, v++) {
- v->enabled = 1;
- v->wanted = 0;
- v->aptr = ptr;
- if (format->interleave) {
- v->area.addr = ptr;
- v->area.first = channel * width;
- v->area.step = format->channels * width;
- } else {
- v->area.addr = ptr + (channel * size);
- v->area.first = 0;
- v->area.step = width;
+ c = plugin->buf_channels;
+ if (format->interleave) {
+ for (channel = 0; channel < format->channels; channel++, c++) {
+ c->enabled = 1;
+ c->wanted = 0;
+ c->area.addr = plugin->buf;
+ c->area.first = channel * width;
+ c->area.step = format->channels * width;
+ }
+ } else {
+ assert(size % format->channels == 0);
+ size /= format->channels;
+ for (channel = 0; channel < format->channels; channel++, c++) {
+ c->enabled = 1;
+ c->wanted = 0;
+ c->area.addr = plugin->buf + (channel * size);
+ c->area.first = 0;
+ c->area.step = width;
}
}
- return frames;
+ return 0;
}
-ssize_t snd_pcm_plugin_client_channels(snd_pcm_plugin_t *plugin,
- size_t frames,
- snd_pcm_plugin_channel_t **channels)
+int snd_pcm_plug_alloc(snd_pcm_plug_t *plug, size_t frames)
{
- return snd_pcm_plugin_side_channels(plugin, 1, frames, channels);
+ int err;
+#ifndef __KERNEL__
+ plug->frames_alloc = frames;
+#endif
+ assert(snd_pcm_plug_first(plug));
+ if (snd_pcm_plug_stream(plug) == SND_PCM_STREAM_PLAYBACK) {
+ snd_pcm_plugin_t *plugin = snd_pcm_plug_first(plug);
+ while (plugin->next) {
+ if (plugin->dst_frames)
+ frames = plugin->dst_frames(plugin, frames);
+ assert(frames > 0);
+ plugin = plugin->next;
+ err = snd_pcm_plugin_alloc(plugin, frames);
+ if (err < 0)
+ return err;
+ }
+ } else {
+ snd_pcm_plugin_t *plugin = snd_pcm_plug_last(plug);
+ while (plugin->prev) {
+ if (plugin->dst_frames)
+ frames = plugin->dst_frames(plugin, frames);
+ assert(frames > 0);
+ plugin = plugin->prev;
+ err = snd_pcm_plugin_alloc(plugin, frames);
+ if (err < 0)
+ return err;
+ }
+ }
+ return 0;
}
-ssize_t snd_pcm_plugin_slave_channels(snd_pcm_plugin_t *plugin,
- size_t frames,
- snd_pcm_plugin_channel_t **channels)
+
+ssize_t snd_pcm_plugin_client_channels(snd_pcm_plugin_t *plugin,
+ size_t frames,
+ snd_pcm_plugin_channel_t **channels)
{
- return snd_pcm_plugin_side_channels(plugin, 0, frames, channels);
+ assert(frames <= plugin->buf_frames);
+ *channels = plugin->buf_channels;
+ return frames;
}
-
-int snd_pcm_plugin_build(snd_pcm_plugin_handle_t *handle,
- int stream,
+int snd_pcm_plugin_build(snd_pcm_plug_t *plug,
const char *name,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
snd_pcm_plugin_t **ret)
{
snd_pcm_plugin_t *plugin;
+ size_t channels;
- assert(handle);
- assert(stream >= 0 && stream <= 1);
+ assert(plug);
assert(src_format && dst_format);
plugin = (snd_pcm_plugin_t *)calloc(1, sizeof(*plugin) + extra);
if (plugin == NULL)
return -ENOMEM;
plugin->name = name ? strdup(name) : NULL;
- plugin->handle = handle;
- plugin->stream = stream;
+ plugin->plug = plug;
+ plugin->stream = snd_pcm_plug_stream(plug);
plugin->src_format = *src_format;
plugin->src_width = snd_pcm_format_physical_width(src_format->format);
assert(plugin->src_width > 0);
plugin->dst_format = *dst_format;
plugin->dst_width = snd_pcm_format_physical_width(dst_format->format);
assert(plugin->dst_width > 0);
- plugin->src_channels = calloc(src_format->channels, sizeof(snd_pcm_plugin_channel_t));
- if (plugin->src_channels == NULL) {
- free(plugin);
- return -ENOMEM;
- }
- plugin->dst_channels = calloc(dst_format->channels, sizeof(snd_pcm_plugin_channel_t));
- if (plugin->dst_channels == NULL) {
- free(plugin->src_channels);
+ if (plugin->stream == SND_PCM_STREAM_PLAYBACK)
+ channels = src_format->channels;
+ else
+ channels = dst_format->channels;
+ plugin->buf_channels = calloc(channels, sizeof(*plugin->buf_channels));
+ if (plugin->buf_channels == NULL) {
free(plugin);
return -ENOMEM;
}
plugin->src_vmask = bitset_alloc(src_format->channels);
if (plugin->src_vmask == NULL) {
- free(plugin->src_channels);
- free(plugin->dst_channels);
+ free(plugin->buf_channels);
free(plugin);
return -ENOMEM;
}
plugin->dst_vmask = bitset_alloc(dst_format->channels);
if (plugin->dst_vmask == NULL) {
- free(plugin->src_channels);
- free(plugin->dst_channels);
+ free(plugin->buf_channels);
free(plugin->src_vmask);
free(plugin);
return -ENOMEM;
int snd_pcm_plugin_free(snd_pcm_plugin_t *plugin)
{
- if (plugin) {
- if (plugin->private_free)
- plugin->private_free(plugin, plugin->private_data);
- if (plugin->name)
- free(plugin->name);
- free(plugin->src_channels);
- free(plugin->dst_channels);
- free(plugin->src_vmask);
- free(plugin->dst_vmask);
- free(plugin);
- }
+ assert(plugin);
+ if (plugin->private_free)
+ plugin->private_free(plugin, plugin->private_data);
+ if (plugin->name)
+ free(plugin->name);
+ free(plugin->buf_channels);
+ if (plugin->buf)
+ vfree(plugin->buf);
+ free(plugin->src_vmask);
+ free(plugin->dst_vmask);
+ free(plugin);
return 0;
}
-ssize_t snd_pcm_plug_client_size(snd_pcm_plugin_handle_t *handle, int stream, size_t drv_frames)
+ssize_t snd_pcm_plug_client_size(snd_pcm_plug_t *plug, size_t drv_frames)
{
snd_pcm_plugin_t *plugin, *plugin_prev, *plugin_next;
-
- assert(handle);
+ int stream = snd_pcm_plug_stream(plug);
+
+ assert(plug);
if (drv_frames == 0)
return 0;
if (stream == SND_PCM_STREAM_PLAYBACK) {
- plugin = snd_pcm_plug_last(handle, SND_PCM_STREAM_PLAYBACK);
+ plugin = snd_pcm_plug_last(plug);
while (plugin && drv_frames > 0) {
plugin_prev = plugin->prev;
if (plugin->src_frames)
plugin = plugin_prev;
}
} else if (stream == SND_PCM_STREAM_CAPTURE) {
- plugin = snd_pcm_plug_first(handle, SND_PCM_STREAM_CAPTURE);
+ plugin = snd_pcm_plug_first(plug);
while (plugin && drv_frames > 0) {
plugin_next = plugin->next;
if (plugin->dst_frames)
return drv_frames;
}
-ssize_t snd_pcm_plug_slave_size(snd_pcm_plugin_handle_t *handle, int stream, size_t clt_frames)
+ssize_t snd_pcm_plug_slave_size(snd_pcm_plug_t *plug, size_t clt_frames)
{
snd_pcm_plugin_t *plugin, *plugin_prev, *plugin_next;
ssize_t frames;
+ int stream = snd_pcm_plug_stream(plug);
- assert(handle);
+ assert(plug);
if (clt_frames == 0)
return 0;
frames = clt_frames;
if (stream == SND_PCM_STREAM_PLAYBACK) {
- plugin = snd_pcm_plug_first(handle, SND_PCM_STREAM_PLAYBACK);
+ plugin = snd_pcm_plug_first(plug);
while (plugin && frames > 0) {
plugin_next = plugin->next;
if (plugin->dst_frames) {
plugin = plugin_next;
}
} else if (stream == SND_PCM_STREAM_CAPTURE) {
- plugin = snd_pcm_plug_last(handle, SND_PCM_STREAM_CAPTURE);
+ plugin = snd_pcm_plug_last(plug);
while (plugin) {
plugin_prev = plugin->prev;
if (plugin->src_frames) {
SND_PCM_SFMT_U8
};
-int snd_pcm_plug_slave_params(snd_pcm_stream_params_t *params,
- snd_pcm_stream_info_t *slave_info,
- snd_pcm_stream_params_t *slave_params)
+int snd_pcm_plug_slave_params(snd_pcm_params_t *params,
+ snd_pcm_info_t *slave_info,
+ snd_pcm_params_t *slave_params)
{
*slave_params = *params;
if ((slave_info->formats & (1 << params->format.format)) == 0) {
}
/* interleave */
- if (!(slave_info->flags & SND_PCM_STREAM_INFO_INTERLEAVE))
+ if (!(slave_info->flags & SND_PCM_INFO_INTERLEAVE))
slave_params->format.interleave = 0;
- if (!(slave_info->flags & SND_PCM_STREAM_INFO_NONINTERLEAVE))
+ if (!(slave_info->flags & SND_PCM_INFO_NONINTERLEAVE))
slave_params->format.interleave = 1;
return 0;
}
-int snd_pcm_plug_format(snd_pcm_plugin_handle_t *handle,
- snd_pcm_stream_params_t *params,
- snd_pcm_stream_params_t *slave_params)
+int snd_pcm_plug_format(snd_pcm_plug_t *plug,
+ snd_pcm_params_t *params,
+ snd_pcm_params_t *slave_params)
{
- snd_pcm_stream_params_t tmpparams;
- snd_pcm_stream_params_t dstparams;
- snd_pcm_stream_params_t *srcparams;
+ snd_pcm_params_t tmpparams;
+ snd_pcm_params_t dstparams;
+ snd_pcm_params_t *srcparams;
snd_pcm_plugin_t *plugin;
int err;
- switch (params->stream) {
+ switch (snd_pcm_plug_stream(plug)) {
case SND_PCM_STREAM_PLAYBACK:
dstparams = *slave_params;
srcparams = slave_params;
tmpparams.format.interleave = dstparams.format.interleave;
switch (srcparams->format.format) {
case SND_PCM_SFMT_MU_LAW:
- err = snd_pcm_plugin_build_mulaw(handle,
- params->stream,
+ err = snd_pcm_plugin_build_mulaw(plug,
&srcparams->format,
&tmpparams.format,
&plugin);
break;
#ifndef __KERNEL__
case SND_PCM_SFMT_A_LAW:
- err = snd_pcm_plugin_build_alaw(handle,
- params->stream,
+ err = snd_pcm_plugin_build_alaw(plug,
&srcparams->format,
&tmpparams.format,
&plugin);
break;
case SND_PCM_SFMT_IMA_ADPCM:
- err = snd_pcm_plugin_build_adpcm(handle,
- params->stream,
+ err = snd_pcm_plugin_build_adpcm(plug,
&srcparams->format,
&tmpparams.format,
&plugin);
if (srcparams->format.rate == dstparams.format.rate &&
snd_pcm_format_linear(dstparams.format.format))
tmpparams.format.format = dstparams.format.format;
- err = snd_pcm_plugin_build_route(handle,
- params->stream,
+ err = snd_pcm_plugin_build_route(plug,
&srcparams->format,
&tmpparams.format,
ttable,
if (srcparams->format.channels == dstparams.format.channels &&
snd_pcm_format_linear(dstparams.format.format))
tmpparams.format.format = dstparams.format.format;
- err = snd_pcm_plugin_build_rate(handle,
- params->stream,
+ err = snd_pcm_plugin_build_rate(plug,
&srcparams->format,
&tmpparams.format,
&plugin);
tmpparams.format.interleave = dstparams.format.interleave;
if (snd_pcm_format_linear(dstparams.format.format))
tmpparams.format.format = dstparams.format.format;
- err = snd_pcm_plugin_build_route(handle,
- params->stream,
+ err = snd_pcm_plugin_build_route(plug,
&srcparams->format,
&tmpparams.format,
ttable,
tmpparams.format.format = dstparams.format.format;
tmpparams.format.interleave = dstparams.format.interleave;
if (tmpparams.format.format == SND_PCM_SFMT_MU_LAW) {
- err = snd_pcm_plugin_build_mulaw(handle,
- params->stream,
+ err = snd_pcm_plugin_build_mulaw(plug,
&srcparams->format,
&tmpparams.format,
&plugin);
}
#ifndef __KERNEL__
else if (tmpparams.format.format == SND_PCM_SFMT_A_LAW) {
- err = snd_pcm_plugin_build_alaw(handle,
- params->stream,
+ err = snd_pcm_plugin_build_alaw(plug,
&srcparams->format,
&tmpparams.format,
&plugin);
}
else if (tmpparams.format.format == SND_PCM_SFMT_IMA_ADPCM) {
- err = snd_pcm_plugin_build_adpcm(handle,
- params->stream,
+ err = snd_pcm_plugin_build_adpcm(plug,
&srcparams->format,
&tmpparams.format,
&plugin);
#endif
else if (snd_pcm_format_linear(srcparams->format.format) &&
snd_pcm_format_linear(tmpparams.format.format)) {
- err = snd_pcm_plugin_build_linear(handle,
- params->stream,
+ err = snd_pcm_plugin_build_linear(plug,
&srcparams->format,
&tmpparams.format,
&plugin);
/* interleave */
if (srcparams->format.interleave != dstparams.format.interleave) {
tmpparams.format.interleave = dstparams.format.interleave;
- err = snd_pcm_plugin_build_copy(handle,
- params->stream,
+ err = snd_pcm_plugin_build_copy(plug,
&srcparams->format,
&tmpparams.format,
&plugin);
return 0;
}
-ssize_t snd_pcm_plug_client_channels_buf(snd_pcm_plugin_handle_t *handle,
- int stream,
+ssize_t snd_pcm_plug_client_channels_buf(snd_pcm_plug_t *plug,
char *buf,
size_t count,
snd_pcm_plugin_channel_t **channels)
snd_pcm_plugin_channel_t *v;
snd_pcm_format_t *format;
int width, nchannels, channel;
+ int stream = snd_pcm_plug_stream(plug);
assert(buf);
if (stream == SND_PCM_STREAM_PLAYBACK) {
- plugin = snd_pcm_plug_first(handle, stream);
+ plugin = snd_pcm_plug_first(plug);
format = &plugin->src_format;
- v = plugin->src_channels;
}
else {
- plugin = snd_pcm_plug_last(handle, stream);
+ plugin = snd_pcm_plug_last(plug);
format = &plugin->dst_format;
- v = plugin->dst_channels;
}
+ v = plugin->buf_channels;
*channels = v;
if ((width = snd_pcm_format_physical_width(format->format)) < 0)
return width;
for (channel = 0; channel < nchannels; channel++, v++) {
v->enabled = 1;
v->wanted = (stream == SND_PCM_STREAM_CAPTURE);
- v->aptr = NULL;
v->area.addr = buf;
v->area.first = channel * width;
v->area.step = nchannels * width;
return count;
}
-ssize_t snd_pcm_plug_client_channels_iovec(snd_pcm_plugin_handle_t *handle,
- int stream,
+ssize_t snd_pcm_plug_client_channels_iovec(snd_pcm_plug_t *plug,
const struct iovec *vector,
unsigned long count,
snd_pcm_plugin_channel_t **channels)
snd_pcm_format_t *format;
int width;
unsigned int nchannels, channel;
+ int stream = snd_pcm_plug_stream(plug);
if (stream == SND_PCM_STREAM_PLAYBACK) {
- plugin = snd_pcm_plug_first(handle, stream);
+ plugin = snd_pcm_plug_first(plug);
format = &plugin->src_format;
- v = plugin->src_channels;
}
else {
- plugin = snd_pcm_plug_last(handle, stream);
+ plugin = snd_pcm_plug_last(plug);
format = &plugin->dst_format;
- v = plugin->dst_channels;
}
+ v = plugin->buf_channels;
*channels = v;
if ((width = snd_pcm_format_physical_width(format->format)) < 0)
return width;
for (channel = 0; channel < nchannels; channel++, v++) {
v->enabled = 1;
v->wanted = (stream == SND_PCM_STREAM_CAPTURE);
- v->aptr = NULL;
v->area.addr = vector->iov_base;
v->area.first = channel * width;
v->area.step = nchannels * width;
assert(vector->iov_len == len);
v->enabled = (vector->iov_base != NULL);
v->wanted = (v->enabled && (stream == SND_PCM_STREAM_CAPTURE));
- v->aptr = NULL;
v->area.addr = vector->iov_base;
v->area.first = 0;
v->area.step = width;
}
}
-int snd_pcm_plug_playback_channels_mask(snd_pcm_plugin_handle_t *handle,
+int snd_pcm_plug_playback_channels_mask(snd_pcm_plug_t *plug,
bitset_t *client_vmask)
{
-#ifndef __KERNEL__
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &handle->private;
-#endif
- snd_pcm_plugin_t *plugin = snd_pcm_plug_last(handle, SND_PCM_STREAM_PLAYBACK);
+ snd_pcm_plugin_t *plugin = snd_pcm_plug_last(plug);
if (plugin == NULL) {
#ifndef __KERNEL__
- return snd_pcm_channels_mask(plug->slave, SND_PCM_STREAM_PLAYBACK, client_vmask);
+ return snd_pcm_channels_mask(plug->slave, client_vmask);
#else
return 0;
#endif
int err;
bitset_one(dstmask, schannels);
#ifndef __KERNEL__
- err = snd_pcm_channels_mask(plug->slave, SND_PCM_STREAM_PLAYBACK, dstmask);
+ err = snd_pcm_channels_mask(plug->slave, dstmask);
if (err < 0)
return err;
#endif
}
}
-int snd_pcm_plug_capture_channels_mask(snd_pcm_plugin_handle_t *handle,
+int snd_pcm_plug_capture_channels_mask(snd_pcm_plug_t *plug,
bitset_t *client_vmask)
{
-#ifndef __KERNEL__
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &handle->private;
-#endif
- snd_pcm_plugin_t *plugin = snd_pcm_plug_first(handle, SND_PCM_STREAM_CAPTURE);
+ snd_pcm_plugin_t *plugin = snd_pcm_plug_first(plug);
if (plugin == NULL) {
#ifndef __KERNEL__
- return snd_pcm_channels_mask(plug->slave, SND_PCM_STREAM_CAPTURE, client_vmask);
+ return snd_pcm_channels_mask(plug->slave, client_vmask);
#else
return 0;
#endif
int err;
bitset_one(srcmask, schannels);
#ifndef __KERNEL__
- err = snd_pcm_channels_mask(plug->slave, SND_PCM_STREAM_CAPTURE, srcmask);
+ err = snd_pcm_channels_mask(plug->slave, srcmask);
if (err < 0)
return err;
#endif
}
}
-static int snd_pcm_plug_playback_disable_useless_channels(snd_pcm_plugin_handle_t *handle,
+static int snd_pcm_plug_playback_disable_useless_channels(snd_pcm_plug_t *plug,
snd_pcm_plugin_channel_t *src_channels)
{
- snd_pcm_plugin_t *plugin = snd_pcm_plug_first(handle, SND_PCM_STREAM_PLAYBACK);
+ snd_pcm_plugin_t *plugin = snd_pcm_plug_first(plug);
unsigned int nchannels = plugin->src_format.channels;
bitset_t bs[bitset_size(nchannels)];
bitset_t *srcmask = bs;
else
bitset_reset(srcmask, channel);
}
- err = snd_pcm_plug_playback_channels_mask(handle, srcmask);
+ err = snd_pcm_plug_playback_channels_mask(plug, srcmask);
if (err < 0)
return err;
for (channel = 0; channel < nchannels; channel++) {
return 0;
}
-static int snd_pcm_plug_capture_disable_useless_channels(snd_pcm_plugin_handle_t *handle,
+static int snd_pcm_plug_capture_disable_useless_channels(snd_pcm_plug_t *plug,
snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *client_channels)
{
-#ifndef __KERNEL__
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &handle->private;
-#endif
- snd_pcm_plugin_t *plugin = snd_pcm_plug_last(handle, SND_PCM_STREAM_CAPTURE);
+ snd_pcm_plugin_t *plugin = snd_pcm_plug_last(plug);
unsigned int nchannels = plugin->dst_format.channels;
bitset_t bs[bitset_size(nchannels)];
bitset_t *dstmask = bs;
plugin = plugin->prev;
}
#ifndef __KERNEL__
- err = snd_pcm_channels_mask(plug->slave, SND_PCM_STREAM_CAPTURE, dstmask);
+ err = snd_pcm_channels_mask(plug->slave, dstmask);
if (err < 0)
return err;
#endif
- plugin = snd_pcm_plug_first(handle, SND_PCM_STREAM_CAPTURE);
+ plugin = snd_pcm_plug_first(plug);
nchannels = plugin->src_format.channels;
for (channel = 0; channel < nchannels; channel++) {
if (!bitset_get(dstmask, channel))
return 0;
}
-ssize_t snd_pcm_plug_write_transfer(snd_pcm_plugin_handle_t *handle, snd_pcm_plugin_channel_t *src_channels, size_t size)
+ssize_t snd_pcm_plug_write_transfer(snd_pcm_plug_t *plug, snd_pcm_plugin_channel_t *src_channels, size_t size)
{
snd_pcm_plugin_t *plugin, *next;
snd_pcm_plugin_channel_t *dst_channels;
int err;
ssize_t frames = size;
- if ((err = snd_pcm_plug_playback_disable_useless_channels(handle, src_channels)) < 0)
+ if ((err = snd_pcm_plug_playback_disable_useless_channels(plug, src_channels)) < 0)
return err;
- plugin = snd_pcm_plug_first(handle, SND_PCM_STREAM_PLAYBACK);
+ plugin = snd_pcm_plug_first(plug);
while (plugin && frames > 0) {
if ((next = plugin->next) != NULL) {
ssize_t frames1 = frames;
if (plugin->dst_frames)
frames1 = plugin->dst_frames(plugin, frames);
if ((err = next->client_channels(next, frames1, &dst_channels)) < 0) {
- snd_pcm_plug_buf_unlock(handle, SND_PCM_STREAM_PLAYBACK, src_channels->aptr);
return err;
}
if (err != frames1) {
if (plugin->src_frames)
frames = plugin->src_frames(plugin, frames1);
}
- } else {
- if ((err = snd_pcm_plugin_slave_channels(plugin, frames, &dst_channels)) < 0)
- return err;
- }
+ } else
+ dst_channels = 0;
pdprintf("write plugin: %s, %i\n", plugin->name, frames);
- if ((frames = plugin->transfer(plugin, src_channels, dst_channels, frames)) < 0) {
- snd_pcm_plug_buf_unlock(handle, SND_PCM_STREAM_PLAYBACK, src_channels->aptr);
- snd_pcm_plug_buf_unlock(handle, SND_PCM_STREAM_PLAYBACK, dst_channels->aptr);
+ if ((frames = plugin->transfer(plugin, src_channels, dst_channels, frames)) < 0)
return frames;
- }
- snd_pcm_plug_buf_unlock(handle, SND_PCM_STREAM_PLAYBACK, src_channels->aptr);
src_channels = dst_channels;
plugin = next;
}
- snd_pcm_plug_buf_unlock(handle, SND_PCM_STREAM_PLAYBACK, src_channels->aptr);
- return snd_pcm_plug_client_size(handle, SND_PCM_STREAM_PLAYBACK, frames);
+ return snd_pcm_plug_client_size(plug, frames);
}
-ssize_t snd_pcm_plug_read_transfer(snd_pcm_plugin_handle_t *handle, snd_pcm_plugin_channel_t *dst_channels_final, size_t size)
+ssize_t snd_pcm_plug_read_transfer(snd_pcm_plug_t *plug, snd_pcm_plugin_channel_t *dst_channels_final, size_t size)
{
snd_pcm_plugin_t *plugin, *next;
snd_pcm_plugin_channel_t *src_channels, *dst_channels;
ssize_t frames = size;
int err;
- plugin = snd_pcm_plug_last(handle, SND_PCM_STREAM_CAPTURE);
- frames = snd_pcm_plug_slave_size(handle, SND_PCM_STREAM_CAPTURE, frames);
+ frames = snd_pcm_plug_slave_size(plug, frames);
if (frames < 0)
return frames;
- plugin = snd_pcm_plug_first(handle, SND_PCM_STREAM_CAPTURE);
- if ((err = snd_pcm_plugin_slave_channels(plugin, frames, &src_channels)) < 0)
- return err;
- if ((err = snd_pcm_plug_capture_disable_useless_channels(handle, src_channels, dst_channels_final) < 0))
- return err;
-
+ src_channels = 0;
+ plugin = snd_pcm_plug_first(plug);
while (plugin && frames > 0) {
if ((next = plugin->next) != NULL) {
if ((err = plugin->client_channels(plugin, frames, &dst_channels)) < 0) {
- snd_pcm_plug_buf_unlock(handle, SND_PCM_STREAM_CAPTURE, src_channels->aptr);
return err;
}
frames = err;
+ if (!plugin->prev) {
+ if ((err = snd_pcm_plug_capture_disable_useless_channels(plug, dst_channels, dst_channels_final) < 0))
+ return err;
+ }
} else {
dst_channels = dst_channels_final;
}
pdprintf("read plugin: %s, %i\n", plugin->name, frames);
- if ((frames = plugin->transfer(plugin, src_channels, dst_channels, frames)) < 0) {
- snd_pcm_plug_buf_unlock(handle, SND_PCM_STREAM_CAPTURE, src_channels->aptr);
- snd_pcm_plug_buf_unlock(handle, SND_PCM_STREAM_CAPTURE, dst_channels->aptr);
+ if ((frames = plugin->transfer(plugin, src_channels, dst_channels, frames)) < 0)
return frames;
- }
-#if 0
- {
- unsigned int channel;
- for (channel = 0; channel < plugin->src_format.channels; ++channel) {
- fprintf(stderr, "%d%d ", src_channels[channel].enabled, src_channels[channel].wanted);
- }
- fprintf(stderr, " -> ");
- for (channel = 0; channel < plugin->dst_format.channels; ++channel) {
- fprintf(stderr, "%d%d ", dst_channels[channel].enabled, dst_channels[channel].wanted);
- }
- fprintf(stderr, "\n");
- }
-#endif
- snd_pcm_plug_buf_unlock(handle, SND_PCM_STREAM_CAPTURE, src_channels->aptr);
plugin = next;
src_channels = dst_channels;
}
- snd_pcm_plug_buf_unlock(handle, SND_PCM_STREAM_CAPTURE, src_channels->aptr);
return frames;
}
#include <sys/uio.h>
#include "pcm_local.h"
-/* snd_pcm_plug helpers */
-
-void *snd_pcm_plug_buf_alloc(snd_pcm_t *pcm, int stream, size_t size)
-{
- int idx;
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- snd_pcm_plug_stream_t *plugstr = &plug->stream[stream];
-
- for (idx = 0; idx < 2; idx++) {
- if (plugstr->alloc_lock[idx])
- continue;
- if (plugstr->alloc_size[idx] >= size) {
- plugstr->alloc_lock[idx] = 1;
- return plugstr->alloc_ptr[idx];
- }
- }
- for (idx = 0; idx < 2; idx++) {
- if (plugstr->alloc_lock[idx])
- continue;
- if (plugstr->alloc_ptr[idx] != NULL)
- free(plugstr->alloc_ptr[idx]);
- plugstr->alloc_ptr[idx] = malloc(size);
- if (plugstr->alloc_ptr[idx] == NULL)
- return NULL;
- plugstr->alloc_size[idx] = size;
- plugstr->alloc_lock[idx] = 1;
- return plugstr->alloc_ptr[idx];
- }
- return NULL;
-}
-
-void snd_pcm_plug_buf_unlock(snd_pcm_t *pcm, int stream, void *ptr)
-{
- int idx;
-
- snd_pcm_plug_t *plug;
- snd_pcm_plug_stream_t *plugstr;
-
- if (!ptr)
- return;
- plug = (snd_pcm_plug_t*) &pcm->private;
- plugstr = &plug->stream[stream];
-
- for (idx = 0; idx < 2; idx++) {
- if (plugstr->alloc_ptr[idx] == ptr) {
- plugstr->alloc_lock[idx] = 0;
- return;
- }
- }
-}
-
/* snd_pcm_plugin externs */
int snd_pcm_plugin_insert(snd_pcm_plugin_t *plugin)
{
snd_pcm_plug_t *plug;
- snd_pcm_plug_stream_t *plugstr;
- snd_pcm_t *pcm;
assert(plugin);
- pcm = plugin->handle;
- plug = (snd_pcm_plug_t*) &pcm->private;
- plugstr = &plug->stream[plugin->stream];
- plugin->next = plugstr->first;
+ plug = plugin->plug;
+ plugin->next = plug->first;
plugin->prev = NULL;
- if (plugstr->first) {
- plugstr->first->prev = plugin;
- plugstr->first = plugin;
+ if (plug->first) {
+ plug->first->prev = plugin;
+ plug->first = plugin;
} else {
- plugstr->last =
- plugstr->first = plugin;
+ plug->last =
+ plug->first = plugin;
}
return 0;
}
int snd_pcm_plugin_append(snd_pcm_plugin_t *plugin)
{
snd_pcm_plug_t *plug;
- snd_pcm_plug_stream_t *plugstr;
- snd_pcm_t *pcm;
assert(plugin);
- pcm = plugin->handle;
- plug = (snd_pcm_plug_t*) &pcm->private;
- plugstr = &plug->stream[plugin->stream];
-
+ plug = plugin->plug;
plugin->next = NULL;
- plugin->prev = plugstr->last;
- if (plugstr->last) {
- plugstr->last->next = plugin;
- plugstr->last = plugin;
+ plugin->prev = plug->last;
+ if (plug->last) {
+ plug->last->next = plugin;
+ plug->last = plugin;
} else {
- plugstr->last =
- plugstr->first = plugin;
+ plug->last =
+ plug->first = plugin;
}
return 0;
}
-#if 0
-int snd_pcm_plugin_remove_to(snd_pcm_plugin_t *plugin)
-{
- snd_pcm_plugin_t *plugin1, *plugin1_prev;
- snd_pcm_plug_t *plug;
- snd_pcm_t *pcm;
- snd_pcm_plug_stream_t *plugstr;
- assert(plugin);
- pcm = plugin->handle;
-
- plug = (snd_pcm_plug_t*) &pcm->private;
- plugstr = &plug->stream[plugin->stream];
-
- plugin1 = plugin;
- while (plugin1->prev)
- plugin1 = plugin1->prev;
- if (plugstr->first != plugin1)
- return -EINVAL;
- plugstr->first = plugin;
- plugin1 = plugin->prev;
- plugin->prev = NULL;
- while (plugin1) {
- plugin1_prev = plugin1->prev;
- snd_pcm_plugin_free(plugin1);
- plugin1 = plugin1_prev;
- }
- return 0;
-}
-
-int snd_pcm_plug_remove_first(snd_pcm_t *pcm, int stream)
-{
- snd_pcm_plugin_t *plugin;
- snd_pcm_plug_t *plug;
- snd_pcm_plug_stream_t *plugstr;
- assert(pcm);
- assert(stream >= 0 && stream <= 1);
- assert(pcm->stream[stream].open);
-
- plug = (snd_pcm_plug_t*) &pcm->private;
- plugstr = &plug->stream[stream];
-
- plugin = plugstr->first;
- if (plugin->next) {
- plugin = plugin->next;
- } else {
- return snd_pcm_plug_clear(pcm, stream);
- }
- return snd_pcm_plugin_remove_to(plugin);
-}
-#endif
-
/* snd_pcm_plug externs */
-int snd_pcm_plug_clear(snd_pcm_t *pcm, int stream)
+int snd_pcm_plug_clear(snd_pcm_plug_t *plug)
{
snd_pcm_plugin_t *plugin, *plugin_next;
- snd_pcm_plug_t *plug;
- snd_pcm_plug_stream_t *plugstr;
- int idx;
- assert(pcm);
- assert(stream >= 0 && stream <= 1);
- assert(pcm->stream[stream].open);
-
- plug = (snd_pcm_plug_t*) &pcm->private;
- plugstr = &plug->stream[stream];
- plugin = plugstr->first;
- plugstr->first = NULL;
- plugstr->last = NULL;
+ assert(plug);
+
+ plugin = plug->first;
+ plug->first = NULL;
+ plug->last = NULL;
while (plugin) {
plugin_next = plugin->next;
snd_pcm_plugin_free(plugin);
plugin = plugin_next;
}
- for (idx = 0; idx < 2; idx++) {
- if (plugstr->alloc_ptr[idx]) {
- free(plugstr->alloc_ptr[idx]);
- plugstr->alloc_ptr[idx] = 0;
- }
- plugstr->alloc_size[idx] = 0;
- plugstr->alloc_lock[idx] = 0;
- }
return 0;
}
-snd_pcm_plugin_t *snd_pcm_plug_first(snd_pcm_t *pcm, int stream)
+snd_pcm_plugin_t *snd_pcm_plug_first(snd_pcm_plug_t *plug)
{
- snd_pcm_plug_t *plug;
- snd_pcm_plug_stream_t *plugstr;
- if (!pcm)
- return NULL;
- if (stream < 0 || stream > 1)
- return NULL;
- if (!pcm->stream[stream].open)
- return NULL;
-
- plug = (snd_pcm_plug_t*) &pcm->private;
- plugstr = &plug->stream[stream];
-
- return plugstr->first;
+ assert(plug);
+ return plug->first;
}
-snd_pcm_plugin_t *snd_pcm_plug_last(snd_pcm_t *pcm, int stream)
+snd_pcm_plugin_t *snd_pcm_plug_last(snd_pcm_plug_t *plug)
{
- snd_pcm_plug_t *plug;
- snd_pcm_plug_stream_t *plugstr;
- if (!pcm)
- return NULL;
- if (stream < 0 || stream > 1)
- return NULL;
- if (!pcm->stream[stream].open)
- return NULL;
-
- plug = (snd_pcm_plug_t*) &pcm->private;
- plugstr = &plug->stream[stream];
-
- return plugstr->last;
-}
-
-int snd_pcm_plug_direct(snd_pcm_t *pcm, int stream)
-{
- return snd_pcm_plug_first(pcm, stream) == NULL;
+ assert(plug);
+ return plug->last;
}
/*
*
*/
-static int snd_pcm_plug_stream_close(snd_pcm_t *pcm, int stream)
+static int snd_pcm_plug_close(void *private)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- snd_pcm_plug_clear(pcm, stream);
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_plug_clear(plug);
+ free(plug->handle->ops);
if (plug->close_slave)
- return snd_pcm_stream_close(plug->slave, stream);
+ return snd_pcm_close(plug->slave);
+ free(private);
return 0;
}
-static int snd_pcm_plug_stream_nonblock(snd_pcm_t *pcm, int stream, int nonblock)
-{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- return snd_pcm_stream_nonblock(plug->slave, stream, nonblock);
-}
-
-static int snd_pcm_plug_info(snd_pcm_t *pcm, int stream UNUSED, snd_pcm_info_t * info)
+static int snd_pcm_plug_nonblock(void *private, int nonblock)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- return snd_pcm_info(plug->slave, info);
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ return snd_pcm_nonblock(plug->slave, nonblock);
}
-static int snd_pcm_plug_stream_info(snd_pcm_t *pcm, snd_pcm_stream_info_t *info)
+static int snd_pcm_plug_info(void *private, snd_pcm_info_t *info)
{
int err;
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- snd_pcm_stream_t *str;
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
- if ((err = snd_pcm_stream_info(plug->slave, info)) < 0)
+ if ((err = snd_pcm_info(plug->slave, info)) < 0)
return err;
info->formats = snd_pcm_plug_formats(info->formats);
info->min_rate = 4000;
info->min_channels = 1;
info->max_channels = 32;
info->rates = SND_PCM_RATE_CONTINUOUS | SND_PCM_RATE_8000_192000;
- info->flags |= SND_PCM_STREAM_INFO_INTERLEAVE | SND_PCM_STREAM_INFO_NONINTERLEAVE;
-
- str = &pcm->stream[info->stream];
- if (pcm->stream[info->stream].valid_setup) {
- info->buffer_size = snd_pcm_plug_client_size(pcm, info->stream, info->buffer_size);
- info->min_fragment_size = snd_pcm_plug_client_size(pcm, info->stream, info->min_fragment_size);
- info->max_fragment_size = snd_pcm_plug_client_size(pcm, info->stream, info->max_fragment_size);
- info->fragment_align = snd_pcm_plug_client_size(pcm, info->stream, info->fragment_align);
- info->fifo_size = snd_pcm_plug_client_size(pcm, info->stream, info->fifo_size);
- info->transfer_block_size = snd_pcm_plug_client_size(pcm, info->stream, info->transfer_block_size);
- if (str->setup.mode == SND_PCM_MODE_FRAGMENT)
- info->mmap_size = str->setup.buffer_size;
- else
- info->mmap_size = snd_pcm_plug_client_size(pcm, info->stream, info->mmap_size);
+ info->flags |= SND_PCM_INFO_INTERLEAVE | SND_PCM_INFO_NONINTERLEAVE;
+
+ if (plug->slave->valid_setup) {
+ info->buffer_size = snd_pcm_plug_client_size(plug, info->buffer_size);
+ info->min_fragment_size = snd_pcm_plug_client_size(plug, info->min_fragment_size);
+ info->max_fragment_size = snd_pcm_plug_client_size(plug, info->max_fragment_size);
+ info->fragment_align = snd_pcm_plug_client_size(plug, info->fragment_align);
+ info->fifo_size = snd_pcm_plug_client_size(plug, info->fifo_size);
+ info->transfer_block_size = snd_pcm_plug_client_size(plug, info->transfer_block_size);
}
- if (!snd_pcm_plug_direct(pcm, info->stream))
- info->flags &= ~(SND_PCM_STREAM_INFO_MMAP | SND_PCM_STREAM_INFO_MMAP_VALID);
+ info->mmap_size = 0;
+ info->flags &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
return 0;
}
-static int snd_pcm_plug_action(snd_pcm_t *pcm, int stream, int action,
+static int snd_pcm_plug_action(snd_pcm_plug_t *plug, int action,
unsigned long data)
{
- snd_pcm_plugin_t *plugin;
int err;
- snd_pcm_plug_t *plug;
- snd_pcm_plug_stream_t *plugstr;
- plug = (snd_pcm_plug_t*) &pcm->private;
- plugstr = &plug->stream[stream];
-
- plugin = plugstr->first;
+ snd_pcm_plugin_t *plugin = plug->first;
while (plugin) {
if (plugin->action) {
if ((err = plugin->action(plugin, action, data))<0)
return 0;
}
-static int snd_pcm_plug_stream_params(snd_pcm_t *pcm, snd_pcm_stream_params_t *params)
+static int snd_pcm_plug_setup(void *private, snd_pcm_setup_t *setup)
{
- snd_pcm_stream_params_t slave_params, params1;
- snd_pcm_stream_info_t slave_info;
- snd_pcm_plugin_t *plugin;
- snd_pcm_plug_t *plug;
int err;
- int stream = params->stream;
-
- plug = (snd_pcm_plug_t*) &pcm->private;
-
- /*
- * try to decide, if a conversion is required
- */
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
- memset(&slave_info, 0, sizeof(slave_info));
- slave_info.stream = stream;
- if ((err = snd_pcm_stream_info(plug->slave, &slave_info)) < 0) {
- snd_pcm_plug_clear(pcm, stream);
- return err;
- }
-
- if ((err = snd_pcm_plug_slave_params(params, &slave_info, &slave_params)) < 0)
- return err;
-
-
- snd_pcm_plug_clear(pcm, stream);
-
- /* add necessary plugins */
- params1 = *params;
- if ((err = snd_pcm_plug_format(pcm, ¶ms1, &slave_params)) < 0)
- return err;
-
- if (snd_pcm_plug_direct(pcm, stream))
- return snd_pcm_stream_params(plug->slave, params);
-
- /* compute right sizes */
- slave_params.frag_size = snd_pcm_plug_slave_size(pcm, stream, params1.frag_size);
- slave_params.buffer_size = snd_pcm_plug_slave_size(pcm, stream, params1.buffer_size);
- slave_params.frames_fill_max = snd_pcm_plug_slave_size(pcm, stream, params1.frames_fill_max);
- slave_params.frames_min = snd_pcm_plug_slave_size(pcm, stream, params1.frames_min);
- slave_params.frames_xrun_max = snd_pcm_plug_slave_size(pcm, stream, params1.frames_xrun_max);
- slave_params.frames_align = snd_pcm_plug_slave_size(pcm, stream, params1.frames_align);
- if (slave_params.frame_boundary == 0 || slave_params.frame_boundary > INT_MAX)
- slave_params.frame_boundary = INT_MAX;
- slave_params.frame_boundary /= params->buffer_size;
- if (slave_params.frame_boundary > INT_MAX / slave_params.buffer_size)
- slave_params.frame_boundary = INT_MAX;
- else
- slave_params.frame_boundary *= slave_params.buffer_size;
-
- /*
- * I/O plugins
- */
-
- if (slave_info.flags & SND_PCM_STREAM_INFO_MMAP) {
- pdprintf("params mmap plugin\n");
- err = snd_pcm_plugin_build_mmap(pcm, stream, plug->slave, &slave_params.format, &plugin);
- } else {
- pdprintf("params I/O plugin\n");
- err = snd_pcm_plugin_build_io(pcm, stream, plug->slave, &slave_params.format, &plugin);
- }
- if (err < 0)
- return err;
- if (stream == SND_PCM_STREAM_PLAYBACK) {
- err = snd_pcm_plugin_append(plugin);
- } else {
- err = snd_pcm_plugin_insert(plugin);
- }
- if (err < 0) {
- snd_pcm_plugin_free(plugin);
- return err;
- }
-
- pdprintf("params requested params: format = %i, rate = %i, channels = %i\n", slave_params.format.format, slave_params.format.rate, slave_params.format.channels);
- err = snd_pcm_stream_params(plug->slave, &slave_params);
+ err = snd_pcm_setup(plug->slave, setup);
if (err < 0)
return err;
-
- err = snd_pcm_plug_action(pcm, stream, INIT, 0);
- if (err < 0)
- return err;
- return 0;
-}
-
-static int snd_pcm_plug_stream_setup(snd_pcm_t *pcm, snd_pcm_stream_setup_t *setup)
-{
- int err;
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- snd_pcm_plug_stream_t *plugstr;
-
- err = snd_pcm_stream_setup(plug->slave, setup);
- if (err < 0)
- return err;
- if (snd_pcm_plug_direct(pcm, setup->stream))
+ if (!plug->first)
return 0;
setup->frame_boundary /= setup->frag_size;
- setup->frag_size = snd_pcm_plug_client_size(pcm, setup->stream, setup->frag_size);
+ setup->frag_size = snd_pcm_plug_client_size(plug, setup->frag_size);
setup->frame_boundary *= setup->frag_size;
setup->buffer_size = setup->frags * setup->frag_size;
- setup->frames_min = snd_pcm_plug_client_size(pcm, setup->stream, setup->frames_min);
- setup->frames_align = snd_pcm_plug_client_size(pcm, setup->stream, setup->frames_align);
- setup->frames_xrun_max = snd_pcm_plug_client_size(pcm, setup->stream, setup->frames_xrun_max);
- setup->frames_fill_max = snd_pcm_plug_client_size(pcm, setup->stream, setup->frames_fill_max);
-
- plugstr = &plug->stream[setup->stream];
- if (setup->stream == SND_PCM_STREAM_PLAYBACK)
- setup->format = plugstr->first->src_format;
+ setup->frames_min = snd_pcm_plug_client_size(plug, setup->frames_min);
+ setup->frames_align = snd_pcm_plug_client_size(plug, setup->frames_align);
+ setup->frames_xrun_max = snd_pcm_plug_client_size(plug, setup->frames_xrun_max);
+ setup->frames_fill_max = snd_pcm_plug_client_size(plug, setup->frames_fill_max);
+
+ if (plug->handle->stream == SND_PCM_STREAM_PLAYBACK)
+ setup->format = plug->first->src_format;
else
- setup->format = plugstr->last->dst_format;
+ setup->format = plug->last->dst_format;
+ err = snd_pcm_plug_alloc(plug, setup->frag_size);
+ if (err < 0)
+ return err;
return 0;
}
-static int snd_pcm_plug_stream_status(snd_pcm_t *pcm, snd_pcm_stream_status_t *status)
+static int snd_pcm_plug_status(void *private, snd_pcm_status_t *status)
{
int err;
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
- err = snd_pcm_stream_status(plug->slave, status);
+ err = snd_pcm_status(plug->slave, status);
if (err < 0)
return err;
- if (snd_pcm_plug_direct(pcm, status->stream))
- return 0;
- status->frame_io = snd_pcm_plug_client_size(pcm, status->stream, status->frame_io);
- status->frame_data = snd_pcm_plug_client_size(pcm, status->stream, status->frame_data);
- status->frames_avail = snd_pcm_plug_client_size(pcm, status->stream, status->frames_avail);
- status->frames_avail_max = snd_pcm_plug_client_size(pcm, status->stream, status->frames_avail_max);
+ status->frame_io = snd_pcm_plug_client_size(plug, status->frame_io);
+ status->frame_data = snd_pcm_plug_client_size(plug, status->frame_data);
+ status->frames_avail = snd_pcm_plug_client_size(plug, status->frames_avail);
+ status->frames_avail_max = snd_pcm_plug_client_size(plug, status->frames_avail_max);
return 0;
}
-static int snd_pcm_plug_stream_state(snd_pcm_t *pcm, int stream)
+static int snd_pcm_plug_state(void *private)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- return snd_pcm_stream_state(plug->slave, stream);
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ return snd_pcm_state(plug->slave);
}
-static int snd_pcm_plug_stream_frame_io(snd_pcm_t *pcm, int stream, int update)
+static int snd_pcm_plug_frame_io(void *private, int update)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- return snd_pcm_stream_frame_io(plug->slave, stream, update);
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ ssize_t frame_io = snd_pcm_frame_io(plug->slave, update);
+ if (frame_io < 0)
+ return frame_io;
+ return snd_pcm_plug_client_size(plug, frame_io);
}
-static int snd_pcm_plug_stream_prepare(snd_pcm_t *pcm, int stream)
+static int snd_pcm_plug_prepare(void *private)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
int err;
- err = snd_pcm_stream_prepare(plug->slave, stream);
+ err = snd_pcm_prepare(plug->slave);
if (err < 0)
return err;
- if (snd_pcm_plug_direct(pcm, stream))
- return 0;
- if ((err = snd_pcm_plug_action(pcm, stream, PREPARE, 0))<0)
+ if ((err = snd_pcm_plug_action(plug, PREPARE, 0))<0)
return err;
return 0;
}
-static int snd_pcm_plug_stream_go(snd_pcm_t *pcm, int stream)
+static int snd_pcm_plug_go(void *private)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- return snd_pcm_stream_go(plug->slave, stream);
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ return snd_pcm_go(plug->slave);
}
-static int snd_pcm_plug_sync_go(snd_pcm_t *pcm, int stream UNUSED, snd_pcm_sync_t *sync)
+static int snd_pcm_plug_sync_go(void *private, snd_pcm_sync_t *sync)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
return snd_pcm_sync_go(plug->slave, sync);
}
-static int snd_pcm_plug_stream_drain(snd_pcm_t *pcm, int stream)
+static int snd_pcm_plug_drain(void *private)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
int err;
- if ((err = snd_pcm_stream_drain(plug->slave, stream)) < 0)
+ if ((err = snd_pcm_drain(plug->slave)) < 0)
return err;
- if (snd_pcm_plug_direct(pcm, stream))
- return 0;
- if ((err = snd_pcm_plug_action(pcm, stream, DRAIN, 0))<0)
+ if ((err = snd_pcm_plug_action(plug, DRAIN, 0))<0)
return err;
return 0;
}
-static int snd_pcm_plug_stream_flush(snd_pcm_t *pcm, int stream)
+static int snd_pcm_plug_flush(void *private)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
int err;
- if ((err = snd_pcm_stream_flush(plug->slave, stream)) < 0)
+ if ((err = snd_pcm_flush(plug->slave)) < 0)
return err;
- if (snd_pcm_plug_direct(pcm, stream))
- return 0;
- if ((err = snd_pcm_plug_action(pcm, stream, FLUSH, 0))<0)
+ if ((err = snd_pcm_plug_action(plug, FLUSH, 0))<0)
return err;
return 0;
}
-static int snd_pcm_plug_stream_pause(snd_pcm_t *pcm, int stream, int enable)
+static int snd_pcm_plug_pause(void *private, int enable)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
int err;
- if ((err = snd_pcm_stream_pause(plug->slave, stream, enable)) < 0)
+ if ((err = snd_pcm_pause(plug->slave, enable)) < 0)
return err;
- if ((err = snd_pcm_plug_action(pcm, stream, PAUSE, 0))<0)
+ if ((err = snd_pcm_plug_action(plug, PAUSE, 0))<0)
return err;
return 0;
}
-static int snd_pcm_plug_channel_setup(snd_pcm_t *pcm, int stream, snd_pcm_channel_setup_t *setup)
+static int snd_pcm_plug_channel_setup(void *private UNUSED, snd_pcm_channel_setup_t *setup UNUSED)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
-
- if (snd_pcm_plug_direct(pcm, stream))
- return snd_pcm_channel_setup(plug->slave, stream, setup);
/* FIXME: non mmap setups */
return -ENXIO;
}
-static ssize_t snd_pcm_plug_stream_frame_data(snd_pcm_t *pcm, int stream, off_t offset)
+static ssize_t snd_pcm_plug_frame_data(void *private, off_t offset)
{
ssize_t ret;
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- if (snd_pcm_plug_direct(pcm, stream))
- return snd_pcm_stream_frame_data(plug->slave, stream, offset);
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
if (offset < 0) {
- offset = snd_pcm_plug_slave_size(pcm, stream, -offset);
+ offset = snd_pcm_plug_slave_size(plug, -offset);
if (offset < 0)
return offset;
offset = -offset;
} else {
- offset = snd_pcm_plug_slave_size(pcm, stream, offset);
+ offset = snd_pcm_plug_slave_size(plug, offset);
if (offset < 0)
return offset;
}
- ret = snd_pcm_stream_frame_data(plug->slave, stream, offset);
+ ret = snd_pcm_frame_data(plug->slave, offset);
if (ret < 0)
return ret;
- return snd_pcm_plug_client_size(pcm, stream, ret);
+ return snd_pcm_plug_client_size(plug, ret);
}
-ssize_t snd_pcm_plug_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count)
+ssize_t snd_pcm_plug_writev(void *private, const struct iovec *vector, unsigned long count)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_t *handle = plug->handle;
unsigned int k, step, channels;
- int size = 0;
- if (snd_pcm_plug_direct(pcm, SND_PCM_STREAM_PLAYBACK))
- return snd_pcm_writev(plug->slave, vector, count);
- channels = str->setup.format.channels;
- if (str->setup.format.interleave)
+ size_t size = 0;
+ assert(plug->frames_alloc);
+ channels = handle->setup.format.channels;
+ if (handle->setup.format.interleave)
step = 1;
else {
step = channels;
assert(count % channels == 0);
}
- for (k = 0; k < count; k += step, vector += step) {
+ for (k = 0; k < count; k += step) {
snd_pcm_plugin_channel_t *channels;
- int expected, ret;
- expected = snd_pcm_plug_client_channels_iovec(pcm, SND_PCM_STREAM_PLAYBACK, vector, count, &channels);
- if (expected < 0)
- return expected;
- ret = snd_pcm_plug_write_transfer(pcm, channels, expected);
- if (ret < 0) {
- if (size > 0)
- return size;
- return ret;
+ ssize_t frames;
+ frames = snd_pcm_plug_client_channels_iovec(plug, vector, count, &channels);
+ if (frames < 0)
+ return frames;
+ while (1) {
+ unsigned int c;
+ ssize_t ret;
+ size_t frames1 = frames;
+ if (frames1 > plug->frames_alloc)
+ frames1 = plug->frames_alloc;
+ ret = snd_pcm_plug_write_transfer(plug, channels, frames1);
+ if (ret < 0) {
+ if (size > 0)
+ return size;
+ return ret;
+ }
+ size += 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;
}
- size += ret;
- if (ret != expected)
- return size;
}
return size;
}
-ssize_t snd_pcm_plug_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count)
+ssize_t snd_pcm_plug_readv(void *private, const struct iovec *vector, unsigned long count)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- snd_pcm_stream_t *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_t *handle = plug->handle;
unsigned int k, step, channels;
- int size = 0;
- if (snd_pcm_plug_direct(pcm, SND_PCM_STREAM_CAPTURE))
- return snd_pcm_readv(plug->slave, vector, count);
- channels = str->setup.format.channels;
- if (str->setup.format.interleave)
+ size_t size = 0;
+ assert(plug->frames_alloc);
+ channels = handle->setup.format.channels;
+ if (handle->setup.format.interleave)
step = 1;
else {
step = channels;
}
for (k = 0; k < count; k += step) {
snd_pcm_plugin_channel_t *channels;
- int expected, ret;
- expected = snd_pcm_plug_client_channels_iovec(pcm, SND_PCM_STREAM_CAPTURE, vector, count, &channels);
- if (expected < 0)
- return expected;
- ret = snd_pcm_plug_read_transfer(pcm, channels, expected);
+ ssize_t frames;
+ frames = snd_pcm_plug_client_channels_iovec(plug, vector, count, &channels);
+ if (frames < 0)
+ return frames;
+ while (1) {
+ unsigned int c;
+ ssize_t ret;
+ size_t frames1 = frames;
+ if (frames1 > plug->frames_alloc)
+ frames1 = plug->frames_alloc;
+ ret = snd_pcm_plug_read_transfer(plug, channels, frames1);
+ if (ret < 0) {
+ if (size > 0)
+ return size;
+ return ret;
+ }
+ size += 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;
+ }
+ }
+ return size;
+}
+
+ssize_t snd_pcm_plug_write(void *private, const void *buf, size_t count)
+{
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_t *handle = plug->handle;
+ ssize_t frames;
+ snd_pcm_plugin_channel_t *channels;
+ size_t size = 0;
+ assert(plug->frames_alloc);
+ frames = snd_pcm_plug_client_channels_buf(plug, (char *)buf, count, &channels);
+ if (frames < 0)
+ return frames;
+
+ while (1) {
+ unsigned int c;
+ ssize_t ret;
+ size_t frames1 = frames;
+ if (frames1 > plug->frames_alloc)
+ frames1 = plug->frames_alloc;
+ ret = snd_pcm_plug_write_transfer(plug, channels, frames1);
if (ret < 0) {
if (size > 0)
return size;
return ret;
}
size += ret;
- if (ret != expected)
- return size;
+ 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;
}
return size;
}
-ssize_t snd_pcm_plug_write(snd_pcm_t *pcm, const void *buf, size_t count)
+ssize_t snd_pcm_plug_read(void *private, void *buf, size_t count)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- int expected;
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ snd_pcm_t *handle = plug->handle;
+ ssize_t frames;
snd_pcm_plugin_channel_t *channels;
-
- if (snd_pcm_plug_direct(pcm, SND_PCM_STREAM_PLAYBACK))
- return snd_pcm_write(plug->slave, buf, count);
- expected = snd_pcm_plug_client_channels_buf(pcm, SND_PCM_STREAM_PLAYBACK, (char *)buf, count, &channels);
- if (expected < 0)
- return expected;
- return snd_pcm_plug_write_transfer(pcm, channels, expected);
-}
-
-ssize_t snd_pcm_plug_read(snd_pcm_t *pcm, void *buf, size_t count)
-{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- int expected;
- snd_pcm_plugin_channel_t *channels;
-
- if (snd_pcm_plug_direct(pcm, SND_PCM_STREAM_CAPTURE))
- return snd_pcm_read(plug->slave, buf, count);
- expected = snd_pcm_plug_client_channels_buf(pcm, SND_PCM_STREAM_CAPTURE, buf, count, &channels);
- if (expected < 0)
- return expected;
- return snd_pcm_plug_read_transfer(pcm, channels, expected);
+ size_t size = 0;
+ assert(plug->frames_alloc);
+ frames = snd_pcm_plug_client_channels_buf(plug, buf, count, &channels);
+ if (frames < 0)
+ return frames;
+
+ while (1) {
+ unsigned int c;
+ ssize_t ret;
+ size_t frames1 = frames;
+ if (frames1 > plug->frames_alloc)
+ frames1 = plug->frames_alloc;
+ ret = snd_pcm_plug_read_transfer(plug, channels, frames1);
+ if (ret < 0) {
+ if (size > 0)
+ return size;
+ return ret;
+ }
+ size += 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;
+ }
+ return size;
}
-static int snd_pcm_plug_mmap_status(snd_pcm_t *pcm, int stream, snd_pcm_mmap_status_t **status)
+static int snd_pcm_plug_mmap_status(void *private UNUSED, snd_pcm_mmap_status_t **status UNUSED)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- if (snd_pcm_plug_direct(pcm, stream))
- return snd_pcm_mmap_status(plug->slave, stream, status);
return -EBADFD;
}
-static int snd_pcm_plug_mmap_control(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t **control)
+static int snd_pcm_plug_mmap_control(void *private UNUSED, snd_pcm_mmap_control_t **control UNUSED)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- if (snd_pcm_plug_direct(pcm, stream))
- return snd_pcm_mmap_control(plug->slave, stream, control);
return -EBADFD;
}
-static int snd_pcm_plug_mmap_data(snd_pcm_t *pcm, int stream, void **buffer, size_t bsize UNUSED)
+static int snd_pcm_plug_mmap_data(void *private UNUSED, void **buffer UNUSED, size_t bsize UNUSED)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- if (snd_pcm_plug_direct(pcm, stream))
- return snd_pcm_mmap_data(plug->slave, stream, buffer);
return -EBADFD;
}
-static int snd_pcm_plug_munmap_status(snd_pcm_t *pcm, int stream, snd_pcm_mmap_status_t *status UNUSED)
+static int snd_pcm_plug_munmap_status(void *private UNUSED, snd_pcm_mmap_status_t *status UNUSED)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- if (snd_pcm_plug_direct(pcm, stream))
- return snd_pcm_munmap_status(plug->slave, stream);
return -EBADFD;
}
-static int snd_pcm_plug_munmap_control(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t *control UNUSED)
+static int snd_pcm_plug_munmap_control(void *private UNUSED, snd_pcm_mmap_control_t *control UNUSED)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- if (snd_pcm_plug_direct(pcm, stream))
- return snd_pcm_munmap_control(plug->slave, stream);
return -EBADFD;
}
-static int snd_pcm_plug_munmap_data(snd_pcm_t *pcm, int stream, void *buffer UNUSED, size_t size UNUSED)
+static int snd_pcm_plug_munmap_data(void *private UNUSED, void *buffer UNUSED, size_t size UNUSED)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- if (snd_pcm_plug_direct(pcm, stream))
- return snd_pcm_munmap_data(plug->slave, stream);
return -EBADFD;
}
-static int snd_pcm_plug_channels_mask(snd_pcm_t *pcm, int stream,
+static int snd_pcm_plug_channels_mask(void *private,
bitset_t *client_vmask)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- if (snd_pcm_plug_direct(pcm, stream))
- return snd_pcm_channels_mask(plug->slave, stream, client_vmask);
- if (stream == SND_PCM_STREAM_PLAYBACK)
- return snd_pcm_plug_playback_channels_mask(pcm, client_vmask);
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ if (plug->handle->stream == SND_PCM_STREAM_PLAYBACK)
+ return snd_pcm_plug_playback_channels_mask(plug, client_vmask);
else
- return snd_pcm_plug_capture_channels_mask(pcm, client_vmask);
+ return snd_pcm_plug_capture_channels_mask(plug, client_vmask);
}
-int snd_pcm_plug_file_descriptor(snd_pcm_t* pcm, int stream)
+int snd_pcm_plug_file_descriptor(void *private)
{
- snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
- return snd_pcm_file_descriptor(plug->slave, stream);
+ snd_pcm_plug_t *plug = (snd_pcm_plug_t*) private;
+ return snd_pcm_file_descriptor(plug->slave);
}
+static int snd_pcm_plug_params(void *private, snd_pcm_params_t *params);
+
struct snd_pcm_ops snd_pcm_plug_ops = {
- stream_close: snd_pcm_plug_stream_close,
- stream_nonblock: snd_pcm_plug_stream_nonblock,
+ close: snd_pcm_plug_close,
+ nonblock: snd_pcm_plug_nonblock,
info: snd_pcm_plug_info,
- stream_info: snd_pcm_plug_stream_info,
- stream_params: snd_pcm_plug_stream_params,
- stream_setup: snd_pcm_plug_stream_setup,
+ params: snd_pcm_plug_params,
+ setup: snd_pcm_plug_setup,
channel_setup: snd_pcm_plug_channel_setup,
- stream_status: snd_pcm_plug_stream_status,
- stream_frame_io: snd_pcm_plug_stream_frame_io,
- stream_state: snd_pcm_plug_stream_state,
- stream_prepare: snd_pcm_plug_stream_prepare,
- stream_go: snd_pcm_plug_stream_go,
+ status: snd_pcm_plug_status,
+ frame_io: snd_pcm_plug_frame_io,
+ state: snd_pcm_plug_state,
+ prepare: snd_pcm_plug_prepare,
+ go: snd_pcm_plug_go,
sync_go: snd_pcm_plug_sync_go,
- stream_drain: snd_pcm_plug_stream_drain,
- stream_flush: snd_pcm_plug_stream_flush,
- stream_pause: snd_pcm_plug_stream_pause,
- stream_frame_data: snd_pcm_plug_stream_frame_data,
+ drain: snd_pcm_plug_drain,
+ flush: snd_pcm_plug_flush,
+ pause: snd_pcm_plug_pause,
+ frame_data: snd_pcm_plug_frame_data,
write: snd_pcm_plug_write,
writev: snd_pcm_plug_writev,
read: snd_pcm_plug_read,
channels_mask: snd_pcm_plug_channels_mask,
};
-int snd_pcm_plug_connect(snd_pcm_t **handle, snd_pcm_t *slave, int mode, int close_slave)
+static int snd_pcm_plug_params(void *private, snd_pcm_params_t *params)
{
- snd_pcm_t *pcm;
+ snd_pcm_params_t slave_params, params1;
+ snd_pcm_info_t slave_info;
+ snd_pcm_plugin_t *plugin;
snd_pcm_plug_t *plug;
int err;
- err = snd_pcm_abstract_open(handle, mode, SND_PCM_TYPE_PLUG, sizeof(snd_pcm_plug_t));
+
+ plug = (snd_pcm_plug_t*) private;
+
+ /*
+ * try to decide, if a conversion is required
+ */
+
+ memset(&slave_info, 0, sizeof(slave_info));
+ slave_info.stream = plug->slave->stream;
+ if ((err = snd_pcm_info(plug->slave, &slave_info)) < 0) {
+ snd_pcm_plug_clear(plug);
+ return err;
+ }
+
+ if ((err = snd_pcm_plug_slave_params(params, &slave_info, &slave_params)) < 0)
+ return err;
+
+
+ snd_pcm_plug_clear(plug);
+
+ /* add necessary plugins */
+ params1 = *params;
+ if ((err = snd_pcm_plug_format(plug, ¶ms1, &slave_params)) < 0)
+ return err;
+
+ if (!plug->first) {
+ err = snd_pcm_params(plug->slave, params);
+ if (err < 0)
+ return err;
+ *plug->handle->ops = *plug->slave->ops;
+ plug->handle->ops->params = snd_pcm_plug_params;
+ plug->handle->ops->setup = snd_pcm_plug_setup;
+ plug->handle->ops->info = snd_pcm_plug_info;
+ plug->handle->op_arg = plug->slave->op_arg;
+ return 0;
+ } else {
+ *plug->handle->ops = snd_pcm_plug_ops;
+ plug->handle->op_arg = plug;
+ }
+
+ /* compute right sizes */
+ slave_params.frag_size = snd_pcm_plug_slave_size(plug, params1.frag_size);
+ slave_params.buffer_size = snd_pcm_plug_slave_size(plug, params1.buffer_size);
+ slave_params.frames_fill_max = snd_pcm_plug_slave_size(plug, params1.frames_fill_max);
+ slave_params.frames_min = snd_pcm_plug_slave_size(plug, params1.frames_min);
+ slave_params.frames_xrun_max = snd_pcm_plug_slave_size(plug, params1.frames_xrun_max);
+ slave_params.frames_align = snd_pcm_plug_slave_size(plug, params1.frames_align);
+ if (slave_params.frame_boundary == 0 || slave_params.frame_boundary > INT_MAX)
+ slave_params.frame_boundary = INT_MAX;
+ assert(params->buffer_size > 0);
+ slave_params.frame_boundary /= params->buffer_size;
+ if (slave_params.frame_boundary > INT_MAX / slave_params.buffer_size)
+ slave_params.frame_boundary = INT_MAX;
+ else
+ slave_params.frame_boundary *= slave_params.buffer_size;
+
+ /*
+ * I/O plugins
+ */
+
+ if (slave_info.flags & SND_PCM_INFO_MMAP) {
+ pdprintf("params mmap plugin\n");
+ err = snd_pcm_plugin_build_mmap(plug, &slave_params.format, &plugin);
+ } else {
+ pdprintf("params I/O plugin\n");
+ err = snd_pcm_plugin_build_io(plug, &slave_params.format, &plugin);
+ }
+ if (err < 0)
+ return err;
+ if (plug->slave->stream == SND_PCM_STREAM_PLAYBACK) {
+ err = snd_pcm_plugin_append(plugin);
+ } else {
+ err = snd_pcm_plugin_insert(plugin);
+ }
if (err < 0) {
- if (close_slave)
- snd_pcm_close(slave);
+ snd_pcm_plugin_free(plugin);
return err;
}
- pcm = *handle;
- pcm->ops = &snd_pcm_plug_ops;
- plug = (snd_pcm_plug_t*) &pcm->private;
+
+ pdprintf("params requested params: format = %i, rate = %i, channels = %i\n", slave_params.format.format, slave_params.format.rate, slave_params.format.channels);
+ err = snd_pcm_params(plug->slave, &slave_params);
+ if (err < 0)
+ return err;
+
+ err = snd_pcm_plug_action(plug, INIT, 0);
+ if (err < 0)
+ return err;
+ return 0;
+}
+
+int snd_pcm_plug_create(snd_pcm_t **handlep, snd_pcm_t *slave, int close_slave)
+{
+ snd_pcm_t *handle;
+ snd_pcm_plug_t *plug;
+ handle = calloc(1, sizeof(snd_pcm_t));
+ if (!handle)
+ return -ENOMEM;
+ plug = calloc(1, sizeof(snd_pcm_plug_t));
+ if (!plug) {
+ free(handle);
+ return -ENOMEM;
+ }
+ plug->handle = handle;
plug->slave = slave;
plug->close_slave = close_slave;
+ handle->type = SND_PCM_TYPE_PLUG;
+ handle->stream = slave->stream;
+ handle->ops = malloc(sizeof(*handle->ops));
+ *handle->ops = *slave->ops;
+ handle->ops->params = snd_pcm_plug_params;
+ handle->ops->setup = snd_pcm_plug_setup;
+ handle->ops->info = snd_pcm_plug_info;
+ handle->op_arg = slave->op_arg;
+ handle->mode = slave->mode;
+ handle->private = plug;
+ *handlep = handle;
return 0;
}
-int snd_pcm_plug_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevice, int mode)
+int snd_pcm_plug_open_subdevice(snd_pcm_t **handlep, int card, int device, int subdevice, int stream, int mode)
{
snd_pcm_t *slave;
int err;
- err = snd_pcm_open_subdevice(&slave, card, device, subdevice, mode);
+ err = snd_pcm_hw_open_subdevice(&slave, card, device, subdevice, stream, mode);
if (err < 0)
return err;
- return snd_pcm_plug_connect(handle, slave, mode, 1);
+ return snd_pcm_plug_create(handlep, slave, 1);
}
-int snd_pcm_plug_open(snd_pcm_t **handle, int card, int device, int mode)
+int snd_pcm_plug_open(snd_pcm_t **handlep, int card, int device, int stream, int mode)
{
- return snd_pcm_plug_open_subdevice(handle, card, device, -1, mode);
+ return snd_pcm_plug_open_subdevice(handlep, card, device, -1, stream, mode);
}
return 0; /* silenty ignore other actions */
}
-int snd_pcm_plugin_build_adpcm(snd_pcm_plugin_handle_t *handle,
- int stream,
+int snd_pcm_plugin_build_adpcm(snd_pcm_plug_t *plug,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
snd_pcm_plugin_t **r_plugin)
assert(0);
assert(snd_pcm_format_linear(format->format));
- err = snd_pcm_plugin_build(handle, stream,
- "Ima-ADPCM<->linear conversion",
- src_format,
- dst_format,
+ err = snd_pcm_plugin_build(plug, "Ima-ADPCM<->linear conversion",
+ src_format, dst_format,
sizeof(adpcm_t) + src_format->channels * sizeof(adpcm_channel_t),
&plugin);
if (err < 0)
return frames;
}
-int snd_pcm_plugin_build_alaw(snd_pcm_plugin_handle_t *handle,
- int stream,
+int snd_pcm_plugin_build_alaw(snd_pcm_plug_t *plug,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
snd_pcm_plugin_t **r_plugin)
assert(0);
assert(snd_pcm_format_linear(format->format));
- err = snd_pcm_plugin_build(handle, stream,
- "A-Law<->linear conversion",
- src_format,
- dst_format,
- sizeof(alaw_t),
- &plugin);
+ err = snd_pcm_plugin_build(plug, "A-Law<->linear conversion",
+ src_format, dst_format,
+ sizeof(alaw_t), &plugin);
if (err < 0)
return err;
data = (alaw_t*)plugin->extra_data;
return frames;
}
-int snd_pcm_plugin_build_copy(snd_pcm_plugin_handle_t *handle,
- int stream,
+int snd_pcm_plugin_build_copy(snd_pcm_plug_t *plug,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
snd_pcm_plugin_t **r_plugin)
width = snd_pcm_format_physical_width(src_format->format);
assert(width > 0);
- err = snd_pcm_plugin_build(handle, stream,
- "copy",
- src_format,
- dst_format,
- 0,
- &plugin);
+ err = snd_pcm_plugin_build(plug, "copy", src_format, dst_format,
+ 0, &plugin);
if (err < 0)
return err;
plugin->transfer = copy_transfer;
#include "../../include/driver.h"
#include "../../include/pcm.h"
#include "../../include/pcm_plugin.h"
-#define snd_pcm_write(handle,buf,count) snd_pcm_oss_write3(handle,buf,count,1)
-#define snd_pcm_writev(handle,vec,count) snd_pcm_oss_writev3(handle,vec,count,1)
-#define snd_pcm_read(handle,buf,count) snd_pcm_oss_read3(handle,buf,count,1)
-#define snd_pcm_readv(handle,vec,count) snd_pcm_oss_readv3(handle,vec,count,1)
+#define pcm_write(plug,buf,count) snd_pcm_oss_write3(plug,buf,count,1)
+#define pcm_writev(plug,vec,count) snd_pcm_oss_writev3(plug,vec,count,1)
+#define pcm_read(plug,buf,count) snd_pcm_oss_read3(plug,buf,count,1)
+#define pcm_readv(plug,vec,count) snd_pcm_oss_readv3(plug,vec,count,1)
#else
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/uio.h>
#include "../pcm_local.h"
+#define pcm_write(plug,buf,count) snd_pcm_write(plug->slave,buf,count)
+#define pcm_writev(plug,vec,count) snd_pcm_writev(plug->slave,vec,count)
+#define pcm_read(plug,buf,count) snd_pcm_read(plug->slave,buf,count)
+#define pcm_readv(plug,vec,count) snd_pcm_readv(plug->slave,vec,count)
#endif
/*
* Basic io plugin
*/
-typedef struct io_private_data {
- snd_pcm_plugin_handle_t *slave;
-} io_t;
-
-static ssize_t io_transfer(snd_pcm_plugin_t *plugin,
- const snd_pcm_plugin_channel_t *src_channels,
- snd_pcm_plugin_channel_t *dst_channels,
- size_t frames)
+static ssize_t io_playback_transfer(snd_pcm_plugin_t *plugin,
+ const snd_pcm_plugin_channel_t *src_channels,
+ snd_pcm_plugin_channel_t *dst_channels UNUSED,
+ size_t frames)
{
- io_t *data;
struct iovec *vec;
int count, channel;
assert(plugin);
- data = (io_t *)plugin->extra_data;
- assert(data);
- vec = (struct iovec *)((char *)data + sizeof(*data));
- if (plugin->stream == SND_PCM_STREAM_PLAYBACK) {
- assert(src_channels);
- count = plugin->src_format.channels;
- if (plugin->src_format.interleave) {
- return snd_pcm_write(data->slave, src_channels->area.addr, frames);
- } else {
- for (channel = 0; channel < count; channel++) {
- if (src_channels[channel].enabled)
- vec[channel].iov_base = src_channels[channel].area.addr;
- else
- vec[channel].iov_base = 0;
- vec[channel].iov_len = frames;
- }
- return snd_pcm_writev(data->slave, vec, count);
- }
- } else if (plugin->stream == SND_PCM_STREAM_CAPTURE) {
- assert(dst_channels);
- count = plugin->dst_format.channels;
- if (plugin->dst_format.interleave) {
- for (channel = 0; channel < count; channel++) {
- dst_channels[channel].enabled = src_channels[channel].enabled;
- }
- return snd_pcm_read(data->slave, dst_channels->area.addr, frames);
- } else {
- for (channel = 0; channel < count; channel++) {
- dst_channels[channel].enabled = src_channels[channel].enabled;
- if (dst_channels[channel].enabled)
- vec[channel].iov_base = dst_channels[channel].area.addr;
- else
- vec[channel].iov_base = 0;
- vec[channel].iov_len = frames;
- }
- return snd_pcm_readv(data->slave, vec, count);
+ vec = (struct iovec *)plugin->extra_data;
+ assert(vec);
+ assert(src_channels);
+ count = plugin->src_format.channels;
+ if (plugin->src_format.interleave) {
+ return pcm_write(plugin->plug, src_channels->area.addr, frames);
+ } else {
+ for (channel = 0; channel < count; channel++) {
+ if (src_channels[channel].enabled)
+ vec[channel].iov_base = src_channels[channel].area.addr;
+ else
+ vec[channel].iov_base = 0;
+ vec[channel].iov_len = frames;
}
+ return pcm_writev(plugin->plug, vec, count);
+ }
+}
+
+static ssize_t io_capture_transfer(snd_pcm_plugin_t *plugin,
+ const snd_pcm_plugin_channel_t *src_channels UNUSED,
+ snd_pcm_plugin_channel_t *dst_channels,
+ size_t frames)
+{
+ struct iovec *vec;
+ int count, channel;
+
+ assert(plugin);
+ vec = (struct iovec *)plugin->extra_data;
+ assert(vec);
+ assert(dst_channels);
+ count = plugin->dst_format.channels;
+ if (plugin->dst_format.interleave) {
+ return pcm_read(plugin->plug, dst_channels->area.addr, frames);
} else {
- assert(0);
+ for (channel = 0; channel < count; channel++) {
+ if (dst_channels[channel].enabled)
+ vec[channel].iov_base = dst_channels[channel].area.addr;
+ else
+ vec[channel].iov_base = 0;
+ vec[channel].iov_len = frames;
+ }
+ return pcm_readv(plugin->plug, vec, count);
}
return 0;
}
if (err < 0)
return err;
*channels = v;
- for (channel = 0; channel < plugin->src_format.channels; ++channel, ++v)
- v->wanted = 1;
+ if (plugin->src_format.interleave) {
+ for (channel = 0; channel < plugin->src_format.channels; ++channel, ++v)
+ v->wanted = 1;
+ }
return frames;
}
-int snd_pcm_plugin_build_io(snd_pcm_plugin_handle_t *pcm,
- int stream,
- snd_pcm_plugin_handle_t *slave,
- snd_pcm_format_t *format,
- snd_pcm_plugin_t **r_plugin)
+int snd_pcm_plugin_build_io(snd_pcm_plug_t *plug,
+ snd_pcm_format_t *format,
+ snd_pcm_plugin_t **r_plugin)
{
int err;
- io_t *data;
snd_pcm_plugin_t *plugin;
assert(r_plugin);
*r_plugin = NULL;
- assert(pcm && format);
- err = snd_pcm_plugin_build(pcm, stream,
- "I/O io",
+ assert(plug && format);
+ err = snd_pcm_plugin_build(plug, "I/O io",
format, format,
- sizeof(io_t) + sizeof(struct iovec) * format->channels,
+ sizeof(struct iovec) * format->channels,
&plugin);
if (err < 0)
return err;
- data = (io_t *)plugin->extra_data;
- data->slave = slave;
- plugin->transfer = io_transfer;
- if (format->interleave && stream == SND_PCM_STREAM_PLAYBACK)
- plugin->client_channels = io_src_channels;
+ if (snd_pcm_plug_stream(plug) == SND_PCM_STREAM_PLAYBACK) {
+ plugin->transfer = io_playback_transfer;
+ if (format->interleave)
+ plugin->client_channels = io_src_channels;
+ } else {
+ plugin->transfer = io_capture_transfer;
+ }
+
*r_plugin = plugin;
return 0;
}
return src_width * 32 + src_endian * 16 + sign * 8 + dst_width * 2 + dst_endian;
}
-int snd_pcm_plugin_build_linear(snd_pcm_plugin_handle_t *handle,
- int stream,
+int snd_pcm_plugin_build_linear(snd_pcm_plug_t *plug,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
snd_pcm_plugin_t **r_plugin)
assert(snd_pcm_format_linear(src_format->format) &&
snd_pcm_format_linear(dst_format->format));
- err = snd_pcm_plugin_build(handle, stream,
- "linear format conversion",
- src_format,
- dst_format,
- sizeof(linear_t),
- &plugin);
+ err = snd_pcm_plugin_build(plug, "linear format conversion",
+ src_format, dst_format,
+ sizeof(linear_t), &plugin);
if (err < 0)
return err;
data = (linear_t *)plugin->extra_data;
*/
typedef struct mmap_private_data {
- snd_pcm_t *slave;
void *buffer;
#if 0
char *silence;
mmap_t *data;
snd_pcm_plugin_channel_t *sv;
snd_pcm_channel_area_t *dv;
- snd_pcm_stream_t *stream;
- snd_pcm_stream_setup_t *setup;
+ snd_pcm_t *stream;
+ snd_pcm_setup_t *setup;
size_t pos;
int ready;
unsigned int channel;
assert(plugin && channels);
data = (mmap_t *)plugin->extra_data;
- stream = &data->slave->stream[plugin->stream];
+ stream = plugin->plug->slave;
setup = &stream->setup;
- if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) < SND_PCM_STATE_PREPARED)
+ if (snd_pcm_mmap_state(stream) < SND_PCM_STATE_PREPARED)
return -EBADFD;
- ready = snd_pcm_mmap_ready(data->slave, plugin->stream);
+ ready = snd_pcm_mmap_ready(stream);
if (ready < 0)
return ready;
if (!ready) {
struct pollfd pfd;
- if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) != SND_PCM_STATE_RUNNING)
+ if (snd_pcm_mmap_state(stream) != SND_PCM_STATE_RUNNING)
return -EPIPE;
if (stream->mode & SND_PCM_NONBLOCK)
return -EAGAIN;
- pfd.fd = snd_pcm_file_descriptor(data->slave, plugin->stream);
+ pfd.fd = snd_pcm_file_descriptor(stream);
pfd.events = POLLOUT | POLLERR;
ready = poll(&pfd, 1, 10000);
if (ready < 0)
return ready;
if (ready && pfd.revents & POLLERR)
return -EPIPE;
- assert(snd_pcm_mmap_ready(data->slave, plugin->stream));
+ assert(snd_pcm_mmap_ready(stream));
}
- pos = snd_pcm_mmap_frames_offset(data->slave, plugin->stream);
+ pos = snd_pcm_mmap_frames_offset(stream);
assert(pos % setup->frames_align == 0);
- sv = plugin->src_channels;
+ sv = plugin->buf_channels;
dv = stream->channels;
*channels = sv;
for (channel = 0; channel < plugin->src_format.channels; ++channel) {
#else
sv->wanted = 1;
#endif
- sv->aptr = 0;
sv->area.addr = dv->addr + dv->step * pos / 8;
sv->area.first = dv->first;
sv->area.step = dv->step;
++sv;
++dv;
}
- return snd_pcm_mmap_frames_xfer(data->slave, plugin->stream, frames);
+ return snd_pcm_mmap_frames_xfer(stream, frames);
}
static ssize_t mmap_dst_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;
int err;
unsigned int channel;
snd_pcm_plugin_channel_t *dv;
snd_pcm_channel_area_t *sv;
- snd_pcm_stream_t *stream;
- snd_pcm_stream_setup_t *setup;
+ snd_pcm_t *stream;
+ snd_pcm_setup_t *setup;
size_t pos;
int ready;
assert(plugin && channels);
data = (mmap_t *)plugin->extra_data;
- stream = &data->slave->stream[plugin->stream];
+ stream = plugin->plug->slave;
setup = &stream->setup;
- if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) < SND_PCM_STATE_PREPARED)
+ if (snd_pcm_mmap_state(stream) < SND_PCM_STATE_PREPARED)
return -EBADFD;
- if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) == SND_PCM_STATE_PREPARED &&
+ if (snd_pcm_mmap_state(stream) == SND_PCM_STATE_PREPARED &&
stream->setup.start_mode == SND_PCM_START_DATA) {
- err = snd_pcm_stream_go(data->slave, plugin->stream);
+ err = snd_pcm_go(stream);
if (err < 0)
return err;
}
- ready = snd_pcm_mmap_ready(data->slave, plugin->stream);
+ ready = snd_pcm_mmap_ready(stream);
if (ready < 0)
return ready;
if (!ready) {
struct pollfd pfd;
- if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) != SND_PCM_STATE_RUNNING)
+ if (snd_pcm_mmap_state(stream) != SND_PCM_STATE_RUNNING)
return -EPIPE;
if (stream->mode & SND_PCM_NONBLOCK)
return -EAGAIN;
- pfd.fd = snd_pcm_file_descriptor(data->slave, plugin->stream);
+ pfd.fd = snd_pcm_file_descriptor(stream);
pfd.events = POLLIN | POLLERR;
ready = poll(&pfd, 1, 10000);
if (ready < 0)
return ready;
if (ready && pfd.revents & POLLERR)
return -EPIPE;
- assert(snd_pcm_mmap_ready(data->slave, plugin->stream));
+ assert(snd_pcm_mmap_ready(stream));
}
- pos = snd_pcm_mmap_frames_offset(data->slave, plugin->stream);
+ pos = snd_pcm_mmap_frames_offset(stream);
assert(pos % setup->frames_align == 0);
sv = stream->channels;
- dv = plugin->dst_channels;
+ dv = plugin->buf_channels;
*channels = dv;
for (channel = 0; channel < plugin->dst_format.channels; ++channel) {
dv->enabled = 1;
dv->wanted = 0;
- dv->aptr = 0;
dv->area.addr = sv->addr + sv->step * pos / 8;
dv->area.first = sv->first;
dv->area.step = sv->step;
++sv;
++dv;
}
- return snd_pcm_mmap_frames_xfer(data->slave, plugin->stream, frames);
+ return snd_pcm_mmap_frames_xfer(stream, frames);
}
static ssize_t mmap_playback_transfer(snd_pcm_plugin_t *plugin,
size_t frames)
{
mmap_t *data;
- snd_pcm_stream_setup_t *setup;
- snd_pcm_stream_t *str;
+ snd_pcm_setup_t *setup;
+ snd_pcm_t *stream;
int err;
assert(plugin && plugin->prev);
assert(src_channels);
data = (mmap_t *)plugin->extra_data;
- str = &data->slave->stream[SND_PCM_STREAM_PLAYBACK];
- setup = &str->setup;
+ stream = plugin->plug->slave;
+ setup = &stream->setup;
#if 0
for (channel = 0; channel < plugin->src_format.channels; channel++) {
}
#endif
- snd_pcm_mmap_stream_frame_data(data->slave, SND_PCM_STREAM_PLAYBACK, frames);
- if (snd_pcm_mmap_stream_state(data->slave, plugin->stream) == SND_PCM_STATE_PREPARED &&
- (str->setup.start_mode == SND_PCM_START_DATA ||
- (str->setup.start_mode == SND_PCM_START_FULL &&
- !snd_pcm_mmap_ready(data->slave, plugin->stream)))) {
- err = snd_pcm_stream_go(data->slave, plugin->stream);
+ snd_pcm_frame_data(stream, frames);
+ if (snd_pcm_mmap_state(stream) == SND_PCM_STATE_PREPARED &&
+ (setup->start_mode == SND_PCM_START_DATA ||
+ (setup->start_mode == SND_PCM_START_FULL &&
+ !snd_pcm_mmap_ready(stream)))) {
+ err = snd_pcm_go(stream);
if (err < 0)
return err;
}
size_t frames)
{
mmap_t *data;
- snd_pcm_stream_t *str;
+ snd_pcm_t *stream;
assert(plugin && plugin->next);
data = (mmap_t *)plugin->extra_data;
- str = &data->slave->stream[SND_PCM_STREAM_CAPTURE];
+ stream = plugin->plug->slave;
/* FIXME: not here the increment */
- snd_pcm_mmap_stream_frame_data(data->slave, SND_PCM_STREAM_CAPTURE, frames);
+ snd_pcm_frame_data(stream, frames);
return frames;
}
unsigned long udata UNUSED)
{
struct mmap_private_data *data;
+ snd_pcm_t *stream;
assert(plugin);
+ stream = plugin->plug->slave;
data = (mmap_t *)plugin->extra_data;
if (action == INIT) {
- snd_pcm_stream_setup_t *setup;
+ snd_pcm_setup_t *setup;
int result;
if (data->buffer) {
- snd_pcm_munmap(data->slave, plugin->stream);
+ snd_pcm_munmap(stream);
data->buffer = 0;
}
- result = snd_pcm_mmap(data->slave, plugin->stream, NULL, NULL, (void **)&data->buffer);
+ result = snd_pcm_mmap(stream, NULL, NULL, (void **)&data->buffer);
if (result < 0)
return result;
- setup = &data->slave->stream[plugin->stream].setup;
+ setup = &stream->setup;
#if 0
if (plugin->stream == SND_PCM_STREAM_PLAYBACK) {
free(data->silence);
#endif
if (data->buffer)
- snd_pcm_munmap(data->slave, plugin->stream);
+ snd_pcm_munmap(plugin->plug->slave);
}
-int snd_pcm_plugin_build_mmap(snd_pcm_plugin_handle_t *pcm,
- int stream,
- snd_pcm_t *slave,
+int snd_pcm_plugin_build_mmap(snd_pcm_plug_t *plug,
snd_pcm_format_t *format,
snd_pcm_plugin_t **r_plugin)
{
assert(r_plugin);
*r_plugin = NULL;
- assert(pcm);
- err = snd_pcm_plugin_build(pcm, stream,
- "I/O mmap",
+ assert(plug);
+ err = snd_pcm_plugin_build(plug, "I/O mmap",
format, format,
sizeof(mmap_t) + sizeof(snd_pcm_plugin_channel_t) * format->channels,
&plugin);
if (err < 0)
return err;
data = (mmap_t *)plugin->extra_data;
- data->slave = slave;
- if (stream == SND_PCM_STREAM_PLAYBACK) {
+ if (plug->handle->stream == SND_PCM_STREAM_PLAYBACK) {
plugin->client_channels = mmap_src_channels;
plugin->transfer = mmap_playback_transfer;
} else {
return frames;
}
-int snd_pcm_plugin_build_mulaw(snd_pcm_plugin_handle_t *handle,
- int stream,
+int snd_pcm_plugin_build_mulaw(snd_pcm_plug_t *plug,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
snd_pcm_plugin_t **r_plugin)
}
assert(snd_pcm_format_linear(format->format));
- err = snd_pcm_plugin_build(handle, stream,
- "Mu-Law<->linear conversion",
- src_format,
- dst_format,
- sizeof(mulaw_t),
- &plugin);
+ err = snd_pcm_plugin_build(plug, "Mu-Law<->linear conversion",
+ src_format, dst_format,
+ sizeof(mulaw_t), &plugin);
if (err < 0)
return err;
data = (mulaw_t*)plugin->extra_data;
return 0; /* silenty ignore other actions */
}
-int snd_pcm_plugin_build_rate(snd_pcm_plugin_handle_t *handle,
- int stream,
+int snd_pcm_plugin_build_rate(snd_pcm_plug_t *plug,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
snd_pcm_plugin_t **r_plugin)
assert(snd_pcm_format_linear(dst_format->format) > 0);
assert(src_format->rate != dst_format->rate);
- err = snd_pcm_plugin_build(handle, stream,
- "rate conversion",
- src_format,
- dst_format,
+ err = snd_pcm_plugin_build(plug, "rate conversion",
+ src_format, dst_format,
sizeof(rate_t) + src_format->channels * sizeof(rate_channel_t),
&plugin);
if (err < 0)
return width * 4 + endian * 2 + sign;
}
-int snd_pcm_plugin_build_route(snd_pcm_plugin_handle_t *handle,
- int stream,
+int snd_pcm_plugin_build_route(snd_pcm_plug_t *plug,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
route_ttable_entry_t *ttable,
assert(snd_pcm_format_linear(src_format->format) &&
snd_pcm_format_linear(dst_format->format));
- err = snd_pcm_plugin_build(handle, stream,
- "attenuated route conversion",
- src_format,
- dst_format,
+ err = snd_pcm_plugin_build(plug, "attenuated route conversion",
+ src_format, dst_format,
sizeof(route_t) + sizeof(data->ttable[0]) * dst_format->channels,
&plugin);
if (err < 0)