Find the closest freq in a filterbank

2 views (last 30 days)
S
S on 15 Jul 2024
Commented: Umar on 6 Sep 2024
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
S
S on 3 Sep 2024
@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:)
Umar
Umar on 6 Sep 2024
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)

Milan Bansal
Milan Bansal on 15 Jul 2024
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
S
S on 17 Jul 2024
@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
Walter Roberson
Walter Roberson on 5 Aug 2024
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.

Categories

Find more on Applications in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!