From: Jaroslav Kysela Date: Thu, 25 Nov 1999 10:15:28 +0000 (+0000) Subject: Fixed many bugs.. X-Git-Tag: v1.0.3~1409 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=adb16d5236fcfc03b3fe257e9fd8b20cfc8f65ec;p=alsa-lib.git Fixed many bugs.. --- diff --git a/src/pcm/plugin/rate.c b/src/pcm/plugin/rate.c index 0522ed5c..8f21df50 100644 --- a/src/pcm/plugin/rate.c +++ b/src/pcm/plugin/rate.c @@ -28,7 +28,7 @@ #include #include "../pcm_local.h" -#define SHIFT 10 +#define SHIFT 11 #define BITS (1<pos; - L_S1 = L_S2 = data->last_L_S1; - R_S1 = R_S2 = data->last_R_S1; - while (dst_size-- > 0) { - pos += data->pitch; - src_ptr += (pos >> SHIFT) * 2; pos &= MASK; + L_S1 = data->last_L_S1; + R_S1 = data->last_R_S1; + L_S2 = data->last_L_S2; + R_S2 = data->last_R_S2; + if (pos >> SHIFT) { + src_ptr += ((pos >> SHIFT) - 1) * 2; pos &= MASK; + L_S1 = L_S2; + R_S1 = R_S2; L_S2 = *src_ptr; - val = L_S1 + ((L_S2 + L_S1) * (signed int)pos) / BITS; + R_S2 = *(src_ptr + 1); + } + 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); + } + + 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; - R_S2 = *(src_ptr + 1); - val = R_S1 + ((R_S2 + R_S1) * (signed int)pos) / BITS; + // 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; + + pos += data->pitch; } - data->last_L_S1 = L_S2; - data->last_R_S1 = R_S2; + 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; } @@ -93,9 +115,33 @@ 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; - mix(data, (signed short *)src_ptr, src_size / 4, - (signed short *)dst_ptr, dst_size / 4); - return (dst_size / 4) * 4; + 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; + } +} + +static int rate_action(snd_pcm_plugin_t *plugin, snd_pcm_plugin_action_t action) +{ + struct rate_private_data *data; + + if (plugin == NULL) + return -EINVAL; + data = (struct rate_private_data *)snd_pcm_plugin_extra_data(plugin); + switch (action) { + case INIT: + case PREPARE: + 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; + break; + } + return 0; /* silenty ignore other actions */ } static ssize_t rate_src_size(snd_pcm_plugin_t *plugin, size_t size) @@ -160,11 +206,13 @@ int snd_pcm_plugin_build_rate(int src_format, int src_rate, int src_voices, data->dst_rate = dst_rate; data->pitch = ((src_rate << SHIFT) + (dst_rate >> 1)) / dst_rate; data->pos = 0; - data->last_L_S1 = data->last_R_S1; + data->last_L_S1 = data->last_R_S1 = 0; + data->last_L_S2 = data->last_R_S2 = 0; data->old_src_size = data->old_dst_size = 0; plugin->transfer = rate_transfer; plugin->src_size = rate_src_size; plugin->dst_size = rate_dst_size; + plugin->action = rate_action; *r_plugin = plugin; return 0; }