2014-11-24 3 views
0

Я реализую фильтр нижних частот в C с библиотекой PortAudio. Я записываю вход микрофона со сценарием из самого PortAudio. Там я добавил следующий код:Фильтр нижних частот в C

float cutoff = 4000.0; 

float filter(float cutofFreq){ 
    float RC = 1.0/(cutofFreq * 2 * M_PI); 
    float dt = 1.0/SAMPLE_RATE; 
    float alpha = dt/(RC+dt); 

    return alpha; 
} 

float filteredArray[numSamples]; 
filteredArray[0] = data.recordedSamples[0]; 

for(i=1; i<numSamples; i++){ 
    if(i%SAMPLE_RATE == 0){ 
     cutoff = cutoff - 400; 
    } 
    data.recordedSamples[i] = data.recordedSamples[i-1] + (filter(cutoff)*(data.recordedSamples[i] - data.recordedSamples[i-1])); 
} 

Когда я запускаю этот скрипт в течение 5 секунд, он работает. Но когда я пытаюсь запустить это более 5 секунд, это терпит неудачу. Приложение записывает все, но сбой при воспроизведении. Если я удалю фильтр, приложение будет работать.

Любые советы?

+0

не получают за то, что вам нужно это: 'если (я% SAMPLE_RATE == 0) ...' и вы хотите сделать непрерывную выборку в РТ или образец сначала, затем фильтр? для первого варианта вы не должны фильтровать все образцы, а только новые добавленные ... также вы фильтруете с помощью 'i-1',' i', поэтому вы должны иметь 'i -' in for loop, а не наоборот (вы воздействуете на элемент 'i-1' перед его использованием ... – Spektre

+0

Я пытаюсь сделать фильтр, который будет работать в режиме реального времени, так что мне потребуется непрерывная выборка, я думаю. Первое, если используется, t хочу изменить обрезку каждую секунду 44100 раз, но только один раз. – boortmans

+0

добавил ответ ... ваш основной вопрос, скорее всего, через 5 секунд - это значение отсечки из вашей полезной области (отрицательно) – Spektre

ответ

1

Проблема:

  1. вы понижаем частоту среза на 400 Гц каждый раз i%SAMPLE_RATE == 0

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

    • ... a[i]=f(a[i],a[i-1]; i++;
    • , что означает, что вы Filte кольцо с уже отфильтрованной a[i-1] значение

Что с ним делать

  1. проверки размещения кода

    • он должен быть в каком-то событии, как на упакованном сделано sompling
    • или в резьбе после некоторого Sleep(...); (или внутри таймер)
    • изменения отрезанного изменения (ручка крайних случаев)
  2. обратного фильтра для направления

Что-то вроде этого:

int i_done=0; 

void on_some_timer() 
{ 
cutoff-=400; 
if (cutoff<1) cutoff=1; // here change 1 for limit frequency 

if (numSamples!=i_done) 
    for (i=numSamples-1,i>=i_done;i--) 
    data.recordedSamples[i] = data.recordedSamples[i-1] + (filter(cutoff)*(data.recordedSamples[i] - data.recordedSamples[i-1])); 
i_done=numSamples; 
} 

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

  • затем просто добавить if (cutoff<1) cutoff=1; после изменения среза
+0

Итак, если мой массив заполнен аудиозаписями , Я должен запустить таймер, цикл через массив и после появления timerevent, изменить обрезание? – boortmans

+0

'cutoff- = cutoff-400;' такое же, как 'cutoff = 400;' – mch

+0

@mch heh yep (ошибка копирования thx для определения его) – Spektre

Смежные вопросы