Программно увеличить шаг массива звуковых выборок

Привет, добрые люди мира аудио вычислений,

У меня есть массив образцов, которые отражают запись. Предположим, что это 5 секунд при 44100Hz. Как я буду играть на повышенном поле? А можно ли динамически увеличивать и уменьшать высоту тона? Например, шаг медленно увеличивается, чтобы удвоить скорость, а затем отступить.

другими словами, Я хочу взять запись и воспроизвести ее, как если бы она была "поцарапана" d.j.

псевдокод всегда приветствуется. Я напишу это на С.

спасибо,


правка 1

позвольте мне уточнить мои намерения. Я хочу сохранить воспроизведение на 44100Hz, и поэтому мне нужно манипулировать образцами перед воспроизведением. Это также потому, что я хотел бы смешайте звук, который имеет увеличенный шаг со звуком, который работает с нормальной скоростью.

выраженный по-другому, может быть, мне нужно сжать звук над тем же количеством образцов каким-то образом? Таким образом, когда он воспроизводится, он будет звучать быстрее?


правка 2

кроме того, я хотел бы сделать это сам. Никаких библиотек, пожалуйста (если вы не считаете, что я могу выбрать код и найти что-то интересное).


правка 3

образец кода, написанного на C, который принимает 2 аргументы (массив образцов и Коэффициент высоты тона), а затем возвращает массив нового звука было бы фантастическим!


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



НАГРАДА ЗА ЩЕДРОСТЬ

честно говоря, я хотел бы распределить награду за несколько разных ответов, поскольку их было довольно много что, по-моему, было очень полезно. Специальный крик Дэниелу за передачу мне кода и Эшелли и Hotpaw2 за такие подробные ответы.

в конечном счете, хотя я использовал ответ от еще один вопрос ссылается datageist и поэтому награда переходит к нему.

еще раз спасибо всем!

6 ответов


взгляните на "слон" в ответ Nosredna на этот (очень похож), поэтому вопрос: Как вы делаете бикубическую (или другую нелинейную) интерполяцию перепробованных аудиоданных?

примеры реализаций предоставляются, начиная со страницы 37, и для справки ответ Эшелли соответствует линейной интерполяции (на той же странице). С небольшой настройкой любая из других формул в документе может быть подключена к этой структуре.

для оценивая качество данного метода интерполяции (и понимая потенциальные проблемы с использованием" более дешевых " схем), взгляните на эту страницу:

http://www.discodsp.com/highlife/aliasing/

для большей теории, чем вы, вероятно, хотите иметь дело с (с исходным кодом), это хорошая ссылка:

https://ccrma.stanford.edu / ~jos / resample/


один из способов-сохранить индекс с плавающей запятой в исходной волне и смешать интерполированные образцы в выходную волну.

//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: на самом деле, попробуйте сначала в любом случае]. Если вам нужно хорошее качество, вам в основном нужен вокодер фазы.

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

  1. запустить FFT
  2. изменить все частоты на a фактор
  3. запустить обратный FFT

Если вы собираетесь реализовать это самостоятельно, вы определенно должны прочитать подробное объяснение того, как работает фазовый вокодер. Алгоритм действительно нуждается в гораздо большем количестве соображений, чем трехэтапное упрощение выше.

конечно, готовые реализации exist, но из вопроса я понял, вы хотите сделать это самостоятельно.


уменьшить и увеличить тангаж как просто как играть образец назад на более низком или более высоком тарифе чем 44,1 кГц. Это создаст более медленный / быстрый звук записи, но вам нужно будет добавить "царапины" реальных записей.


этой помог мне с повторной выборкой, что то же самое, что вам нужно просто посмотреть с противоположной стороны.

Если вы не можете найти код, ping меня, у меня есть хорошая процедура C для этого.