ПрограммированиеФорумЗвук

HRTF и интерполяция HRIR

#0
21:25, 18 дек 2019

Делаю HRTF (head-related transfer function) для своего звукового движка и все вроде бы получается весьма неплохо, но при смене спектров HRIR (head-related impulse response) для правого и левого уха при перемещении источника звука, слышны короткие глухие щелчки. Если HRIR остается тем же самым, то никаких щелчков нет. Алгоритм я использую относительно простой:
1) Берем базу HRIR отсюда
2) Получаем спектры HRIR через БПФ (быстрое преобразование Фурье)
3) Для каждого источника выполняем свертку сигнала от источника с HRIR в пространстве частот по этому методу
4) Получаем очень годное звучание и отличный объемный звук, но со щелчками при смене HRIR.

Как видно из графического представления алгоритма, для каждого нового отрезка сигнала часть сигнала после свертки с предыдущего "кадра" суммируется:
Изображение

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

#1
21:30, 18 дек 2019

Похоже что вот это http://www02.smt.ufrj.br/~diniz/conf/confi117.pdf может помочь.

#2
1:02, 19 дек 2019

mr.DIMAS

Как видно из графического представления алгоритма, для каждого нового отрезка сигнала часть сигнала после свертки с предыдущего "кадра" суммируется:

Щелчки - это явно фазовый сдвиг складываемых кусков. (А сдвиг как раз и нужен.)
У меня похожее было, вылечил когда сделал "синхронизацию" по прохождению волны через ноль.

#3
21:14, 19 дек 2019

В общем интерполяция HRIR почти помогла, щелчки стали едва слышимы. Но думаю это просто косяк в реализации, буду дебажить.

Прошло более 1 года
#4
15:04, 18 янв 2021

mr.DIMAS

На той неделе делал реализацию hrtf у себя и столкнулся с той же проблемой щелчков при смене hrir. Идея со сферой и интерполяцией hrir по барицентрическим координатам крутая, но мне кажется, что ее можно улучшить(оптимизировать) если сферу рейкастить не тупо брутфорсом треугольников, а как-то иначе, например по вертикмльным срезам азимутов - по dir.y определяем срез азимутов и рейкастим треугольники внутри среза. Также можно учесть, что левая и правая полусфера зеркальны между собой. Еще, как вариант, можно сгенерировать сферу с регулярным шагом сетки, тогда поиск пересечения с треугольником вообще можно свести к О(1).
Проблема щелчков полностью не решается интерполированием предыдущего и текущего вектора до источника. У себя решил следующим образом: для каждого сегмента применяем 2 hrtf (от предыдущей и текущией позиции источника) и линейно интерполируем между результирующими дорожками. Псевдокод:

// prev, cur - предыдущее и текущее состояние вектора до источника в координатах слушателя

sampleSphere(prev, lefthrtfPrev, righthrtfPrev );

for each segment
{
  dir = lerp( prev, cur, (segmentNum+1)/segmentsCount).norm();

  sampleSphere(dir, lefthrtf, righthrtf );

  applyHrtf( segment, lefthrtfPrev, righthrtfPrev, resultSamplesPrev );

  applyHrtf( segment, lefthrt, righthrtf, resultSamplesCur );

  lefthrtfPrev = lefthrt;
  righthrtfPrev = righthrtf;

  for n 0..segmentLength
  {
    x = n/segmentLength;
    resultSamples[n].left = lerp( resultSamplesPrev[n].left, resultSamplesCur[n].left, x );
    resultSamples[n].right = lerp( resultSamplesPrev[n].right, resultSamplesCur[n].right, x );
  }
}

  
#5
23:38, 19 янв 2021

0xc0de Если честно я не запаривался с оптимизацией рейкаста, все равно большую часть времени жрет преобразование Фурье. Хотя в последнее время rustfft стал нагибать FFTW и может вполне станется так что придется оптимизировать рейкаст. А вот с удалением щелчков идея хорошая, может у себя запилю как время будет. Кстати ты же используешь сферы отсюда https://github.com/mrDIMAS/hrir_sphere_builder ?

#6
0:22, 20 янв 2021

mr.DIMAS
> Кстати ты же используешь сферы отсюда https://github.com/m… phere_builder ?

Да, irc_1002_c.bin

ПрограммированиеФорумЗвук

Тема в архиве.