Finding Dominant Frequency of Real Time Audio
39 views (last 30 days)
Show older comments
Hi I am doing a fpga audio project, and i encountered an obstacle. I want to display the dominant frequency of audio signal from my laptop. I have this code to use laptop microphone as input audio :
clc;
clear;
devicereader = audioDeviceReader('SampleRate',48000);
devicewriter = audioDeviceWriter('SampleRate',devicereader.SampleRate);
while (1)
audio = devicereader();
devicewriter(audio);
end
and this code for finding dominant frequency:
Fs = 100; % sampling frequency 1 kHz
t = [0,10,20,30,40,50,60,70,80,90]; % time scale
x = [10,120,130,120,120,100,123,456,78,89]; % time series
x = x - mean(x);
plot(t,x), axis('tight'), grid('on'), title('Time series'), figure
nfft = 512; % next larger power of 2
y = fft(x,nfft); % Fast Fourier Transform
y = abs(y.^2); % raw power spectrum density
y = y(1:1+nfft/2); % half-spectrum
[v,k] = max(y); % find maximum
f_scale = (0:nfft/2)* Fs/nfft; % frequency scale
plot(f_scale, y),axis('tight'),grid('on'),title('Dominant Frequency')
fest = f_scale(k); % dominant frequency estimate
fprintf('Dominant freq.: true %f Hz, estimated %f Hznn\n', fest, fest)
fprintf('Frequency step (resolution) = %f Hznn\n', f_scale(2))
How can I write the code instead of the given vector value (i.e. x = [10,120,130,120,120,100,123,456,78,89];) but a real time audio signal from my laptop?
Thanks.
1 Comment
Jonas
on 27 May 2022
you can use the output of device reader as x. but window you signal before using fft. and of course think about the resolition of you fft, if you take only one buffer of samples (e.g. 512 sameples) as fft input. you could also collect the data of multiple buffer outputs and fft that, it depends on your need of fft resolution, wanted reaction time of you fft and the lrocessing power if you pc
Answers (1)
Sudarsanan A K
on 22 Jan 2024
Hello Taehyung Kim,
To analyze the dominant frequency of a real-time audio signal from your laptop's microphone, you will need to modify the second code snippet to process the audio data captured by "audioDeviceReader" in the first code snippet.
Here is how you can integrate the two pieces of code:
- Read audio data from the microphone using "audioDeviceReader".
- Perform the Fast Fourier Transform (FFT) on the audio data.
- Find the dominant frequency from the FFT result.
- Display the dominant frequency.
Below is a modified code snippet that combines reading audio from the microphone and finding its dominant frequency in real-time:
clc;
clear;
close;
% Create an audio device reader and writer
devicereader = audioDeviceReader('SampleRate', 48000, 'SamplesPerFrame', 1024);
devicewriter = audioDeviceWriter('SampleRate', devicereader.SampleRate);
% Define the FFT parameters
Fs = devicereader.SampleRate; % Sampling frequency
nfft = 2048; % Number of points for FFT
% Create a figure to display the frequency
hFig = figure('Name', 'Dominant Frequency', 'NumberTitle', 'off');
hAx = axes('Parent', hFig);
xlabel(hAx, 'Frequency (Hz)');
ylabel(hAx, 'Power Spectrum Density');
title(hAx, 'Real-time Dominant Frequency');
grid(hAx, 'on');
hold(hAx, 'on');
% Set plot style
plotStyle = {'LineWidth', 2, 'Color', 'blue'};
while (1)
% Read audio frame from the microphone
audio = devicereader();
devicewriter(audio); % You can remove this line if you don't want to play back the audio
% Remove the mean to eliminate DC offset
x = audio - mean(audio);
% Perform FFT
y = fft(x, nfft);
y = abs(y.^2); % Power spectrum density
y = y(1:1+nfft/2); % Half-spectrum
% Find the dominant frequency
[v, k] = max(y);
f_scale = (0:nfft/2) * Fs / nfft;
fest = f_scale(k);
% Update the plot
hLine = plot(hAx, f_scale, y, plotStyle{:});
xlim(hAx, [0, Fs/2]); % Limit x-axis to half the sampling rate (Nyquist frequency)
ylim(hAx, [0, max(y)*1.1]); % Adjust y-axis to show a bit more than the max value
% Update the title with the current dominant frequency
title(hAx, sprintf('Dominant Frequency: %.2f Hz', fest));
% Update the figure
drawnow;
% Remove the previous line to avoid redrawing multiple lines
delete(hLine);
% Optional: Break the loop with a condition or a user input
% e.g., if you press a key, you can break the loop
% if stopConditionMet
% break;
% end
end
The output of this code for a 1 kHz sine wave audio is as shown in the figure below, which captures and plots the dominant frequency component in the real-time audio.
You can additionally refer to the following documentation links for better understanding of the "audioDeviceReader" and "audioDeviceWriter" functions, and the real-time audio processing in MATLAB.
- "audioDeviceReader": https://mathworks.com/help/audio/ref/audiodevicereader-system-object.html
- "audioDeviceWriter": https://mathworks.com/help/audio/ref/audiodevicewriter-system-object.html
- Real-TIme Audio in MATLAB: https://mathworks.com/help/audio/gs/real-time-audio-in-matlab.html
I hope this helps!
0 Comments
See Also
Categories
Find more on Audio I/O and Waveform Generation in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!