Программно увеличить шаг массива звуковых выборок
Привет, добрые люди мира аудио вычислений,
У меня есть массив образцов, которые отражают запись. Предположим, что это 5 секунд при 44100Hz. Как я буду играть на повышенном поле? А можно ли динамически увеличивать и уменьшать высоту тона? Например, шаг медленно увеличивается, чтобы удвоить скорость, а затем отступить.
другими словами, Я хочу взять запись и воспроизвести ее, как если бы она была "поцарапана" d.j.
псевдокод всегда приветствуется. Я напишу это на С.
спасибо,
правка 1
позвольте мне уточнить мои намерения. Я хочу сохранить воспроизведение на 44100Hz, и поэтому мне нужно манипулировать образцами перед воспроизведением. Это также потому, что я хотел бы смешайте звук, который имеет увеличенный шаг со звуком, который работает с нормальной скоростью.
выраженный по-другому, может быть, мне нужно сжать звук над тем же количеством образцов каким-то образом? Таким образом, когда он воспроизводится, он будет звучать быстрее?
правка 2
кроме того, я хотел бы сделать это сам. Никаких библиотек, пожалуйста (если вы не считаете, что я могу выбрать код и найти что-то интересное).
правка 3
образец кода, написанного на C, который принимает 2 аргументы (массив образцов и Коэффициент высоты тона), а затем возвращает массив нового звука было бы фантастическим!
PS я начал награду за это не потому, что я не думаю, что ответы, уже данные, недействительны. Я просто подумал, что было бы неплохо получить больше отзывов по этому вопросу.
НАГРАДА ЗА ЩЕДРОСТЬ
честно говоря, я хотел бы распределить награду за несколько разных ответов, поскольку их было довольно много что, по-моему, было очень полезно. Специальный крик Дэниелу за передачу мне кода и Эшелли и Hotpaw2 за такие подробные ответы.
в конечном счете, хотя я использовал ответ от еще один вопрос ссылается datageist и поэтому награда переходит к нему.
еще раз спасибо всем!
6 ответов
взгляните на "слон" в ответ Nosredna на этот (очень похож), поэтому вопрос: Как вы делаете бикубическую (или другую нелинейную) интерполяцию перепробованных аудиоданных?
примеры реализаций предоставляются, начиная со страницы 37, и для справки ответ Эшелли соответствует линейной интерполяции (на той же странице). С небольшой настройкой любая из других формул в документе может быть подключена к этой структуре.
для оценивая качество данного метода интерполяции (и понимая потенциальные проблемы с использованием" более дешевых " схем), взгляните на эту страницу:
http://www.discodsp.com/highlife/aliasing/
для большей теории, чем вы, вероятно, хотите иметь дело с (с исходным кодом), это хорошая ссылка:
один из способов-сохранить индекс с плавающей запятой в исходной волне и смешать интерполированные образцы в выходную волну.
//Simulate scratching of `inwave`:
// `rate` is the speedup/slowdown factor.
// result mixed into `outwave`
// "Sample" is a typedef for the raw audio type.
void ScratchMix(Sample* outwave, Sample* inwave, float rate)
{
float index = 0;
while (index < inputLen)
{
int i = (int)index;
float frac = index-i; //will be between 0 and 1
Sample s1 = inwave[i];
Sample s2 = inwave[i+1];
*outwave++ += s1 + (s2-s1)*frac; //do clipping here if needed
index+=rate;
}
}
если вы хотите изменить rate
на лету, вы можете сделать это.
если это создает шумные артефакты при скорости > 1, Попробуйте заменить *outwave++ += s1 + (s2-s1)*frac;
С помощью этого метода (от этого вопроса)
*outwave++ = InterpolateHermite4pt3oX(inwave+i-1,frac);
здесь
public static float InterpolateHermite4pt3oX(Sample* x, float t)
{
float c0 = x[1];
float c1 = .5F * (x[2] - x[0]);
float c2 = x[0] - (2.5F * x[1]) + (2 * x[2]) - (.5F * x[3]);
float c3 = (.5F * (x[3] - x[0])) + (1.5F * (x[1] - x[2]));
return (((((c3 * t) + c2) * t) + c1) * t) + c0;
}
пример использования линейной интерполяции техника на " Windows Startup.wav " с коэффициентом 1,1. Оригинал находится сверху, ускоренная версия находится внизу:
это может быть не математически идеально, но это звучит так, как должно, и должно отлично работать для нужд OP..
Да, это возможно.
но это не небольшое количество псевдо-кода. Вы просите алгоритм модификации временного шага, который представляет собой довольно большой и сложный объем кода DSP для достойных результатов.
здесь обзор растяжения временного шага от DSP Dimensions. Вы также можете Google для алгоритмов фазового вокодера.
добавлено:
Если вы хотите "поцарапать", как DJ может сделать с LP на физический turntable, вам не нужно изменение врем-тангажа. Царапины изменяют высоту и скорость игры на ту же величину (не независимо, как потребовалось бы время-изменение шага).
и результирующий массив не будет одинаковой длины, но будет короче или длиннее на Амон изменения шага/скорости.
вы можете изменить высоту тона, а также сделать звук играть быстрее или медленнее по тому же соотношению, просто повторно отсчет сигнала с помощью правильно отфильтрованного интерполяция. Просто переместите каждую точку выборки, а не на 1.0, путем добавления с плавающей запятой по желаемому изменению скорости, затем отфильтруйте и интерполируйте данные в этой точке. Интерполяция с использованием оконного ядра интерполяции Sinc с частотой перехода фильтра нижних частот ниже нижней исходной и интерполированной локальной частоты дискретизации будет работать довольно хорошо. Поиск "оконной интерполяции Sinc" в интернете возвращает множество подходящих результатов.
вам нужна интерполяция метод, который включает в себя фильтр нижних частот, иначе вы услышите ужасный шум сглаживания. (Исключение может быть, если исходный звуковой файл уже сильно отфильтрован с низким пропуском на десятилетие или более ниже частоты дискретизации.)
Если вы хотите, чтобы это было сделано легко, см. предложение AShelly [edit: на самом деле, попробуйте сначала в любом случае]. Если вам нужно хорошее качество, вам в основном нужен вокодер фазы.
основная идея фазового вокодера состоит в том, чтобы найти частоты, из которых состоит звук, изменить эти частоты по мере необходимости и ресинтезировать звук. Таким образом, жестокое упрощение было бы:
- запустить FFT
- изменить все частоты на a фактор
- запустить обратный FFT
Если вы собираетесь реализовать это самостоятельно, вы определенно должны прочитать подробное объяснение того, как работает фазовый вокодер. Алгоритм действительно нуждается в гораздо большем количестве соображений, чем трехэтапное упрощение выше.
конечно, готовые реализации exist, но из вопроса я понял, вы хотите сделать это самостоятельно.
уменьшить и увеличить тангаж как просто как играть образец назад на более низком или более высоком тарифе чем 44,1 кГц. Это создаст более медленный / быстрый звук записи, но вам нужно будет добавить "царапины" реальных записей.
этой помог мне с повторной выборкой, что то же самое, что вам нужно просто посмотреть с противоположной стороны.
Если вы не можете найти код, ping меня, у меня есть хорошая процедура C для этого.