Better names for ALSA API. Added min_fragments, max_fragments.

This commit is contained in:
Abramo Bagnara 2000-05-27 16:52:17 +00:00
parent 4bb0a08bf9
commit 1a7f88d10e
26 changed files with 1938 additions and 1938 deletions

View file

@ -29,7 +29,7 @@ and vice versa. The ADPCM code used is the Intel/DVI ADPCM code which
is being recommended by the IMA Digital Audio Technical Working Group.
The algorithm for this coder was taken from:
Proposal for Standardized Audio Interchange Formats,
Proposal for Standardized Audio Interstreamge Formats,
IMA compatability project proceedings, Vol 2, Issue 2, May 1992.
- No, this is *not* a G.721 coder/decoder. The algorithm used by G.721
@ -74,32 +74,32 @@ static short StepSize[89] = {
typedef struct {
int pred_val; /* Calculated predicted value */
int step_idx; /* Previous StepSize lookup index */
} adpcm_voice_t;
} adpcm_channel_t;
typedef void (*adpcm_f)(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames);
typedef struct adpcm_private_data {
adpcm_f func;
int conv;
adpcm_voice_t voices[0];
adpcm_channel_t channels[0];
} adpcm_t;
static void adpcm_init(snd_pcm_plugin_t *plugin)
{
unsigned int voice;
unsigned int channel;
adpcm_t *data = (adpcm_t *)plugin->extra_data;
for (voice = 0; voice < plugin->src_format.voices; voice++) {
adpcm_voice_t *v = &data->voices[voice];
for (channel = 0; channel < plugin->src_format.channels; channel++) {
adpcm_channel_t *v = &data->channels[channel];
v->pred_val = 0;
v->step_idx = 0;
}
}
static char adpcm_encoder(int sl, adpcm_voice_t * state)
static char adpcm_encoder(int sl, adpcm_channel_t * state)
{
short diff; /* Difference between sl and predicted sample */
short pred_diff; /* Predicted difference to next sample */
@ -160,7 +160,7 @@ static char adpcm_encoder(int sl, adpcm_voice_t * state)
}
static int adpcm_decoder(unsigned char code, adpcm_voice_t * state)
static int adpcm_decoder(unsigned char code, adpcm_channel_t * state)
{
short pred_diff; /* Predicted difference to next sample */
short step; /* holds previous StepSize value */
@ -211,8 +211,8 @@ static int adpcm_decoder(unsigned char code, adpcm_voice_t * state)
*/
static void adpcm_decode(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames)
{
#define PUT_S16_LABELS
@ -220,29 +220,29 @@ static void adpcm_decode(snd_pcm_plugin_t *plugin,
#undef PUT_S16_LABELS
adpcm_t *data = (adpcm_t *)plugin->extra_data;
void *put = put_s16_labels[data->conv];
int voice;
int nvoices = plugin->src_format.voices;
for (voice = 0; voice < nvoices; ++voice) {
int channel;
int nchannels = plugin->src_format.channels;
for (channel = 0; channel < nchannels; ++channel) {
char *src;
int srcbit;
char *dst;
int src_step, srcbit_step, dst_step;
size_t frames1;
adpcm_voice_t *state;
if (!src_voices[voice].enabled) {
if (dst_voices[voice].wanted)
snd_pcm_area_silence(&dst_voices[voice].area, 0, frames, plugin->dst_format.format);
dst_voices[voice].enabled = 0;
adpcm_channel_t *state;
if (!src_channels[channel].enabled) {
if (dst_channels[channel].wanted)
snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
dst_channels[channel].enabled = 0;
continue;
}
dst_voices[voice].enabled = 1;
src = src_voices[voice].area.addr + src_voices[voice].area.first / 8;
srcbit = src_voices[voice].area.first % 8;
dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
src_step = src_voices[voice].area.step / 8;
srcbit_step = src_voices[voice].area.step % 8;
dst_step = dst_voices[voice].area.step / 8;
state = &data->voices[voice];
dst_channels[channel].enabled = 1;
src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
srcbit = src_channels[channel].area.first % 8;
dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
src_step = src_channels[channel].area.step / 8;
srcbit_step = src_channels[channel].area.step % 8;
dst_step = dst_channels[channel].area.step / 8;
state = &data->channels[channel];
frames1 = frames;
while (frames1-- > 0) {
signed short sample;
@ -269,8 +269,8 @@ static void adpcm_decode(snd_pcm_plugin_t *plugin,
}
static void adpcm_encode(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames)
{
#define GET_S16_LABELS
@ -278,30 +278,30 @@ static void adpcm_encode(snd_pcm_plugin_t *plugin,
#undef GET_S16_LABELS
adpcm_t *data = (adpcm_t *)plugin->extra_data;
void *get = get_s16_labels[data->conv];
int voice;
int nvoices = plugin->src_format.voices;
int channel;
int nchannels = plugin->src_format.channels;
signed short sample = 0;
for (voice = 0; voice < nvoices; ++voice) {
for (channel = 0; channel < nchannels; ++channel) {
char *src;
char *dst;
int dstbit;
int src_step, dst_step, dstbit_step;
size_t frames1;
adpcm_voice_t *state;
if (!src_voices[voice].enabled) {
if (dst_voices[voice].wanted)
snd_pcm_area_silence(&dst_voices[voice].area, 0, frames, plugin->dst_format.format);
dst_voices[voice].enabled = 0;
adpcm_channel_t *state;
if (!src_channels[channel].enabled) {
if (dst_channels[channel].wanted)
snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
dst_channels[channel].enabled = 0;
continue;
}
dst_voices[voice].enabled = 1;
src = src_voices[voice].area.addr + src_voices[voice].area.first / 8;
dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
dstbit = dst_voices[voice].area.first % 8;
src_step = src_voices[voice].area.step / 8;
dst_step = dst_voices[voice].area.step / 8;
dstbit_step = dst_voices[voice].area.step % 8;
state = &data->voices[voice];
dst_channels[channel].enabled = 1;
src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
dstbit = dst_channels[channel].area.first % 8;
src_step = src_channels[channel].area.step / 8;
dst_step = dst_channels[channel].area.step / 8;
dstbit_step = dst_channels[channel].area.step % 8;
state = &data->channels[channel];
frames1 = frames;
while (frames1-- > 0) {
int v;
@ -327,34 +327,34 @@ static void adpcm_encode(snd_pcm_plugin_t *plugin,
}
static ssize_t adpcm_transfer(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames)
{
adpcm_t *data;
unsigned int voice;
unsigned int channel;
if (plugin == NULL || src_voices == NULL || dst_voices == NULL)
if (plugin == NULL || src_channels == NULL || dst_channels == NULL)
return -EFAULT;
if (frames == 0)
return 0;
for (voice = 0; voice < plugin->src_format.voices; voice++) {
for (channel = 0; channel < plugin->src_format.channels; channel++) {
if (plugin->src_format.format == SND_PCM_SFMT_IMA_ADPCM) {
if (src_voices[voice].area.first % 4 != 0 ||
src_voices[voice].area.step % 4 != 0 ||
dst_voices[voice].area.first % 8 != 0 ||
dst_voices[voice].area.step % 8 != 0)
if (src_channels[channel].area.first % 4 != 0 ||
src_channels[channel].area.step % 4 != 0 ||
dst_channels[channel].area.first % 8 != 0 ||
dst_channels[channel].area.step % 8 != 0)
return -EINVAL;
} else {
if (src_voices[voice].area.first % 8 != 0 ||
src_voices[voice].area.step % 8 != 0 ||
dst_voices[voice].area.first % 4 != 0 ||
dst_voices[voice].area.step % 4 != 0)
if (src_channels[channel].area.first % 8 != 0 ||
src_channels[channel].area.step % 8 != 0 ||
dst_channels[channel].area.first % 4 != 0 ||
dst_channels[channel].area.step % 4 != 0)
return -EINVAL;
}
}
data = (adpcm_t *)plugin->extra_data;
data->func(plugin, src_voices, dst_voices, frames);
data->func(plugin, src_channels, dst_channels, frames);
return frames;
}
@ -378,7 +378,7 @@ static int adpcm_action(snd_pcm_plugin_t * plugin,
}
int snd_pcm_plugin_build_adpcm(snd_pcm_plugin_handle_t *handle,
int channel,
int stream,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
snd_pcm_plugin_t **r_plugin)
@ -395,7 +395,7 @@ int snd_pcm_plugin_build_adpcm(snd_pcm_plugin_handle_t *handle,
if (src_format->rate != dst_format->rate)
return -EINVAL;
if (src_format->voices != dst_format->voices)
if (src_format->channels != dst_format->channels)
return -EINVAL;
if (dst_format->format == SND_PCM_SFMT_IMA_ADPCM) {
@ -411,11 +411,11 @@ int snd_pcm_plugin_build_adpcm(snd_pcm_plugin_handle_t *handle,
if (!snd_pcm_format_linear(format->format))
return -EINVAL;
err = snd_pcm_plugin_build(handle, channel,
err = snd_pcm_plugin_build(handle, stream,
"Ima-ADPCM<->linear conversion",
src_format,
dst_format,
sizeof(adpcm_t) + src_format->voices * sizeof(adpcm_voice_t),
sizeof(adpcm_t) + src_format->channels * sizeof(adpcm_channel_t),
&plugin);
if (err < 0)
return err;

View file

@ -133,8 +133,8 @@ static int alaw2linear(unsigned char a_val)
*/
typedef void (*alaw_f)(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames);
typedef struct alaw_private_data {
@ -143,8 +143,8 @@ typedef struct alaw_private_data {
} alaw_t;
static void alaw_decode(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames)
{
#define PUT_S16_LABELS
@ -152,24 +152,24 @@ static void alaw_decode(snd_pcm_plugin_t *plugin,
#undef PUT_S16_LABELS
alaw_t *data = (alaw_t *)plugin->extra_data;
void *put = put_s16_labels[data->conv];
int voice;
int nvoices = plugin->src_format.voices;
for (voice = 0; voice < nvoices; ++voice) {
int channel;
int nchannels = plugin->src_format.channels;
for (channel = 0; channel < nchannels; ++channel) {
char *src;
char *dst;
int src_step, dst_step;
size_t frames1;
if (!src_voices[voice].enabled) {
if (dst_voices[voice].wanted)
snd_pcm_area_silence(&dst_voices[voice].area, 0, frames, plugin->dst_format.format);
dst_voices[voice].enabled = 0;
if (!src_channels[channel].enabled) {
if (dst_channels[channel].wanted)
snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
dst_channels[channel].enabled = 0;
continue;
}
dst_voices[voice].enabled = 1;
src = src_voices[voice].area.addr + src_voices[voice].area.first / 8;
dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
src_step = src_voices[voice].area.step / 8;
dst_step = dst_voices[voice].area.step / 8;
dst_channels[channel].enabled = 1;
src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
src_step = src_channels[channel].area.step / 8;
dst_step = dst_channels[channel].area.step / 8;
frames1 = frames;
while (frames1-- > 0) {
signed short sample = alaw2linear(*src);
@ -185,8 +185,8 @@ static void alaw_decode(snd_pcm_plugin_t *plugin,
}
static void alaw_encode(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames)
{
#define GET_S16_LABELS
@ -194,25 +194,25 @@ static void alaw_encode(snd_pcm_plugin_t *plugin,
#undef GET_S16_LABELS
alaw_t *data = (alaw_t *)plugin->extra_data;
void *get = get_s16_labels[data->conv];
int voice;
int nvoices = plugin->src_format.voices;
int channel;
int nchannels = plugin->src_format.channels;
signed short sample = 0;
for (voice = 0; voice < nvoices; ++voice) {
for (channel = 0; channel < nchannels; ++channel) {
char *src;
char *dst;
int src_step, dst_step;
size_t frames1;
if (!src_voices[voice].enabled) {
if (dst_voices[voice].wanted)
snd_pcm_area_silence(&dst_voices[voice].area, 0, frames, plugin->dst_format.format);
dst_voices[voice].enabled = 0;
if (!src_channels[channel].enabled) {
if (dst_channels[channel].wanted)
snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
dst_channels[channel].enabled = 0;
continue;
}
dst_voices[voice].enabled = 1;
src = src_voices[voice].area.addr + src_voices[voice].area.first / 8;
dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
src_step = src_voices[voice].area.step / 8;
dst_step = dst_voices[voice].area.step / 8;
dst_channels[channel].enabled = 1;
src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
src_step = src_channels[channel].area.step / 8;
dst_step = dst_channels[channel].area.step / 8;
frames1 = frames;
while (frames1-- > 0) {
goto *get;
@ -228,32 +228,32 @@ static void alaw_encode(snd_pcm_plugin_t *plugin,
}
static ssize_t alaw_transfer(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames)
{
alaw_t *data;
unsigned int voice;
unsigned int channel;
if (plugin == NULL || src_voices == NULL || dst_voices == NULL)
if (plugin == NULL || src_channels == NULL || dst_channels == NULL)
return -EFAULT;
if (frames == 0)
return 0;
for (voice = 0; voice < plugin->src_format.voices; voice++) {
if (src_voices[voice].area.first % 8 != 0 ||
src_voices[voice].area.step % 8 != 0)
for (channel = 0; channel < plugin->src_format.channels; channel++) {
if (src_channels[channel].area.first % 8 != 0 ||
src_channels[channel].area.step % 8 != 0)
return -EINVAL;
if (dst_voices[voice].area.first % 8 != 0 ||
dst_voices[voice].area.step % 8 != 0)
if (dst_channels[channel].area.first % 8 != 0 ||
dst_channels[channel].area.step % 8 != 0)
return -EINVAL;
}
data = (alaw_t *)plugin->extra_data;
data->func(plugin, src_voices, dst_voices, frames);
data->func(plugin, src_channels, dst_channels, frames);
return frames;
}
int snd_pcm_plugin_build_alaw(snd_pcm_plugin_handle_t *handle,
int channel,
int stream,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
snd_pcm_plugin_t **r_plugin)
@ -270,7 +270,7 @@ int snd_pcm_plugin_build_alaw(snd_pcm_plugin_handle_t *handle,
if (src_format->rate != dst_format->rate)
return -EINVAL;
if (src_format->voices != dst_format->voices)
if (src_format->channels != dst_format->channels)
return -EINVAL;
if (dst_format->format == SND_PCM_SFMT_A_LAW) {
@ -286,7 +286,7 @@ int snd_pcm_plugin_build_alaw(snd_pcm_plugin_handle_t *handle,
if (!snd_pcm_format_linear(format->format))
return -EINVAL;
err = snd_pcm_plugin_build(handle, channel,
err = snd_pcm_plugin_build(handle, stream,
"A-Law<->linear conversion",
src_format,
dst_format,

View file

@ -36,41 +36,41 @@
#endif
static ssize_t copy_transfer(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames)
{
unsigned int voice;
unsigned int nvoices;
unsigned int channel;
unsigned int nchannels;
if (plugin == NULL || src_voices == NULL || dst_voices == NULL)
if (plugin == NULL || src_channels == NULL || dst_channels == NULL)
return -EFAULT;
if (frames == 0)
return 0;
nvoices = plugin->src_format.voices;
for (voice = 0; voice < nvoices; voice++) {
if (src_voices->area.first % 8 != 0 ||
src_voices->area.step % 8 != 0)
nchannels = plugin->src_format.channels;
for (channel = 0; channel < nchannels; channel++) {
if (src_channels->area.first % 8 != 0 ||
src_channels->area.step % 8 != 0)
return -EINVAL;
if (dst_voices->area.first % 8 != 0 ||
dst_voices->area.step % 8 != 0)
if (dst_channels->area.first % 8 != 0 ||
dst_channels->area.step % 8 != 0)
return -EINVAL;
if (!src_voices->enabled) {
if (dst_voices->wanted)
snd_pcm_area_silence(&dst_voices->area, 0, frames, plugin->dst_format.format);
dst_voices->enabled = 0;
if (!src_channels->enabled) {
if (dst_channels->wanted)
snd_pcm_area_silence(&dst_channels->area, 0, frames, plugin->dst_format.format);
dst_channels->enabled = 0;
continue;
}
dst_voices->enabled = 1;
snd_pcm_area_copy(&src_voices->area, 0, &dst_voices->area, 0, frames, plugin->src_format.format);
src_voices++;
dst_voices++;
dst_channels->enabled = 1;
snd_pcm_area_copy(&src_channels->area, 0, &dst_channels->area, 0, frames, plugin->src_format.format);
src_channels++;
dst_channels++;
}
return frames;
}
int snd_pcm_plugin_build_copy(snd_pcm_plugin_handle_t *handle,
int channel,
int stream,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
snd_pcm_plugin_t **r_plugin)
@ -87,14 +87,14 @@ int snd_pcm_plugin_build_copy(snd_pcm_plugin_handle_t *handle,
return -EINVAL;
if (src_format->rate != dst_format->rate)
return -EINVAL;
if (src_format->voices != dst_format->voices)
if (src_format->channels != dst_format->channels)
return -EINVAL;
width = snd_pcm_format_physical_width(src_format->format);
if (width < 0)
return -EINVAL;
err = snd_pcm_plugin_build(handle, channel,
err = snd_pcm_plugin_build(handle, stream,
"copy",
src_format,
dst_format,

View file

@ -46,14 +46,14 @@ typedef struct io_private_data {
} io_t;
static ssize_t io_transfer(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames)
{
io_t *data;
ssize_t result;
struct iovec *vec;
int count, voice;
int count, channel;
if (plugin == NULL)
return -EINVAL;
@ -61,48 +61,48 @@ static ssize_t io_transfer(snd_pcm_plugin_t *plugin,
if (data == NULL)
return -EINVAL;
vec = (struct iovec *)((char *)data + sizeof(*data));
if (plugin->channel == SND_PCM_CHANNEL_PLAYBACK) {
if (src_voices == NULL)
if (plugin->stream == SND_PCM_STREAM_PLAYBACK) {
if (src_channels == NULL)
return -EINVAL;
if ((result = snd_pcm_plugin_src_frames_to_size(plugin, frames)) < 0)
return result;
count = plugin->src_format.voices;
count = plugin->src_format.channels;
if (plugin->src_format.interleave) {
result = snd_pcm_write(data->slave, src_voices->area.addr, result);
result = snd_pcm_write(data->slave, src_channels->area.addr, result);
} else {
result /= count;
for (voice = 0; voice < count; voice++) {
if (src_voices[voice].enabled)
vec[voice].iov_base = src_voices[voice].area.addr;
for (channel = 0; channel < count; channel++) {
if (src_channels[channel].enabled)
vec[channel].iov_base = src_channels[channel].area.addr;
else
vec[voice].iov_base = 0;
vec[voice].iov_len = result;
vec[channel].iov_base = 0;
vec[channel].iov_len = result;
}
result = snd_pcm_writev(data->slave, vec, count);
}
if (result < 0)
return result;
return snd_pcm_plugin_src_size_to_frames(plugin, result);
} else if (plugin->channel == SND_PCM_CHANNEL_CAPTURE) {
if (dst_voices == NULL)
} else if (plugin->stream == SND_PCM_STREAM_CAPTURE) {
if (dst_channels == NULL)
return -EINVAL;
if ((result = snd_pcm_plugin_dst_frames_to_size(plugin, frames)) < 0)
return result;
count = plugin->dst_format.voices;
count = plugin->dst_format.channels;
if (plugin->dst_format.interleave) {
result = snd_pcm_read(data->slave, dst_voices->area.addr, result);
for (voice = 0; voice < count; voice++) {
dst_voices[voice].enabled = src_voices[voice].enabled;
result = snd_pcm_read(data->slave, dst_channels->area.addr, result);
for (channel = 0; channel < count; channel++) {
dst_channels[channel].enabled = src_channels[channel].enabled;
}
} else {
result /= count;
for (voice = 0; voice < count; voice++) {
dst_voices[voice].enabled = src_voices[voice].enabled;
if (dst_voices[voice].enabled)
vec[voice].iov_base = dst_voices[voice].area.addr;
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[voice].iov_base = 0;
vec[voice].iov_len = result;
vec[channel].iov_base = 0;
vec[channel].iov_len = result;
}
result = snd_pcm_readv(data->slave, vec, count);
}
@ -114,24 +114,24 @@ static ssize_t io_transfer(snd_pcm_plugin_t *plugin,
}
}
static ssize_t io_src_voices(snd_pcm_plugin_t *plugin,
static ssize_t io_src_channels(snd_pcm_plugin_t *plugin,
size_t frames,
snd_pcm_plugin_voice_t **voices)
snd_pcm_plugin_channel_t **channels)
{
int err;
unsigned int voice;
snd_pcm_plugin_voice_t *v;
err = snd_pcm_plugin_client_voices(plugin, frames, &v);
unsigned int channel;
snd_pcm_plugin_channel_t *v;
err = snd_pcm_plugin_client_channels(plugin, frames, &v);
if (err < 0)
return err;
*voices = v;
for (voice = 0; voice < plugin->src_format.voices; ++voice, ++v)
*channels = v;
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 channel,
int stream,
snd_pcm_plugin_handle_t *slave,
snd_pcm_format_t *format,
snd_pcm_plugin_t **r_plugin)
@ -145,18 +145,18 @@ int snd_pcm_plugin_build_io(snd_pcm_plugin_handle_t *pcm,
*r_plugin = NULL;
if (pcm == NULL || format == NULL)
return -EINVAL;
err = snd_pcm_plugin_build(pcm, channel,
err = snd_pcm_plugin_build(pcm, stream,
"I/O io",
format, format,
sizeof(io_t) + sizeof(struct iovec) * format->voices,
sizeof(io_t) + 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 && channel == SND_PCM_CHANNEL_PLAYBACK)
plugin->client_voices = io_src_voices;
if (format->interleave && stream == SND_PCM_STREAM_PLAYBACK)
plugin->client_channels = io_src_channels;
*r_plugin = plugin;
return 0;
}

View file

@ -45,8 +45,8 @@ typedef struct linear_private_data {
} linear_t;
static void convert(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames)
{
#define CONV_LABELS
@ -54,24 +54,24 @@ static void convert(snd_pcm_plugin_t *plugin,
#undef CONV_LABELS
linear_t *data = (linear_t *)plugin->extra_data;
void *conv = conv_labels[data->conv];
int voice;
int nvoices = plugin->src_format.voices;
for (voice = 0; voice < nvoices; ++voice) {
int channel;
int nchannels = plugin->src_format.channels;
for (channel = 0; channel < nchannels; ++channel) {
char *src;
char *dst;
int src_step, dst_step;
size_t frames1;
if (!src_voices[voice].enabled) {
if (dst_voices[voice].wanted)
snd_pcm_area_silence(&dst_voices[voice].area, 0, frames, plugin->dst_format.format);
dst_voices[voice].enabled = 0;
if (!src_channels[channel].enabled) {
if (dst_channels[channel].wanted)
snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
dst_channels[channel].enabled = 0;
continue;
}
dst_voices[voice].enabled = 1;
src = src_voices[voice].area.addr + src_voices[voice].area.first / 8;
dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
src_step = src_voices[voice].area.step / 8;
dst_step = dst_voices[voice].area.step / 8;
dst_channels[channel].enabled = 1;
src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
src_step = src_channels[channel].area.step / 8;
dst_step = dst_channels[channel].area.step / 8;
frames1 = frames;
while (frames1-- > 0) {
goto *conv;
@ -86,27 +86,27 @@ static void convert(snd_pcm_plugin_t *plugin,
}
static ssize_t linear_transfer(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames)
{
linear_t *data;
unsigned int voice;
unsigned int channel;
if (plugin == NULL || src_voices == NULL || dst_voices == NULL)
if (plugin == NULL || src_channels == NULL || dst_channels == NULL)
return -EFAULT;
data = (linear_t *)plugin->extra_data;
if (frames == 0)
return 0;
for (voice = 0; voice < plugin->src_format.voices; voice++) {
if (src_voices[voice].area.first % 8 != 0 ||
src_voices[voice].area.step % 8 != 0)
for (channel = 0; channel < plugin->src_format.channels; channel++) {
if (src_channels[channel].area.first % 8 != 0 ||
src_channels[channel].area.step % 8 != 0)
return -EINVAL;
if (dst_voices[voice].area.first % 8 != 0 ||
dst_voices[voice].area.step % 8 != 0)
if (dst_channels[channel].area.first % 8 != 0 ||
dst_channels[channel].area.step % 8 != 0)
return -EINVAL;
}
convert(plugin, src_voices, dst_voices, frames);
convert(plugin, src_channels, dst_channels, frames);
return frames;
}
@ -138,7 +138,7 @@ int conv_index(int src_format, int dst_format)
}
int snd_pcm_plugin_build_linear(snd_pcm_plugin_handle_t *handle,
int channel,
int stream,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
snd_pcm_plugin_t **r_plugin)
@ -153,13 +153,13 @@ int snd_pcm_plugin_build_linear(snd_pcm_plugin_handle_t *handle,
if (src_format->rate != dst_format->rate)
return -EINVAL;
if (src_format->voices != dst_format->voices)
if (src_format->channels != dst_format->channels)
return -EINVAL;
if (!(snd_pcm_format_linear(src_format->format) &&
snd_pcm_format_linear(dst_format->format)))
return -EINVAL;
err = snd_pcm_plugin_build(handle, channel,
err = snd_pcm_plugin_build(handle, stream,
"linear format conversion",
src_format,
dst_format,

View file

@ -43,60 +43,60 @@ typedef struct mmap_private_data {
} mmap_t;
static ssize_t mmap_src_voices(snd_pcm_plugin_t *plugin,
static ssize_t mmap_src_channels(snd_pcm_plugin_t *plugin,
size_t frames,
snd_pcm_plugin_voice_t **voices)
snd_pcm_plugin_channel_t **channels)
{
mmap_t *data;
snd_pcm_plugin_voice_t *sv;
snd_pcm_voice_area_t *dv;
struct snd_pcm_chan *chan;
snd_pcm_channel_setup_t *setup;
snd_pcm_plugin_channel_t *sv;
snd_pcm_channel_area_t *dv;
struct snd_pcm_stream *stream;
snd_pcm_stream_setup_t *setup;
snd_pcm_mmap_control_t *ctrl;
size_t pos;
int ready;
unsigned int voice;
unsigned int channel;
if (plugin == NULL || voices == NULL)
if (plugin == NULL || channels == NULL)
return -EINVAL;
data = (mmap_t *)plugin->extra_data;
ctrl = data->control;
chan = &data->slave->chan[plugin->channel];
stream = &data->slave->stream[plugin->stream];
setup = &chan->setup;
setup = &stream->setup;
if (ctrl->status < SND_PCM_STATUS_PREPARED)
return -EBADFD;
ready = snd_pcm_mmap_ready(data->slave, plugin->channel);
ready = snd_pcm_mmap_ready(data->slave, plugin->stream);
if (ready < 0)
return ready;
if (!ready) {
struct pollfd pfd;
if (ctrl->status != SND_PCM_STATUS_RUNNING)
return -EPIPE;
if (chan->mode & SND_PCM_NONBLOCK)
if (stream->mode & SND_PCM_NONBLOCK)
return -EAGAIN;
pfd.fd = snd_pcm_file_descriptor(data->slave, plugin->channel);
pfd.fd = snd_pcm_file_descriptor(data->slave, plugin->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->channel));
assert(snd_pcm_mmap_ready(data->slave, plugin->stream));
}
pos = ctrl->byte_data % setup->buffer_size;
if ((pos * 8) % chan->bits_per_frame != 0)
if ((pos * 8) % stream->bits_per_frame != 0)
return -EINVAL;
pos = (pos * 8) / chan->bits_per_frame;
pos = (pos * 8) / stream->bits_per_frame;
sv = plugin->src_voices;
dv = chan->voices;
*voices = sv;
for (voice = 0; voice < plugin->src_format.voices; ++voice) {
sv = plugin->src_channels;
dv = stream->channels;
*channels = sv;
for (channel = 0; channel < plugin->src_format.channels; ++channel) {
sv->enabled = 1;
#if 0
sv->wanted = !data->silence[voice * setup->frags + f];
sv->wanted = !data->silence[channel * setup->frags + f];
#else
sv->wanted = 1;
#endif
@ -107,66 +107,66 @@ static ssize_t mmap_src_voices(snd_pcm_plugin_t *plugin,
++sv;
++dv;
}
return snd_pcm_mmap_frames_xfer(data->slave, plugin->channel, frames);
return snd_pcm_mmap_frames_xfer(data->slave, plugin->stream, frames);
}
static ssize_t mmap_dst_voices(snd_pcm_plugin_t *plugin,
static ssize_t mmap_dst_channels(snd_pcm_plugin_t *plugin,
size_t frames,
snd_pcm_plugin_voice_t **voices)
snd_pcm_plugin_channel_t **channels)
{
mmap_t *data;
int err;
unsigned int voice;
snd_pcm_plugin_voice_t *dv;
snd_pcm_voice_area_t *sv;
struct snd_pcm_chan *chan;
snd_pcm_channel_setup_t *setup;
unsigned int channel;
snd_pcm_plugin_channel_t *dv;
snd_pcm_channel_area_t *sv;
struct snd_pcm_stream *stream;
snd_pcm_stream_setup_t *setup;
snd_pcm_mmap_control_t *ctrl;
size_t pos;
int ready;
if (plugin == NULL || voices == NULL)
if (plugin == NULL || channels == NULL)
return -EINVAL;
data = (mmap_t *)plugin->extra_data;
chan = &data->slave->chan[plugin->channel];
stream = &data->slave->stream[plugin->stream];
setup = &chan->setup;
setup = &stream->setup;
ctrl = data->control;
if (ctrl->status < SND_PCM_STATUS_PREPARED)
return -EBADFD;
if (ctrl->status == SND_PCM_STATUS_PREPARED &&
chan->setup.start_mode == SND_PCM_START_DATA) {
err = snd_pcm_channel_go(data->slave, plugin->channel);
stream->setup.start_mode == SND_PCM_START_DATA) {
err = snd_pcm_stream_go(data->slave, plugin->stream);
if (err < 0)
return err;
}
ready = snd_pcm_mmap_ready(data->slave, plugin->channel);
ready = snd_pcm_mmap_ready(data->slave, plugin->stream);
if (ready < 0)
return ready;
if (!ready) {
struct pollfd pfd;
if (ctrl->status != SND_PCM_STATUS_RUNNING)
return -EPIPE;
if (chan->mode & SND_PCM_NONBLOCK)
if (stream->mode & SND_PCM_NONBLOCK)
return -EAGAIN;
pfd.fd = snd_pcm_file_descriptor(data->slave, plugin->channel);
pfd.fd = snd_pcm_file_descriptor(data->slave, plugin->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->channel));
assert(snd_pcm_mmap_ready(data->slave, plugin->stream));
}
pos = ctrl->byte_data % setup->buffer_size;
if ((pos * 8) % chan->bits_per_frame != 0)
if ((pos * 8) % stream->bits_per_frame != 0)
return -EINVAL;
pos = (pos * 8) / chan->bits_per_frame;
pos = (pos * 8) / stream->bits_per_frame;
sv = chan->voices;
dv = plugin->dst_voices;
*voices = dv;
for (voice = 0; voice < plugin->dst_format.voices; ++voice) {
sv = stream->channels;
dv = plugin->dst_channels;
*channels = dv;
for (channel = 0; channel < plugin->dst_format.channels; ++channel) {
dv->enabled = 1;
dv->wanted = 0;
dv->aptr = 0;
@ -176,46 +176,46 @@ static ssize_t mmap_dst_voices(snd_pcm_plugin_t *plugin,
++sv;
++dv;
}
return snd_pcm_mmap_frames_xfer(data->slave, plugin->channel, frames);
return snd_pcm_mmap_frames_xfer(data->slave, plugin->stream, frames);
}
static ssize_t mmap_playback_transfer(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices UNUSED,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels UNUSED,
size_t frames)
{
mmap_t *data;
snd_pcm_channel_setup_t *setup;
snd_pcm_stream_setup_t *setup;
snd_pcm_mmap_control_t *ctrl;
struct snd_pcm_chan *chan;
struct snd_pcm_stream *stream;
int err;
if (plugin == NULL)
return -EINVAL;
data = (mmap_t *)plugin->extra_data;
if (src_voices == NULL)
if (src_channels == NULL)
return -EINVAL;
if (plugin->prev == NULL)
return -EINVAL;
ctrl = data->control;
if (ctrl == NULL)
return -EINVAL;
chan = &data->slave->chan[SND_PCM_CHANNEL_PLAYBACK];
setup = &chan->setup;
stream = &data->slave->stream[SND_PCM_STREAM_PLAYBACK];
setup = &stream->setup;
#if 0
for (voice = 0; voice < plugin->src_format.voices; voice++) {
if (src_voices[voice].enabled)
data->silence[voice * setup->frags + f] = 0;
for (channel = 0; channel < plugin->src_format.channels; channel++) {
if (src_channels[channel].enabled)
data->silence[channel * setup->frags + f] = 0;
}
#endif
snd_pcm_mmap_commit_frames(data->slave, SND_PCM_CHANNEL_PLAYBACK, frames);
snd_pcm_mmap_commit_frames(data->slave, SND_PCM_STREAM_PLAYBACK, frames);
if (ctrl->status == SND_PCM_STATUS_PREPARED &&
(chan->setup.start_mode == SND_PCM_START_DATA ||
(chan->setup.start_mode == SND_PCM_START_FULL &&
!snd_pcm_mmap_ready(data->slave, plugin->channel)))) {
err = snd_pcm_channel_go(data->slave, plugin->channel);
(stream->setup.start_mode == SND_PCM_START_DATA ||
(stream->setup.start_mode == SND_PCM_START_FULL &&
!snd_pcm_mmap_ready(data->slave, plugin->stream)))) {
err = snd_pcm_stream_go(data->slave, plugin->stream);
if (err < 0)
return err;
}
@ -223,12 +223,12 @@ static ssize_t mmap_playback_transfer(snd_pcm_plugin_t *plugin,
}
static ssize_t mmap_capture_transfer(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices UNUSED,
snd_pcm_plugin_voice_t *dst_voices UNUSED,
const snd_pcm_plugin_channel_t *src_channels UNUSED,
snd_pcm_plugin_channel_t *dst_channels UNUSED,
size_t frames)
{
mmap_t *data;
snd_pcm_channel_setup_t *setup;
snd_pcm_stream_setup_t *setup;
snd_pcm_mmap_control_t *ctrl;
if (plugin == NULL)
@ -240,10 +240,10 @@ static ssize_t mmap_capture_transfer(snd_pcm_plugin_t *plugin,
ctrl = data->control;
if (ctrl == NULL)
return -EINVAL;
setup = &data->slave->chan[SND_PCM_CHANNEL_CAPTURE].setup;
setup = &data->slave->stream[SND_PCM_STREAM_CAPTURE].setup;
/* FIXME: not here the increment */
snd_pcm_mmap_commit_frames(data->slave, SND_PCM_CHANNEL_CAPTURE, frames);
snd_pcm_mmap_commit_frames(data->slave, SND_PCM_STREAM_CAPTURE, frames);
return frames;
}
@ -257,20 +257,20 @@ static int mmap_action(snd_pcm_plugin_t *plugin,
return -EINVAL;
data = (mmap_t *)plugin->extra_data;
if (action == INIT) {
snd_pcm_channel_setup_t *setup;
snd_pcm_stream_setup_t *setup;
int result;
if (data->control)
snd_pcm_munmap(data->slave, plugin->channel);
result = snd_pcm_mmap(data->slave, plugin->channel, &data->control, (void **)&data->buffer);
snd_pcm_munmap(data->slave, plugin->stream);
result = snd_pcm_mmap(data->slave, plugin->stream, &data->control, (void **)&data->buffer);
if (result < 0)
return result;
setup = &data->slave->chan[plugin->channel].setup;
setup = &data->slave->stream[plugin->stream].setup;
#if 0
if (plugin->channel == SND_PCM_CHANNEL_PLAYBACK) {
data->silence = malloc(setup->frags * setup->format.voices);
memset(data->silence, 0, setup->frags * setup->format.voices);
if (plugin->stream == SND_PCM_STREAM_PLAYBACK) {
data->silence = malloc(setup->frags * setup->format.channels);
memset(data->silence, 0, setup->frags * setup->format.channels);
} else
data->silence = 0;
#endif
@ -291,11 +291,11 @@ static void mmap_free(snd_pcm_plugin_t *plugin, void *private_data UNUSED)
free(data->silence);
#endif
if (data->control)
snd_pcm_munmap(data->slave, plugin->channel);
snd_pcm_munmap(data->slave, plugin->stream);
}
int snd_pcm_plugin_build_mmap(snd_pcm_plugin_handle_t *pcm,
int channel,
int stream,
snd_pcm_t *slave,
snd_pcm_format_t *format,
snd_pcm_plugin_t **r_plugin)
@ -309,20 +309,20 @@ int snd_pcm_plugin_build_mmap(snd_pcm_plugin_handle_t *pcm,
*r_plugin = NULL;
if (!pcm)
return -EINVAL;
err = snd_pcm_plugin_build(pcm, channel,
err = snd_pcm_plugin_build(pcm, stream,
"I/O mmap",
format, format,
sizeof(mmap_t) + sizeof(snd_pcm_plugin_voice_t) * format->voices,
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 (channel == SND_PCM_CHANNEL_PLAYBACK) {
plugin->client_voices = mmap_src_voices;
if (stream == SND_PCM_STREAM_PLAYBACK) {
plugin->client_channels = mmap_src_channels;
plugin->transfer = mmap_playback_transfer;
} else {
plugin->client_voices = mmap_dst_voices;
plugin->client_channels = mmap_dst_channels;
plugin->transfer = mmap_capture_transfer;
}
plugin->action = mmap_action;

View file

@ -149,8 +149,8 @@ static int ulaw2linear(unsigned char u_val)
*/
typedef void (*mulaw_f)(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames);
typedef struct mulaw_private_data {
@ -159,8 +159,8 @@ typedef struct mulaw_private_data {
} mulaw_t;
static void mulaw_decode(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames)
{
#define PUT_S16_LABELS
@ -168,24 +168,24 @@ static void mulaw_decode(snd_pcm_plugin_t *plugin,
#undef PUT_S16_LABELS
mulaw_t *data = (mulaw_t *)plugin->extra_data;
void *put = put_s16_labels[data->conv];
int voice;
int nvoices = plugin->src_format.voices;
for (voice = 0; voice < nvoices; ++voice) {
int channel;
int nchannels = plugin->src_format.channels;
for (channel = 0; channel < nchannels; ++channel) {
char *src;
char *dst;
int src_step, dst_step;
size_t frames1;
if (!src_voices[voice].enabled) {
if (dst_voices[voice].wanted)
snd_pcm_area_silence(&dst_voices[voice].area, 0, frames, plugin->dst_format.format);
dst_voices[voice].enabled = 0;
if (!src_channels[channel].enabled) {
if (dst_channels[channel].wanted)
snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
dst_channels[channel].enabled = 0;
continue;
}
dst_voices[voice].enabled = 1;
src = src_voices[voice].area.addr + src_voices[voice].area.first / 8;
dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
src_step = src_voices[voice].area.step / 8;
dst_step = dst_voices[voice].area.step / 8;
dst_channels[channel].enabled = 1;
src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
src_step = src_channels[channel].area.step / 8;
dst_step = dst_channels[channel].area.step / 8;
frames1 = frames;
while (frames1-- > 0) {
signed short sample = ulaw2linear(*src);
@ -201,8 +201,8 @@ static void mulaw_decode(snd_pcm_plugin_t *plugin,
}
static void mulaw_encode(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames)
{
#define GET_S16_LABELS
@ -210,25 +210,25 @@ static void mulaw_encode(snd_pcm_plugin_t *plugin,
#undef GET_S16_LABELS
mulaw_t *data = (mulaw_t *)plugin->extra_data;
void *get = get_s16_labels[data->conv];
int voice;
int nvoices = plugin->src_format.voices;
int channel;
int nchannels = plugin->src_format.channels;
signed short sample = 0;
for (voice = 0; voice < nvoices; ++voice) {
for (channel = 0; channel < nchannels; ++channel) {
char *src;
char *dst;
int src_step, dst_step;
size_t frames1;
if (!src_voices[voice].enabled) {
if (dst_voices[voice].wanted)
snd_pcm_area_silence(&dst_voices[voice].area, 0, frames, plugin->dst_format.format);
dst_voices[voice].enabled = 0;
if (!src_channels[channel].enabled) {
if (dst_channels[channel].wanted)
snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
dst_channels[channel].enabled = 0;
continue;
}
dst_voices[voice].enabled = 1;
src = src_voices[voice].area.addr + src_voices[voice].area.first / 8;
dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
src_step = src_voices[voice].area.step / 8;
dst_step = dst_voices[voice].area.step / 8;
dst_channels[channel].enabled = 1;
src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
src_step = src_channels[channel].area.step / 8;
dst_step = dst_channels[channel].area.step / 8;
frames1 = frames;
while (frames1-- > 0) {
goto *get;
@ -244,32 +244,32 @@ static void mulaw_encode(snd_pcm_plugin_t *plugin,
}
static ssize_t mulaw_transfer(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames)
{
mulaw_t *data;
unsigned int voice;
unsigned int channel;
if (plugin == NULL || src_voices == NULL || dst_voices == NULL)
if (plugin == NULL || src_channels == NULL || dst_channels == NULL)
return -EFAULT;
if (frames == 0)
return 0;
for (voice = 0; voice < plugin->src_format.voices; voice++) {
if (src_voices[voice].area.first % 8 != 0 ||
src_voices[voice].area.step % 8 != 0)
for (channel = 0; channel < plugin->src_format.channels; channel++) {
if (src_channels[channel].area.first % 8 != 0 ||
src_channels[channel].area.step % 8 != 0)
return -EINVAL;
if (dst_voices[voice].area.first % 8 != 0 ||
dst_voices[voice].area.step % 8 != 0)
if (dst_channels[channel].area.first % 8 != 0 ||
dst_channels[channel].area.step % 8 != 0)
return -EINVAL;
}
data = (mulaw_t *)plugin->extra_data;
data->func(plugin, src_voices, dst_voices, frames);
data->func(plugin, src_channels, dst_channels, frames);
return frames;
}
int snd_pcm_plugin_build_mulaw(snd_pcm_plugin_handle_t *handle,
int channel,
int stream,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
snd_pcm_plugin_t **r_plugin)
@ -286,7 +286,7 @@ int snd_pcm_plugin_build_mulaw(snd_pcm_plugin_handle_t *handle,
if (src_format->rate != dst_format->rate)
return -EINVAL;
if (src_format->voices != dst_format->voices)
if (src_format->channels != dst_format->channels)
return -EINVAL;
if (dst_format->format == SND_PCM_SFMT_MU_LAW) {
@ -302,7 +302,7 @@ int snd_pcm_plugin_build_mulaw(snd_pcm_plugin_handle_t *handle,
if (!snd_pcm_format_linear(format->format))
return -EINVAL;
err = snd_pcm_plugin_build(handle, channel,
err = snd_pcm_plugin_build(handle, stream,
"Mu-Law<->linear conversion",
src_format,
dst_format,

View file

@ -45,11 +45,11 @@
typedef struct {
signed short last_S1;
signed short last_S2;
} rate_voice_t;
} rate_channel_t;
typedef void (*rate_f)(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
int src_frames, int dst_frames);
typedef struct rate_private_data {
@ -58,34 +58,34 @@ typedef struct rate_private_data {
rate_f func;
int get, put;
ssize_t old_src_frames, old_dst_frames;
rate_voice_t voices[0];
rate_channel_t channels[0];
} rate_t;
static void rate_init(snd_pcm_plugin_t *plugin)
{
unsigned int voice;
unsigned int channel;
rate_t *data = (rate_t *)plugin->extra_data;
data->pos = 0;
for (voice = 0; voice < plugin->src_format.voices; voice++) {
data->voices[voice].last_S1 = 0;
data->voices[voice].last_S2 = 0;
for (channel = 0; channel < plugin->src_format.channels; channel++) {
data->channels[channel].last_S1 = 0;
data->channels[channel].last_S2 = 0;
}
}
static void resample_expand(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
int src_frames, int dst_frames)
{
unsigned int pos = 0;
signed int val;
signed short S1, S2;
char *src, *dst;
unsigned int voice;
unsigned int channel;
int src_step, dst_step;
int src_frames1, dst_frames1;
rate_t *data = (rate_t *)plugin->extra_data;
rate_voice_t *rvoices = data->voices;
rate_channel_t *rchannels = data->channels;
#define GET_S16_LABELS
#define PUT_S16_LABELS
@ -100,21 +100,21 @@ static void resample_expand(snd_pcm_plugin_t *plugin,
#include "plugin_ops.h"
#undef GET_S16_END
for (voice = 0; voice < plugin->src_format.voices; voice++, rvoices++) {
for (channel = 0; channel < plugin->src_format.channels; channel++, rchannels++) {
pos = data->pos;
S1 = rvoices->last_S1;
S2 = rvoices->last_S2;
if (!src_voices[voice].enabled) {
if (dst_voices[voice].wanted)
snd_pcm_area_silence(&dst_voices[voice].area, 0, dst_frames, plugin->dst_format.format);
dst_voices[voice].enabled = 0;
S1 = rchannels->last_S1;
S2 = rchannels->last_S2;
if (!src_channels[channel].enabled) {
if (dst_channels[channel].wanted)
snd_pcm_area_silence(&dst_channels[channel].area, 0, dst_frames, plugin->dst_format.format);
dst_channels[channel].enabled = 0;
continue;
}
dst_voices[voice].enabled = 1;
src = (char *)src_voices[voice].area.addr + src_voices[voice].area.first / 8;
dst = (char *)dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
src_step = src_voices[voice].area.step / 8;
dst_step = dst_voices[voice].area.step / 8;
dst_channels[channel].enabled = 1;
src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8;
dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
src_step = src_channels[channel].area.step / 8;
dst_step = dst_channels[channel].area.step / 8;
src_frames1 = src_frames;
dst_frames1 = dst_frames;
if (pos & ~MASK) {
@ -153,27 +153,27 @@ static void resample_expand(snd_pcm_plugin_t *plugin,
dst += dst_step;
pos += data->pitch;
}
rvoices->last_S1 = S1;
rvoices->last_S2 = S2;
rvoices++;
rchannels->last_S1 = S1;
rchannels->last_S2 = S2;
rchannels++;
}
data->pos = pos;
}
static void resample_shrink(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
int src_frames, int dst_frames)
{
unsigned int pos = 0;
signed int val;
signed short S1, S2;
char *src, *dst;
unsigned int voice;
unsigned int channel;
int src_step, dst_step;
int src_frames1, dst_frames1;
rate_t *data = (rate_t *)plugin->extra_data;
rate_voice_t *rvoices = data->voices;
rate_channel_t *rchannels = data->channels;
#define GET_S16_LABELS
#define PUT_S16_LABELS
@ -184,21 +184,21 @@ static void resample_shrink(snd_pcm_plugin_t *plugin,
void *put = put_s16_labels[data->put];
signed short sample = 0;
for (voice = 0; voice < plugin->src_format.voices; ++voice) {
for (channel = 0; channel < plugin->src_format.channels; ++channel) {
pos = data->pos;
S1 = rvoices->last_S1;
S2 = rvoices->last_S2;
if (!src_voices[voice].enabled) {
if (dst_voices[voice].wanted)
snd_pcm_area_silence(&dst_voices[voice].area, 0, dst_frames, plugin->dst_format.format);
dst_voices[voice].enabled = 0;
S1 = rchannels->last_S1;
S2 = rchannels->last_S2;
if (!src_channels[channel].enabled) {
if (dst_channels[channel].wanted)
snd_pcm_area_silence(&dst_channels[channel].area, 0, dst_frames, plugin->dst_format.format);
dst_channels[channel].enabled = 0;
continue;
}
dst_voices[voice].enabled = 1;
src = (char *)src_voices[voice].area.addr + src_voices[voice].area.first / 8;
dst = (char *)dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
src_step = src_voices[voice].area.step / 8;
dst_step = dst_voices[voice].area.step / 8;
dst_channels[channel].enabled = 1;
src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8;
dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
src_step = src_channels[channel].area.step / 8;
dst_step = dst_channels[channel].area.step / 8;
src_frames1 = src_frames;
dst_frames1 = dst_frames;
while (dst_frames1 > 0) {
@ -230,9 +230,9 @@ static void resample_shrink(snd_pcm_plugin_t *plugin,
}
pos += data->pitch;
}
rvoices->last_S1 = S1;
rvoices->last_S2 = S2;
rvoices++;
rchannels->last_S1 = S1;
rchannels->last_S2 = S2;
rchannels++;
}
data->pos = pos;
}
@ -300,30 +300,30 @@ static ssize_t rate_dst_frames(snd_pcm_plugin_t *plugin, size_t frames)
}
static ssize_t rate_transfer(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames)
{
size_t dst_frames;
unsigned int voice;
unsigned int channel;
rate_t *data;
if (plugin == NULL || src_voices == NULL || dst_voices == NULL)
if (plugin == NULL || src_channels == NULL || dst_channels == NULL)
return -EFAULT;
if (frames == 0)
return 0;
for (voice = 0; voice < plugin->src_format.voices; voice++) {
if (src_voices[voice].area.first % 8 != 0 ||
src_voices[voice].area.step % 8 != 0)
for (channel = 0; channel < plugin->src_format.channels; channel++) {
if (src_channels[channel].area.first % 8 != 0 ||
src_channels[channel].area.step % 8 != 0)
return -EINVAL;
if (dst_voices[voice].area.first % 8 != 0 ||
dst_voices[voice].area.step % 8 != 0)
if (dst_channels[channel].area.first % 8 != 0 ||
dst_channels[channel].area.step % 8 != 0)
return -EINVAL;
}
dst_frames = rate_dst_frames(plugin, frames);
data = (rate_t *)plugin->extra_data;
data->func(plugin, src_voices, dst_voices, frames, dst_frames);
data->func(plugin, src_channels, dst_channels, frames, dst_frames);
return dst_frames;
}
@ -347,7 +347,7 @@ static int rate_action(snd_pcm_plugin_t *plugin,
}
int snd_pcm_plugin_build_rate(snd_pcm_plugin_handle_t *handle,
int channel,
int stream,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
snd_pcm_plugin_t **r_plugin)
@ -360,9 +360,9 @@ int snd_pcm_plugin_build_rate(snd_pcm_plugin_handle_t *handle,
return -EINVAL;
*r_plugin = NULL;
if (src_format->voices != dst_format->voices)
if (src_format->channels != dst_format->channels)
return -EINVAL;
if (src_format->voices < 1)
if (src_format->channels < 1)
return -EINVAL;
if (snd_pcm_format_linear(src_format->format) <= 0)
return -EINVAL;
@ -371,11 +371,11 @@ int snd_pcm_plugin_build_rate(snd_pcm_plugin_handle_t *handle,
if (src_format->rate == dst_format->rate)
return -EINVAL;
err = snd_pcm_plugin_build(handle, channel,
err = snd_pcm_plugin_build(handle, stream,
"rate conversion",
src_format,
dst_format,
sizeof(rate_t) + src_format->voices * sizeof(rate_voice_t),
sizeof(rate_t) + src_format->channels * sizeof(rate_channel_t),
&plugin);
if (err < 0)
return err;

View file

@ -47,13 +47,13 @@
typedef struct ttable_dst ttable_dst_t;
typedef struct route_private_data route_t;
typedef void (*route_voice_f)(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voice,
typedef void (*route_channel_f)(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channel,
ttable_dst_t* ttable, size_t frames);
typedef struct {
int voice;
int channel;
int as_int;
#if ROUTE_PLUGIN_USE_FLOAT
float as_float;
@ -64,7 +64,7 @@ struct ttable_dst {
int att; /* Attenuated */
int nsrcs;
ttable_src_t* srcs;
route_voice_f func;
route_channel_f func;
};
struct route_private_data {
@ -84,19 +84,19 @@ typedef union {
} sum_t;
static void route_to_voice_from_zero(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices UNUSED,
snd_pcm_plugin_voice_t *dst_voice,
static void route_to_channel_from_zero(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_channel_t *src_channels UNUSED,
snd_pcm_plugin_channel_t *dst_channel,
ttable_dst_t* ttable UNUSED, size_t frames)
{
if (dst_voice->wanted)
snd_pcm_area_silence(&dst_voice->area, 0, frames, plugin->dst_format.format);
dst_voice->enabled = 0;
if (dst_channel->wanted)
snd_pcm_area_silence(&dst_channel->area, 0, frames, plugin->dst_format.format);
dst_channel->enabled = 0;
}
static void route_to_voice_from_one(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voice,
static void route_to_channel_from_one(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channel,
ttable_dst_t* ttable, size_t frames)
{
#define CONV_LABELS
@ -104,26 +104,26 @@ static void route_to_voice_from_one(snd_pcm_plugin_t *plugin,
#undef CONV_LABELS
route_t *data = (route_t *)plugin->extra_data;
void *conv;
const snd_pcm_plugin_voice_t *src_voice = 0;
const snd_pcm_plugin_channel_t *src_channel = 0;
int srcidx;
char *src, *dst;
int src_step, dst_step;
for (srcidx = 0; srcidx < ttable->nsrcs; ++srcidx) {
src_voice = &src_voices[ttable->srcs[srcidx].voice];
if (src_voice->area.addr != NULL)
src_channel = &src_channels[ttable->srcs[srcidx].channel];
if (src_channel->area.addr != NULL)
break;
}
if (srcidx == ttable->nsrcs) {
route_to_voice_from_zero(plugin, src_voices, dst_voice, ttable, frames);
route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames);
return;
}
dst_voice->enabled = 1;
dst_channel->enabled = 1;
conv = conv_labels[data->conv];
src = src_voice->area.addr + src_voice->area.first / 8;
src_step = src_voice->area.step / 8;
dst = dst_voice->area.addr + dst_voice->area.first / 8;
dst_step = dst_voice->area.step / 8;
src = src_channel->area.addr + src_channel->area.first / 8;
src_step = src_channel->area.step / 8;
dst = dst_channel->area.addr + dst_channel->area.first / 8;
dst_step = dst_channel->area.step / 8;
while (frames-- > 0) {
goto *conv;
#define CONV_END after
@ -135,9 +135,9 @@ static void route_to_voice_from_one(snd_pcm_plugin_t *plugin,
}
}
static void route_to_voice(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voice,
static void route_to_channel(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channel,
ttable_dst_t* ttable, size_t frames)
{
#define GET_U_LABELS
@ -196,31 +196,31 @@ static void route_to_voice(snd_pcm_plugin_t *plugin,
u_int32_t sample = 0;
int srcidx, srcidx1 = 0;
for (srcidx = 0; srcidx < nsrcs; ++srcidx) {
const snd_pcm_plugin_voice_t *src_voice = &src_voices[ttable->srcs[srcidx].voice];
if (!src_voice->enabled)
const snd_pcm_plugin_channel_t *src_channel = &src_channels[ttable->srcs[srcidx].channel];
if (!src_channel->enabled)
continue;
srcs[srcidx1] = src_voice->area.addr + src_voices->area.first / 8;
src_steps[srcidx1] = src_voice->area.step / 8;
srcs[srcidx1] = src_channel->area.addr + src_channels->area.first / 8;
src_steps[srcidx1] = src_channel->area.step / 8;
src_tt[srcidx1] = ttable->srcs[srcidx];
srcidx1++;
}
nsrcs = srcidx1;
if (nsrcs == 0) {
route_to_voice_from_zero(plugin, src_voices, dst_voice, ttable, frames);
route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames);
return;
} else if (nsrcs == 1 && src_tt[0].as_int == ROUTE_PLUGIN_RESOLUTION) {
route_to_voice_from_one(plugin, src_voices, dst_voice, ttable, frames);
route_to_channel_from_one(plugin, src_channels, dst_channel, ttable, frames);
return;
}
dst_voice->enabled = 1;
dst_channel->enabled = 1;
zero = zero_labels[data->sum_type];
get = get_u_labels[data->get];
add = add_labels[data->sum_type * 2 + ttable->att];
norm = norm_labels[data->sum_type * 8 + ttable->att * 4 + 4 - data->src_sample_size];
put_u32 = put_u32_labels[data->put];
dst = dst_voice->area.addr + dst_voice->area.first / 8;
dst_step = dst_voice->area.step / 8;
dst = dst_channel->area.addr + dst_channel->area.first / 8;
dst_step = dst_channel->area.step / 8;
while (frames-- > 0) {
ttable_src_t *ttp = src_tt;
@ -361,47 +361,47 @@ static void route_to_voice(snd_pcm_plugin_t *plugin,
}
}
int route_src_voices_mask(snd_pcm_plugin_t *plugin,
int route_src_channels_mask(snd_pcm_plugin_t *plugin,
bitset_t *dst_vmask,
bitset_t **src_vmask)
{
route_t *data = (route_t *)plugin->extra_data;
int svoices = plugin->src_format.voices;
int dvoices = plugin->dst_format.voices;
int schannels = plugin->src_format.channels;
int dchannels = plugin->dst_format.channels;
bitset_t *vmask = plugin->src_vmask;
int voice;
int channel;
ttable_dst_t *dp = data->ttable;
bitset_zero(vmask, svoices);
for (voice = 0; voice < dvoices; voice++, dp++) {
bitset_zero(vmask, schannels);
for (channel = 0; channel < dchannels; channel++, dp++) {
int src;
ttable_src_t *sp;
if (!bitset_get(dst_vmask, voice))
if (!bitset_get(dst_vmask, channel))
continue;
sp = dp->srcs;
for (src = 0; src < dp->nsrcs; src++, sp++)
bitset_set(vmask, sp->voice);
bitset_set(vmask, sp->channel);
}
*src_vmask = vmask;
return 0;
}
int route_dst_voices_mask(snd_pcm_plugin_t *plugin,
int route_dst_channels_mask(snd_pcm_plugin_t *plugin,
bitset_t *src_vmask,
bitset_t **dst_vmask)
{
route_t *data = (route_t *)plugin->extra_data;
int dvoices = plugin->dst_format.voices;
int dchannels = plugin->dst_format.channels;
bitset_t *vmask = plugin->dst_vmask;
int voice;
int channel;
ttable_dst_t *dp = data->ttable;
bitset_zero(vmask, dvoices);
for (voice = 0; voice < dvoices; voice++, dp++) {
bitset_zero(vmask, dchannels);
for (channel = 0; channel < dchannels; channel++, dp++) {
int src;
ttable_src_t *sp;
sp = dp->srcs;
for (src = 0; src < dp->nsrcs; src++, sp++) {
if (bitset_get(src_vmask, sp->voice)) {
bitset_set(vmask, voice);
if (bitset_get(src_vmask, sp->channel)) {
bitset_set(vmask, channel);
break;
}
}
@ -413,10 +413,10 @@ int route_dst_voices_mask(snd_pcm_plugin_t *plugin,
static void route_free(snd_pcm_plugin_t *plugin, void* private_data UNUSED)
{
route_t *data = (route_t *)plugin->extra_data;
unsigned int dst_voice;
for (dst_voice = 0; dst_voice < plugin->dst_format.voices; ++dst_voice) {
if (data->ttable[dst_voice].srcs != NULL)
free(data->ttable[dst_voice].srcs);
unsigned int dst_channel;
for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) {
if (data->ttable[dst_channel].srcs != NULL)
free(data->ttable[dst_channel].srcs);
}
}
@ -424,7 +424,7 @@ static int route_load_ttable(snd_pcm_plugin_t *plugin,
const route_ttable_entry_t* src_ttable)
{
route_t *data;
unsigned int src_voice, dst_voice;
unsigned int src_channel, dst_channel;
const route_ttable_entry_t *sptr;
ttable_dst_t *dptr;
if (src_ttable == NULL)
@ -433,16 +433,16 @@ static int route_load_ttable(snd_pcm_plugin_t *plugin,
dptr = data->ttable;
sptr = src_ttable;
plugin->private_free = route_free;
for (dst_voice = 0; dst_voice < plugin->dst_format.voices; ++dst_voice) {
for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) {
route_ttable_entry_t t = 0;
int att = 0;
int nsrcs = 0;
ttable_src_t srcs[plugin->src_format.voices];
for (src_voice = 0; src_voice < plugin->src_format.voices; ++src_voice) {
ttable_src_t srcs[plugin->src_format.channels];
for (src_channel = 0; src_channel < plugin->src_format.channels; ++src_channel) {
if (*sptr < 0 || *sptr > FULL)
return -EINVAL;
if (*sptr != 0) {
srcs[nsrcs].voice = src_voice;
srcs[nsrcs].channel = src_channel;
#if ROUTE_PLUGIN_USE_FLOAT
/* Also in user space for non attenuated */
srcs[nsrcs].as_int = (*sptr == FULL ? ROUTE_PLUGIN_RESOLUTION : 0);
@ -465,13 +465,13 @@ static int route_load_ttable(snd_pcm_plugin_t *plugin,
dptr->nsrcs = nsrcs;
switch (nsrcs) {
case 0:
dptr->func = route_to_voice_from_zero;
dptr->func = route_to_channel_from_zero;
break;
case 1:
dptr->func = route_to_voice_from_one;
dptr->func = route_to_channel_from_one;
break;
default:
dptr->func = route_to_voice;
dptr->func = route_to_channel;
break;
}
if (nsrcs > 0) {
@ -485,40 +485,40 @@ static int route_load_ttable(snd_pcm_plugin_t *plugin,
}
static ssize_t route_transfer(snd_pcm_plugin_t *plugin,
const snd_pcm_plugin_voice_t *src_voices,
snd_pcm_plugin_voice_t *dst_voices,
const snd_pcm_plugin_channel_t *src_channels,
snd_pcm_plugin_channel_t *dst_channels,
size_t frames)
{
route_t *data;
int src_nvoices, dst_nvoices;
int src_voice, dst_voice;
int src_nchannels, dst_nchannels;
int src_channel, dst_channel;
ttable_dst_t *ttp;
snd_pcm_plugin_voice_t *dvp;
snd_pcm_plugin_channel_t *dvp;
if (plugin == NULL || src_voices == NULL || dst_voices == NULL)
if (plugin == NULL || src_channels == NULL || dst_channels == NULL)
return -EFAULT;
if (frames == 0)
return 0;
data = (route_t *)plugin->extra_data;
src_nvoices = plugin->src_format.voices;
for (src_voice = 0; src_voice < src_nvoices; ++src_voice) {
if (src_voices[src_voice].area.first % 8 != 0 ||
src_voices[src_voice].area.step % 8 != 0)
src_nchannels = plugin->src_format.channels;
for (src_channel = 0; src_channel < src_nchannels; ++src_channel) {
if (src_channels[src_channel].area.first % 8 != 0 ||
src_channels[src_channel].area.step % 8 != 0)
return -EINVAL;
}
dst_nvoices = plugin->dst_format.voices;
for (dst_voice = 0; dst_voice < dst_nvoices; ++dst_voice) {
if (dst_voices[dst_voice].area.first % 8 != 0 ||
dst_voices[dst_voice].area.step % 8 != 0)
dst_nchannels = plugin->dst_format.channels;
for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) {
if (dst_channels[dst_channel].area.first % 8 != 0 ||
dst_channels[dst_channel].area.step % 8 != 0)
return -EINVAL;
}
ttp = data->ttable;
dvp = dst_voices;
for (dst_voice = 0; dst_voice < dst_nvoices; ++dst_voice) {
ttp->func(plugin, src_voices, dvp, ttp, frames);
dvp = dst_channels;
for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) {
ttp->func(plugin, src_channels, dvp, ttp, frames);
dvp++;
ttp++;
}
@ -543,7 +543,7 @@ int getput_index(int format)
}
int snd_pcm_plugin_build_route(snd_pcm_plugin_handle_t *handle,
int channel,
int stream,
snd_pcm_format_t *src_format,
snd_pcm_format_t *dst_format,
route_ttable_entry_t *ttable,
@ -562,11 +562,11 @@ int snd_pcm_plugin_build_route(snd_pcm_plugin_handle_t *handle,
snd_pcm_format_linear(dst_format->format)))
return -EINVAL;
err = snd_pcm_plugin_build(handle, channel,
err = snd_pcm_plugin_build(handle, stream,
"attenuated route conversion",
src_format,
dst_format,
sizeof(route_t) + sizeof(data->ttable[0]) * dst_format->voices,
sizeof(route_t) + sizeof(data->ttable[0]) * dst_format->channels,
&plugin);
if (err < 0)
return err;
@ -592,8 +592,8 @@ int snd_pcm_plugin_build_route(snd_pcm_plugin_handle_t *handle,
return err;
}
plugin->transfer = route_transfer;
plugin->src_voices_mask = route_src_voices_mask;
plugin->dst_voices_mask = route_dst_voices_mask;
plugin->src_channels_mask = route_src_channels_mask;
plugin->dst_channels_mask = route_dst_channels_mask;
*r_plugin = plugin;
return 0;
}