Find the closest freq in a filterbank

I am using a filter bank to run different freq signals through. I am trying to make it more efficient (to not have to use all the filters every time) so I am trying to find a way to specify in my code to only use the 3 filters with the closest center frequency to the input. Right now I am only able to input the filter numbers I want manually (with filter_number). I am not sure how I would change this. I was trying to use the 'find' function but was only able to make it work using freq not filter numbers. Like this:
indf = find(CenterFreqs<signal_freq)
How can I chnage something like the above line to instead use filter number in my code below?Thank you for your time!
%Parameters
fs = 16e3;
t = 0:(1/fs):0.03;
t = t(:); % ensure column vector
numFilts = 32;
filter_number = 10;
range = [50 8000];
gammaFiltBank = gammatoneFilterBank(range,numFilts,fs); % set fs explicity
input_signal = sin(2*pi*100*t)
output_signal = gammaFiltBank(input_signal);
figure %1
stem(t,output_signal(:,filter_number));
title(sprintf('Output of Filter %d',filter_number))
figure
impulse_input = 0*t;
impulse_input(1) = 1;
reset(gammaFiltBank); % IMPORTANT!
yimp = gammaFiltBank(impulse_input);
%Add together outputs of specific filters
filter_number2=12;
Add1=yimp(:,filter_number);
Add2=yimp(:,filter_number2);
Total=Add1 + Add2;
stem(t,Total)
title(sprintf('Impulse of %d plus %d',filter_number,filter_number2))

7 Comments

Hi S,
Obtain the frequency response of the filter using the 'freqz' function in your code. For more information on this function, please refer to
% Obtain frequency response
[h, f] = freqz(output_signal(:, filter_number));
Then apply the obtained response to filter the output signal using the 'filter' function.
% Apply frequency filtering
filtered_output = filter(h, 1, output_signal);
This will allow you to achieve frequency-based filtering for your specific filter number.
Please let me know if you have any further questions.
Thanks Walter for your help with making my code cleaner.
@Umar Thank you! Where my confusion is that I want to find the closest filters to my given input frequency. This is using filter number as an input, where I do not want it to necessarily use the same filter every time. Would I use a similar method to you to do this?
Hi @S,
To find the closest filters to a given input frequency based on a specific filter number in Matlab, you can follow a similar approach to what I have described in my recent comments. So, the above step will stays the same which is start by obtaining the frequency response of the filter corresponding to the filter number using the freqz function which will give you the filter's frequency response h and the corresponding frequencies f.
% Obtain frequency response
[h, f] = freqz(output_signal(:, filter_number));
To find the closest filters to your desired input frequency, you can compare the obtained frequency response h with the desired frequency response. You can calculate the difference between the two responses and choose the filter that minimizes this difference. Once you have identified the closest filter based on the frequency response, you can apply this filter to the output signal using the filter function. This will perform frequency-based filtering on the output signal.
Here is much detailed code snippet to showcase for what I mentioned,
% Define the filter coefficients 'h'
h = fir1(31, 0.5);
% Generate or load the 'output_signal' variable
output_signal = your_output_signal_generation_function(); % Replace with actual signal generation code
% Apply frequency filtering
filtered_output = filter(h, 1, output_signal);
% Define input frequency
input_frequency = 0.3; % Example input frequency
% Calculate the closest filter number
[~, closest_filter_number] = min(abs(f - input_frequency));
% Obtain the frequency response for the closest filter
[h_closest, ~] = freqz(output_signal(:, closest_filter_number));
% Apply frequency filtering using the closest filter
filtered_output_closest = filter(h_closest, 1, output_signal);
Hope this helps. Feel free to ask if you need further clarification or assistance in implementing this approach.
Umar
Umar on 5 Aug 2024
Edited: Umar on 4 Sep 2024

Hi @S,

After reading your comments second time, “ This is using filter number as an input, where I do not want it to necessarily use the same filter every time.” It helped me to clarify my thoughts little better, so to achieve frequency-based filtering without being constrained to a fixed filter number, you can modify the code to calculate the closest filter number for each input frequency. Instead of using a fixed filter_number, you can iterate over all available filters and choose the one that minimizes the difference between its frequency response and the desired input frequency. I have modified code above to demonstrate this approach:

% Generate or load the 'output_signal' variable
output_signal = your_output_signal_generation_function(); % Replace   with actual signal generation code
% Define input frequency
input_frequency = 0.3; % Example input frequency
% Initialize variables for closest filter selection
min_difference = Inf;
closest_filter_number = 1;
% Iterate over all filters to find the closest one
for filter_number = 1:num_filters % num_filters is the total number     of filters
% Obtain frequency response for the current filter
[h, f] = freqz(output_signal(:, filter_number));
% Calculate the difference between current filter response and input     frequency
difference = abs(f - input_frequency);
% Update closest filter if the current one is closer
if min(difference) < min_difference
min_difference = min(difference);
closest_filter_number = filter_number;
end
end
% Obtain the frequency response for the closest filter
[h_closest, ~] = freqz(output_signal(:, closest_filter_number));
% Apply frequency filtering using the closest filter
filtered_output_closest = filter(h_closest, 1, output_signal);

Hope, this will help to achieve your task now, let me know if this is what you’re looking for.

@Umar Thank you! This is more what I was looking for! So closest_filter_number is now the number of filters I am finding closest to the input freq correct? So it could be changed to other values?
I could just add this below what I already have? Or would it require further adjustment?
Thanks again:)
Hi @S,
I have provided the solution below to address your concerns. Please let me know if this helps resolve your issue.

