Как я могу сделать сэмпл 16000 Гц из семпла 44100 Гц в потоке в реальном времени?

Я использую portaudio в работе Cpp. Моя модель сигнала обрабатывает только аудиовход 16000 Гц и

Когда The First выпустил мою работу, мне не нужно было использовать частоту дискретизации 44100. Это был всего лишь микрофон с частотой 48000 Гц. Поэтому я передискретизировал свой сигнал как 48000 -> 16000 -> 48000 с помощью простого алгоритма прореживания и линейной интерполяции.

Но теперь я хочу использовать микрофон 44100. При обработке в реальном времени Мой буфер составляет 256 точек при 16000 Гц. Так что трудно найти размер входного буфера в 44100 Гц и даунсэмплинг с 44100 до 16000.

Когда я использовал только фильтр прореживания или усреднения (https://github.com/mattdiamond/Recorderjs/issues/186), выходная речь выше, чем входная, а интерполяция оконной функции sinc создает искажение.

Есть ли способ сделать 44100->16000 даунсэмплинг для обработки в реальном времени? пожалуйста, дайте мне знать...

благодарю вас.

1 ответ

В прошлом мне приходилось решать аналогичную задачу, но не для звука, а для имитации асинхронности между частотой дискретизации передаваемого сигнала и частотой дискретизации приемника.

Вот как я буду действовать:

Давайте позвоним T1длительность выборки входящего сигнала x: T1=1/44100и давайте позвоним T2продолжительность времени выборки сигнала, который будет сгенерирован y.

Чтобы вычислить значение сигнала y[n*T2], выберите два входных значения x[k*T1]а также x[(k+1)*T2]которые окружают вычисляемое значение:

      k*T1 <= n*T2 < (k+1)*T1

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

Если t = n*T2, a = k*T1а также b = (k+1)*T2, тогда

      p = (x[b] - x[a])/T1
y[t] = p*(t-a) + x[a]

С частотой 44,1 кГц, x|a]а также x[a+T1]должны быть достаточно хорошо коррелированы, и линейная интерполяция может быть достаточно хорошей.

При полученном недостаточно хорошем качестве можно интерполировать входящий сигнал с фиксированным коэффициентом интерполяции, например 2, с классическим четко определенным хорошим интерполяционным фильтром.

Затем можно применить предыдущую процедуру с помощью нового рассчитанного сигнала, длительность дискретизации которого равна T1/2.

Если входящий сигнал имеет некоторые высокие частоты, то, чтобы избежать алиасинга, вам необходимо применить фильтр низких частот к входящему сигналу перед субдискретизацией. Обратите внимание, что это необходимо даже в вашем предыдущем случае 48 кГц -> 16 кГц.

Другие вопросы по тегам