From 6aabe84a5e40d1fdc0515d361ccbd91a216ba2f5 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 6 Dec 1999 00:01:26 +0000 Subject: [PATCH] Abramo Bagnara Sun, 05 Dec 1999 19:02:01 +0100 Bug fixed: - duplicated deallocation for mmap'ed area - missing deallocation in es18xx - some bugs in volbal conversion New features: - virtual mixer for card-share (it seems to work, but I feel that it need further testing) Misc: - reorganization and extension of rate.c Jaroslav changes: - volbal source is mostly reverted back (no card-share mixer polling) --- include/pcm.h | 2 +- src/pcm/plugin/rate.c | 134 +++++++++++++--------------------------- src/pcm/plugin/volbal.c | 92 ++++++++++++++------------- 3 files changed, 88 insertions(+), 140 deletions(-) diff --git a/include/pcm.h b/include/pcm.h index 13b8c9da..b58f5c1b 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -146,7 +146,7 @@ int snd_pcm_plugin_build_voices(snd_pcm_format_t *src_format, int snd_pcm_plugin_build_volbal(snd_pcm_format_t *src_format, snd_pcm_format_t *dst_format, int *ttable, - snd_pcm_plugin_t **r_plugin); + snd_pcm_plugin_t **r_plugin); /* * Loopback interface diff --git a/src/pcm/plugin/rate.c b/src/pcm/plugin/rate.c index af849895..85814d7e 100644 --- a/src/pcm/plugin/rate.c +++ b/src/pcm/plugin/rate.c @@ -31,6 +31,7 @@ #define SHIFT 11 #define BITS (1<pos; - L_S1 = data->last_L_S1; - L_S2 = data->last_L_S2; - if (pos >> SHIFT) { - src_ptr += ((pos >> SHIFT) - 1); pos &= MASK; - L_S1 = L_S2; - L_S2 = *src_ptr; - } - while (dst_size-- > 0) { - if (pos >> SHIFT) { - src_ptr += (pos >> SHIFT); pos &= MASK; - L_S1 = L_S2; - L_S2 = *src_ptr; - } - - val = L_S1 + ((L_S2 - L_S1) * (signed int)pos) / BITS; - if (val < -32768) - val = -32768; - else if (val > 32767) - val = 32767; - *dst_ptr++ = val; - - pos += data->pitch; - } - data->last_L_S1 = L_S1; - data->last_L_S2 = L_S2; - data->pos = pos; -} -static void mix_stereo(struct rate_private_data *data, - signed short *src_ptr, int src_size, - signed short *dst_ptr, int dst_size) +static void mix(struct rate_private_data *data, int voices, + signed short *src_ptr, int src_size, + signed short *dst_ptr, int dst_size) { unsigned int pos; signed int val; - signed int L_S1, R_S1, L_S2, R_S2; + signed short *S1, *S2; + int voice; pos = data->pos; - L_S1 = data->last_L_S1; - R_S1 = data->last_R_S1; - L_S2 = data->last_L_S2; - R_S2 = data->last_R_S2; + S1 = data->last_S1; + S2 = data->last_S2; if (pos >> SHIFT) { - src_ptr += ((pos >> SHIFT) - 1) * 2; pos &= MASK; - L_S1 = L_S2; - R_S1 = R_S2; - L_S2 = *src_ptr; - R_S2 = *(src_ptr + 1); + src_ptr += ((pos >> SHIFT) - 1) * voices; pos &= MASK; + for (voice = 0; voice < voices; ++voice) { + S1[voice] = S2[voice]; + S2[voice] = src_ptr[voice]; + } } while (dst_size-- > 0) { if (pos >> SHIFT) { - src_ptr += (pos >> SHIFT) * 2; pos &= MASK; - L_S1 = L_S2; - R_S1 = R_S2; - L_S2 = *src_ptr; - R_S2 = *(src_ptr + 1); + src_ptr += (pos >> SHIFT) * voices; pos &= MASK; + for (voice = 0; voice < voices; ++voice) { + S1[voice] = S2[voice]; + S2[voice] = src_ptr[voice]; + } } - val = L_S1 + ((L_S2 - L_S1) * (signed int)pos) / BITS; - if (val < -32768) - val = -32768; - else if (val > 32767) - val = 32767; - *dst_ptr++ = val; - // printf("L_S1 = %i, L_S2 = %i, pos = %i, val = %i\n", L_S1, L_S2, pos, val); - - val = R_S1 + ((R_S2 - R_S1) * (signed int)pos) / BITS; - if (val < -32768) - val = -32768; - else if (val > 32767) - val = 32767; - *dst_ptr++ = val; + for (voice = 0; voice < voices; ++voice) { + val = S1[voice] + ((S2[voice] - S1[voice]) * (signed int)pos) / BITS; + if (val < -32768) + val = -32768; + else if (val > 32767) + val = 32767; + *dst_ptr++ = val; + } pos += data->pitch; } - data->last_L_S1 = L_S1; - data->last_R_S1 = R_S1; - data->last_L_S2 = L_S2; - data->last_R_S2 = R_S2; data->pos = pos; } @@ -152,23 +106,16 @@ static ssize_t rate_transfer(snd_pcm_plugin_t *plugin, data = (struct rate_private_data *)snd_pcm_plugin_extra_data(plugin); if (data == NULL) return -EINVAL; - if (data->src_voices == 1) { - mix_mono(data, (signed short *)src_ptr, src_size / 2, - (signed short *)dst_ptr, dst_size / 2); - return (dst_size / 2) * 2; - } - else if (data->src_voices == 2) { - mix_stereo(data, (signed short *)src_ptr, src_size / 4, - (signed short *)dst_ptr, dst_size / 4); - return (dst_size / 4) * 4; - } else { - return -EINVAL; - } + mix(data, data->src_voices, + (signed short *)src_ptr, src_size / (data->src_voices * 2), + (signed short *)dst_ptr, dst_size / (data->dst_voices * 2)); + return dst_size / (2 * data->src_voices) * (2 * data->src_voices); } static int rate_action(snd_pcm_plugin_t *plugin, snd_pcm_plugin_action_t action) { struct rate_private_data *data; + int voice; if (plugin == NULL) return -EINVAL; @@ -179,8 +126,9 @@ static int rate_action(snd_pcm_plugin_t *plugin, snd_pcm_plugin_action_t action) case DRAIN: case FLUSH: data->pos = 0; - data->last_L_S1 = data->last_R_S1 = 0; - data->last_L_S2 = data->last_R_S2 = 0; + for (voice = 0; voice < data->src_voices; ++voice) { + data->last_S1[voice] = data->last_S2[voice] = 0; + } break; } return 0; /* silenty ignore other actions */ @@ -215,7 +163,7 @@ static ssize_t rate_dst_size(snd_pcm_plugin_t *plugin, size_t size) return -EINVAL; data = (struct rate_private_data *)snd_pcm_plugin_extra_data(plugin); res = (((size << SHIFT) + (data->pitch / 2)) / data->pitch); - res = res / (data->src_voices*2) * (data->src_voices*2); + res = res / (data->dst_voices*2) * (data->dst_voices*2); /* Why this? */ if (size < 128*1024) { if (data->old_dst_size == size) @@ -232,6 +180,7 @@ int snd_pcm_plugin_build_rate(snd_pcm_format_t *src_format, { struct rate_private_data *data; snd_pcm_plugin_t *plugin; + int voice; if (!r_plugin) return -EINVAL; @@ -245,7 +194,7 @@ int snd_pcm_plugin_build_rate(snd_pcm_format_t *src_format, return -EINVAL; if (src_format->voices != dst_format->voices) return -EINVAL; - if (dst_format->voices != 1 && dst_format->voices != 2) + if (dst_format->voices < 1 || dst_format->voices > MAX_VOICES) return -EINVAL; if (src_format->format != SND_PCM_SFMT_S16_LE || @@ -264,8 +213,9 @@ int snd_pcm_plugin_build_rate(snd_pcm_format_t *src_format, data->dst_rate = dst_format->rate; data->pitch = ((src_format->rate << SHIFT) + (dst_format->rate >> 1)) / dst_format->rate; data->pos = 0; - data->last_L_S1 = data->last_R_S1 = 0; - data->last_L_S2 = data->last_R_S2 = 0; + for (voice = 0; voice < data->src_voices; ++voice) { + data->last_S1[voice] = data->last_S2[voice] = 0; + } data->old_src_size = data->old_dst_size = 0; plugin->transfer = rate_transfer; plugin->src_size = rate_src_size; diff --git a/src/pcm/plugin/volbal.c b/src/pcm/plugin/volbal.c index 3747e208..6deef5e6 100644 --- a/src/pcm/plugin/volbal.c +++ b/src/pcm/plugin/volbal.c @@ -28,15 +28,47 @@ #include #include "../pcm_local.h" - #define VOLBAL_RESOLUTION 16 struct volbal_private_data { int src_voices; - int noop; + unsigned int noop:1; int ttable[0]; }; +static int volbal_load_ttable(struct volbal_private_data *data, + const int *src_ttable) +{ + int src_voice, dst_voice; + const int *sptr; + int *dptr; + data->noop = 1; + if (src_ttable == NULL) + return 0; + dptr = data->ttable; + sptr = src_ttable; + for (dst_voice = 0; dst_voice < data->src_voices; ++dst_voice) { + int t = 0; + for (src_voice = 0; src_voice < data->src_voices; ++src_voice) { + if (*sptr < 0 || *sptr > VOLBAL_RESOLUTION) + return -EINVAL; + if (src_voice == dst_voice) { + if (*sptr != VOLBAL_RESOLUTION) + data->noop = 0; + } + else { + if (*sptr != 0) + data->noop = 0; + } + t += *sptr; + *dptr++ = *sptr++; + } + if (t > VOLBAL_RESOLUTION) + return -EINVAL; + } + return 0; +} + static void volbal(int voices, int samples, int *ttable, signed short *src_ptr, signed short *dst_ptr) { @@ -48,11 +80,11 @@ static void volbal(int voices, int samples, int *ttable, int src_voice; signed short *s = src_ptr; for (src_voice = 0; src_voice < voices; ++src_voice) { - v += *s++ * *t++ / VOLBAL_RESOLUTION; + v += (int) *s++ * *t++ / VOLBAL_RESOLUTION; } *dst_ptr++ = v; - src_ptr += voices; } + src_ptr += voices; } } @@ -61,16 +93,17 @@ static ssize_t volbal_transfer(snd_pcm_plugin_t *plugin, char *dst_ptr, size_t dst_size) { struct volbal_private_data *data; + if (plugin == NULL || src_ptr == NULL || src_size < 0 || dst_ptr == NULL || dst_size < 0) return -EINVAL; if (src_size == 0) return 0; data = (struct volbal_private_data *)snd_pcm_plugin_extra_data(plugin); - if (data == NULL) - return -EINVAL; - if (data->noop) - return 0; + if (data->noop) { + memcpy(dst_ptr, src_ptr, src_size); + return src_size; + } volbal(data->src_voices, src_size / 2 / data->src_voices, data->ttable, (signed short *)src_ptr, (signed short *)dst_ptr); @@ -91,41 +124,6 @@ static ssize_t volbal_dst_size(snd_pcm_plugin_t *plugin, size_t size) return size; } - -static int volbal_load_ttable(struct volbal_private_data *data, - const int *src_ttable) -{ - int src_voice, dst_voice; - const int *sptr; - int *dptr; - data->noop = 1; - if (src_ttable == NULL) - return 0; - sptr = src_ttable; - dptr = data->ttable; - for (dst_voice = 0; dst_voice < data->src_voices; ++dst_voice) { - int t = 0; - for (src_voice = 0; src_voice < data->src_voices; ++src_voice) { - if (*sptr < 0 || *sptr > VOLBAL_RESOLUTION) - return -EINVAL; - if (src_voice == dst_voice) { - if (*sptr != VOLBAL_RESOLUTION) - data->noop = 0; - } - else { - if (*sptr != 0) - data->noop = 0; - } - t += *sptr; - *dptr++ = *sptr++; - } - if (t > VOLBAL_RESOLUTION) - return -EINVAL; - } - return 0; -} - - int snd_pcm_plugin_build_volbal(snd_pcm_format_t *src_format, snd_pcm_format_t *dst_format, int *ttable, @@ -133,7 +131,7 @@ int snd_pcm_plugin_build_volbal(snd_pcm_format_t *src_format, { struct volbal_private_data *data; snd_pcm_plugin_t *plugin; - int res; + int err; if (!r_plugin) return -EINVAL; @@ -159,10 +157,10 @@ int snd_pcm_plugin_build_volbal(snd_pcm_format_t *src_format, if (plugin == NULL) return -ENOMEM; data = (struct volbal_private_data *)snd_pcm_plugin_extra_data(plugin); - data->src_voices = src_format->voices; - if ((res = volbal_load_ttable(data, ttable)) < 0) - return res; + data->src_voices = src_format->voices; + if ((err = volbal_load_ttable(data, ttable)) < 0) + return err; plugin->transfer = volbal_transfer; plugin->src_size = volbal_src_size; plugin->dst_size = volbal_dst_size; -- 2.47.1