On the internet, I have seen people use Matplotlib/Python and short-time fourier transformations to create spectrograms. Are their other formula/algorithms to create spectrograms? And are they possible to implement in python or be called through command prompt?
3 Answers
so here's a short MATLAB script that will compute and draw a spectrogram.
if ~exist('inputFile', 'var')
inputFile = 'tom_hit.wav';
end
if ~exist('frameLength', 'var')
frameLength = 8192;
end
frameLength = 2.^(ceil(log2(frameLength) - 1e-10));
if ~exist('frameHop', 'var')
frameHop = 256;
end
frameHop = 2.^(floor(log2(frameHop) + 1e-10));
frameHop = min(frameHop, frameLength/2); % insure at least 50% overlap
[inputBuffer, Fs] = audioread(inputFile);
[inputFileSize, nChannels] = size(inputBuffer);
nSamples = 2.^(ceil(log2(inputFileSize + frameLength) - 1e-10)); % zero-pad on both sides and round up to nearest power of 2
nFrames = floor((nSamples-frameLength)/frameHop);
x = zeros(nSamples, 1);
x(frameLength/2+1:frameLength/2+inputFileSize) = inputBuffer(:,1); % use left channel only, zero-pad half frame on both sides
clear inputBuffer; % free this memory
dB_floor = -90;
beta = 5;
frameWindow = gausswin(frameLength, beta); % gaussian window
XX = zeros(nFrames, frameLength/2+1);
for frame = 1:nFrames
X = fft( fftshift( x((frame-1)*frameHop+1:(frame-1)*frameHop+frameLength, 1).*frameWindow ) );
XX(frame,:) = abs( X(1:frameLength/2+1) ).^2 + 10^(dB_floor/10); % leave XX as energy with dB_floor dB floor.
end
figure(1);
[taxis, faxis] = meshgrid(0:Fs/frameLength:Fs/2, 0:frameHop/Fs:(nFrames-1)*frameHop/Fs);
surf(faxis, taxis, 10*log10(XX), 'EdgeColor','none', 'LineStyle','none');
xlabel('sec')
ylabel('Hz')
zlabel('dB')
view(40,40);
Sometimes people use time-frequency representations (TFRs) as a generalization of the spectrogram.
This C code calculates some different TFRs of Cohen’s class: bilinear TFRs.
There are spectral analyzers that come with executables (and sometimes source code) like:
- Spek – Acoustic Spectrum Analyser (Unix, Windows and Mac OS X)
- BaudLine (Unix, Windows and Mac OS X)
- Spectro
- Sonic Visualiser
- SoX (which is identified as having command line)
Even FFMpeg can do the job: ffmpeg -i inputfile.mp3 -lavfi showspectrumpic=s=800x400:mode=separate spectrogram.png
The basic formula is typically composed of:
- select a frame, and apply a window,
- compute a Fourier transform,
- display magnitude or square magnitude values.
as detailed by Robert. As Peter wrote, there are many extensions or reformulation, termed time-frequency distributions or time-scale representations, that can be implemented as filter banks, quadratic formulae, etc. Among script language implementations, you can check:
- LTFAT: The Large Time-Frequency Analysis Toolbox
- DiscreteTFDs: Time-Frequency Analysis Software
- TFTB: Time-Frequency Toolbox
This is still an open research topic.
surf()
. is that what you're looking for? it's pretty simple. $\endgroup$