Sign in to comment.

Answers (2)

Hi S,
I understand that you wish to use the 3 filters from your filter bank which have their center frequency closest to the frequency of the input signal.
Please refer to the following steps to achive this:
  1. Get the center frequencies of all the filters in the filter bank using the getCenterFrequencies function.
  2. Calculate the absolute difference of center frequency and center frequencies from 1st step.
  3. Get the sorted indices of the difference and select the 1st 3 indices. These are the filter numbers which have closest center frequencies.
  4. Use these filter numbers to get the desired output.
Please refer to the following code snippet to modify your code:
% Parameters
fs = 16e3;
t = 0:(1/fs):0.03;
t = t(:); % ensure column vector
numFilts = 32;
signal_freq = 100; % frequency of input signal
range = [50 8000];
gammaFiltBank = gammatoneFilterBank(range, numFilts, fs); % set fs explicitly
% Generate input signal
input_signal = sin(2*pi*signal_freq*t);
% Get the center frequencies of the filters
CenterFreqs = getCenterFrequencies(gammaFiltBank);
% Find the 3 filters with the closest center frequencies to the input signal's frequency
[~, sorted_indices] = sort(abs(CenterFreqs - signal_freq));
closest_filters = sorted_indices(1:3);
% Process the input signal through the selected filters
output_signal = gammaFiltBank(input_signal);
figure
stem(t, output_signal(:, closest_filters(1)));
title(sprintf('Output of Closest Filter %d', closest_filters(1)))
figure
stem(t, output_signal(:, closest_filters(2)));
title(sprintf('Output of Closest Filter %d', closest_filters(2)))
figure
stem(t, output_signal(:, closest_filters(3)));
title(sprintf('Output of Closest Filter %d', closest_filters(3)))
% Generate impulse response and add the outputs of the selected filters
impulse_input = 0*t;
impulse_input(1) = 1;
reset(gammaFiltBank); % IMPORTANT!
yimp = gammaFiltBank(impulse_input);
% Add together outputs of specific filters
Add1 = yimp(:, closest_filters(1));
Add2 = yimp(:, closest_filters(2));
Add3 = yimp(:, closest_filters(3));
Total = Add1 + Add2 + Add3;
figure
stem(t, Total)
title(sprintf('Impulse of Closest Filters %d, %d, and %d', closest_filters(1), closest_filters(2), closest_filters(3)))
Please refer to the following documentation link to learn more about getCenterFrequencies function.
Hope this helps!

2 Comments

@Milan Bansal Thank you! Just to be sure, this line:
closest_filters = sorted_indices(1:3);
is not just giving me filter 1,2,and 3's response, it is giving the 3 filters with the center frequencies closest to my input (100 in this case) so it could technically be filter 5,6, and 7 for ex. even though it is labeled 1-3. Right? I just want to make sure I am understanding correctly
It would be returning the index of which filters are closest.

Sign in to comment.

Umar
Umar on 4 Sep 2024

Hi @S,

To achieve frequency-based filtering in MATLAB, where the filter selection is not fixed but rather determined by the proximity of the filter's frequency response to the desired input frequency, first, you need to know that each filter has a specific frequency response that can be obtained using the freqz function. This function returns the frequency response of a filter given its coefficients. So, instead of using a predetermined filter number, iterate through all available filters. For each filter, compute its frequency response and determine how close it is to the desired input frequency. Afterwards, maintain a variable to track the minimum difference between the input frequency and the frequencies of the filters. The filter that yields the smallest difference will be selected for filtering the output signal. Once the closest filter is identified, we will apply it to the output signal using the filter function. Here is a complete example that demonstrates it.

% Generate or load the 'output_signal' variable
output_signal = your_output_signal_generation_function(); % Replace with     
actual signal generation code
% Define input frequency
input_frequency = 0.3; % Example input frequency
% Initialize variables for closest filter selection
num_filters = size(output_signal, 2); % Assuming output_signal has filters as   
columns
min_difference = Inf;
closest_filter_number = 1;
% Iterate over all filters to find the closest one
for filter_number = 1:num_filters
  % Obtain frequency response for the current filter
  [h, f] = freqz(output_signal(:, filter_number));
    % Calculate the difference between current filter response and input
    frequency
    difference = abs(f - input_frequency);
      % Update closest filter if the current one is closer
      if min(difference) < min_difference
        min_difference = min(difference);
        closest_filter_number = filter_number;
    end
  end
% Obtain the frequency response for the closest filter
[h_closest, ~] = freqz(output_signal(:, closest_filter_number));
% Apply frequency filtering using the closest filter
filtered_output_closest = filter(h_closest, 1, output_signal);
% Display the results
disp(['The closest filter number is: ', num2str(closest_filter_number)]);

Integrate this code into your existing code

So, at this point, integrate this code snippet into your existing MATLAB script. Simply place it below your current filtering logic. Make sure that the output_signal variable is correctly defined and that the number of filters is accurately represented in the num_filters variable.

This approach should allow you now for a flexible and dynamic selection of filters based on the input frequency, enhancing the adaptability of your filtering process.

Should you have any further questions or require additional modifications, please feel free to reach out.

Tags

Asked:

S
S
on 15 Jul 2024

Commented:

on 6 Sep 2024

Community Treasure Hunt

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

Start Hunting!