Стерео линейная интерполяция с чередованием

Я реализую линейную интерполяцию аудиоданных в реальном времени, которые хранятся в чередующихся аудиобуферах. Аудио файлы могут быть одноканальными или многоканальными. В случае одноканальных аудиофайлов я интерполирую следующим образом:

f_dex = offset + ((position / oldlength) * (newlength * b_channelcount));
i_dex = trunc(f_dex); // get truncated index
fraction = f_dex - i_dex; // calculate fraction value for interpolation
b_read = (b_sample[i_dex] + fraction * (b_sample[i_dex + b_channelcount] - b_sample[i_dex]));
outsample_left += b_read;
outsample_right += b_read;

Звучит замечательно, и у меня нет никаких проблем. Однако, когда я хочу прочитать многоканальные файлы, я должен скорректировать вычисленную позицию чтения, чтобы убедиться, что она находится в первом образце в соответствующем кадре, например:

f_dex = offset + ((position / oldlength) * (newlength * b_channelcount));
if ((long)trunc(f_dex) % 2) {
    f_dex -= 1.0;
}
i_dex = trunc(f_dex); // get truncated index
fraction = f_dex - i_dex; // calculate fraction value for interpolation
outsample_left += (b_sample[i_dex] + fraction * (b_sample[i_dex + b_channelcount] - b_sample[i_dex])) * w_read;
outsample_right += (b_sample[i_dex + 1] + fraction * (b_sample[(i_dex + 1) + b_channelcount] - b_sample[i_dex + 1])) * w_read;

Теперь здесь появляется некоторый цифровой шум, и я не могу объяснить, почему. Есть ли другой / лучший способ применить линейную интерполяцию в реальном времени к чередующимся стерео файлам?


person Matthias Müller    schedule 05.11.2014    source источник


Ответы (1)


Меня немного смущают ваши имена переменных, position, oldlength и outsample_left/outsample_right, похоже, предназначены для вывода, а newlength и offset - для ввода, b_sample?

Я думаю, что ваша проблема заключается в том, чтобы включить b_channelcount в вычисление f_dex. Попробуйте вместо этого

f_dex = offset + ((position / oldlength) * newlength);

и вы можете опустить % 2 проверку и регулировку. Эта корректировка не делает то, что вы намереваетесь.

Приложение 11/7: Я кое-что пропустил, вам также необходимо настроить использование i_dex, поскольку я установил здесь f_dex, он считает весь блок для каждого канала как 1. Если раньше у вас было b_sample[i_dex], вместо этого используйте b_sample[i_dex*b_channelcount]; это приведет вас к первому сэмплу блока (слева, если стерео). Точно так же вы можете использовать b_sample[i_dex*b_channelcount + 1] для правого канала, если он есть, b_sample[(i_dex+1)*b_channelcount] для первой выборки следующего блока для интерполяции и т. Д.

person hcs    schedule 06.11.2014
comment
Извините, я не могу понять, как разместить правильный код в комментариях ... если это вообще возможно ... В любом случае это должно сделать имена переменных и намерения немного более ясными. Я вижу, что это работает с одноканальными файлами, но не с многоканальными. Кроме того, как я могу убедиться, что вычисление для f_dex относится к первой выборке в кадре? - person Matthias Müller; 07.11.2014
comment
@ MatthiasMüller простое решение - отредактировать этот код в исходном вопросе (не обязательно заменяя ваш старый код, хотя это вариант). Я отредактировал свой ответ, чтобы охватить проблему, заключающуюся в том, что f_dex (и, следовательно, i_dex) теперь считает кадры вместо отдельных выборок. - person hcs; 07.11.2014
comment
Большое спасибо @hcs! Это решило мою проблему, и теперь код работает стабильно! И спасибо за советы по редактированию сообщений. - person Matthias Müller; 08.11.2014