mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-12-20 08:56:54 -05:00
Better names for ALSA API. Added min_fragments, max_fragments.
This commit is contained in:
parent
4bb0a08bf9
commit
1a7f88d10e
26 changed files with 1938 additions and 1938 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue