Inefficient Use of Bandpass IIR Filter Object (DSP System Toolbox)

3 visualizaciones (últimos 30 días)
Hey all, I'm trying to do something hopefully quite simple, but I'm having a little trouble understanding a proper implementation.
I'm processing audio signals using the Audio Toolbox audioPlugin class and want to implement a simple bandpass filter in my processing loop.
Im using the below function from the DSP System toolbox to create a system object for filtering.
designBandpassIIR
I want to implement the filtering such that it operates in a per-sample manner instead of a frame-based one as this gives me the flexibility I need for the feedback in my system.
The main hotspot when I've profiled it is
feedbackSample = plugin.feedbackBpf{ch}(feedbackSample); % problematic line
This is to the extent that it means my algorithm can't run properly in real-time any more.
The relevant snippet of code is below. Any help would be massively appreciated!
function plugin = gDel
% constructor
...
plugin.feedbackBpf = {designBandpassIIR(FilterOrder=2,HalfPowerFrequency1=0.1,HalfPowerFrequency2=0.9,DesignMethod="butter", SystemObject=true), ...
designBandpassIIR(FilterOrder=2,HalfPowerFrequency1=0.1,HalfPowerFrequency2=0.9,DesignMethod="butter", SystemObject=true)};
end
function out = process(plugin, in)
nChannels = size(in, 2);
frameSize = size(in, 1);
...
for ch = 1:nChannels
for n = 1:frameSize
inputSample = in(n, ch);
feedbackSample = plugin.feedbackBuffer{ch}.read(); % custom buffer I've written
feedbackSample = plugin.feedbackBpf{ch}(feedbackSample); % problematic line

Respuesta aceptada

jibrahim
jibrahim el 22 de Feb. de 2024
Editada: jibrahim el 22 de Feb. de 2024
Hi Anthony,
It is expected that filtering your input sample-by-sample will be significantly slower than filtering the entire frame in one shot. Using frame-based processing removes overhead (related to calling the object repeatadly). Moreover, with frame-based processing, the filtering can be more efficient because it takes advantage of optimized vector operations (as well as some parallelism in many cases).
That being said, if you really can't use frame-based processing, you can still potentially remove a lot of the overhead by generating an audio plugin from your audio plugin MATLAB class.
I have attached code that demonstrates this:
  • myFilterSamples: An audio plugin that filters an input sample by sample
  • myFilterFrames: An audio plugin that filters the entire frame in one shot
  • myTiming: Timing results
To generate the audio plugin, use:
generateAudioPlugin myFilterSamples
generateAudioPlugin myFilterFrames
You can then use the generated audio plugin instead of the MATLAB class:
p = loadAudioPlugin("myFilterSamples.dll");
process(p, in);
Moreover, you will notice that you can still filter all input channels in one shot, even if you want to filter sample per sample. That might help you.
Here is a sample timing result I got:
  • Samples filter in MATLAB: 0.587555 s
  • Frame filter in MATLAB: 0.003006 s
  • Samples filter generated plugin: 0.016783 s
  • Frame filter generated plugin: 0.019210 s
  1 comentario
Anthony Gillan
Anthony Gillan el 26 de Feb. de 2024
Thank you for this thorough description and code examples! I've now gone through my codebase and vectorised the operations.
There was a marked increase in efficiency from a frame-based processing configuration. Turns out the sacrifices that I needed to make to implement this sort of architecture weren't as important as I thought for my prototype. I also realised that I missed this page too.
The idea of testing the plugin by loading it after building it is very helpful.
Thank you for your time, much appreciated :)

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Audio Plugin Creation and Hosting en Help Center y File Exchange.

Etiquetas

Productos


Versión

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by