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

1 view (last 30 days)
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

Accepted Answer

jibrahim
jibrahim on 22 Feb 2024
Edited: jibrahim on 22 Feb 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 Comment
Anthony Gillan
Anthony Gillan on 26 Feb 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 :)

Sign in to comment.

More Answers (0)

Categories

Find more on Audio Plugin Creation and Hosting in Help Center and File Exchange

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!