Как я могу сделать сэмпл 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 кГц.