1 |
4 |
dgisselq |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
2 |
|
|
%%
|
3 |
|
|
%% Filename: showspectrogram.m
|
4 |
|
|
%%
|
5 |
|
|
%% Project: A Wishbone Controlled PWM (audio) controller
|
6 |
|
|
%%
|
7 |
|
|
%% Purpose: To generate a spectrogram image which can then be used to
|
8 |
|
|
%% evaluate the wavfp.dbl file produced by the pdmdemo executable
|
9 |
|
|
%% in this directory.
|
10 |
|
|
%%
|
11 |
|
|
%% This script has been tested with Octave, and it is known to work with
|
12 |
|
|
%% Octave. While it may work within Matlab as well, no representation is
|
13 |
|
|
%% being made to that effect.
|
14 |
|
|
%%
|
15 |
|
|
%% Creator: Dan Gisselquist, Ph.D.
|
16 |
|
|
%% Gisselquist Technology, LLC
|
17 |
|
|
%%
|
18 |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
19 |
|
|
%%
|
20 |
|
|
%% Copyright (C) 2017, Gisselquist Technology, LLC
|
21 |
|
|
%%
|
22 |
|
|
%% This program is free software (firmware): you can redistribute it and/or
|
23 |
|
|
%% modify it under the terms of the GNU General Public License as published
|
24 |
|
|
%% by the Free Software Foundation, either version 3 of the License, or (at
|
25 |
|
|
%% your option) any later version.
|
26 |
|
|
%%
|
27 |
|
|
%% This program is distributed in the hope that it will be useful, but WITHOUT
|
28 |
|
|
%% ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
|
29 |
|
|
%% FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
30 |
|
|
%% for more details.
|
31 |
|
|
%%
|
32 |
|
|
%% You should have received a copy of the GNU General Public License along
|
33 |
|
|
%% with this program. (It's in the $(ROOT)/doc directory. Run make with no
|
34 |
|
|
%% target there if the PDF file isn't present.) If not, see
|
35 |
|
|
%% <http://www.gnu.org/licenses/> for a copy.
|
36 |
|
|
%%
|
37 |
|
|
%% License: GPL, v3, as defined and found on www.gnu.org,
|
38 |
|
|
%% http://www.gnu.org/licenses/gpl.html
|
39 |
|
|
%%
|
40 |
|
|
%%
|
41 |
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
42 |
|
|
%%
|
43 |
|
|
%%
|
44 |
|
|
function [img] = showspectrogram(fname)
|
45 |
|
|
% Read the waveform into memory
|
46 |
|
|
fid = fopen(fname,'r');
|
47 |
|
|
dat = fread(fid, inf, 'double');
|
48 |
|
|
fclose(fid);
|
49 |
|
|
|
50 |
|
|
% You can plot it at this point if you would like
|
51 |
|
|
% plot(dat);
|
52 |
|
|
|
53 |
|
|
sample_rate = 44.1e3;
|
54 |
|
|
window_length = 512; % Size of the FFT
|
55 |
|
|
Nc = 256; % Number of colors
|
56 |
|
|
|
57 |
|
|
h = hanning(window_length); % About 1 ms
|
58 |
|
|
rows = (length(dat)-length(h)) / length(h) * 2
|
59 |
|
|
img = zeros(length(h)/2, rows);
|
60 |
|
|
size(img)
|
61 |
|
|
|
62 |
|
|
for n=1:rows
|
63 |
|
|
cut = dat((1:length(h)) + (n-1)*length(h)/2);
|
64 |
|
|
cutf = abs(fft(cut.*h)).^2;
|
65 |
|
|
img(:,n) = cutf(1:(length(h)/2));
|
66 |
|
|
end
|
67 |
|
|
|
68 |
|
|
mintime = 0;
|
69 |
|
|
maxtime = rows / sample_rate * window_length / 2;
|
70 |
|
|
minfreq = 0;
|
71 |
|
|
maxfreq = 0.5 * sample_rate;
|
72 |
|
|
|
73 |
|
|
% Normalize the image so that the maximum value is one.
|
74 |
|
|
img = img ./ max(max(img));
|
75 |
|
|
|
76 |
|
|
%
|
77 |
|
|
% Turn out spectrogram image into dB
|
78 |
|
|
%
|
79 |
|
|
% Adding 1e-8 is useful for artificially forcing the floor of the
|
80 |
|
|
% image to be at a particular value, as well as for keeping the log
|
81 |
|
|
% from reporting values too negative to plot successfully.
|
82 |
|
|
img = 10 * log(img + 1e-8)/log(10);
|
83 |
|
|
|
84 |
|
|
img = (img + 80)/80;
|
85 |
|
|
colormap(mymap(256));
|
86 |
|
|
image([mintime, maxtime], [minfreq, maxfreq/1e3], img * Nc);
|
87 |
|
|
ylabel('Frequency (kHz)');
|
88 |
|
|
xlabel('Time (s)');
|
89 |
|
|
|
90 |
|
|
% Trim this image output to the relevant portion of the output
|
91 |
|
|
axis([0, 6.2, 0, maxfreq/1e3]);
|
92 |
|
|
|
93 |
|
|
% For the plot, comment out the img ./ max(max(img)) line, as well as the
|
94 |
|
|
% img = (img+80)/80 line. Then you can call this as:
|
95 |
|
|
% img = showspectrogram('pdm8k-weak.dbl');
|
96 |
|
|
% imgpwm = showspectrogram('pwm8k-weak.dbl');
|
97 |
|
|
%
|
98 |
|
|
% freq = (0:(window_length-1))/(window_length)*(sample_rate/2/1e3)
|
99 |
|
|
% plot(freq,img(:,1400),'b;PDM;',freq,imgpwm(:,1400),'r;PWM;');
|
100 |
|
|
% grid on; xlabel('Frequency (kHz)'); ylabel('Volume (dB)');
|
101 |
|
|
% axis([0,22,-70,50]);
|