matthiasm@8
|
1 function [results, info] = chromamatthias(filename, prod, maxx)
|
matthiasm@8
|
2
|
matthiasm@8
|
3 %---------------------------------------------------------------
|
matthiasm@8
|
4 % Part of the matthiasmISMIR08 project
|
matthiasm@8
|
5 % Written by Christopher Harte, modified by Matthias Mauch
|
matthiasm@8
|
6 % @ Queen Mary, University of London
|
matthiasm@8
|
7 % 2008
|
matthiasm@8
|
8 %---------------------------------------------------------------
|
matthiasm@8
|
9
|
matthiasm@8
|
10
|
matthiasm@8
|
11 % Set up info structure (initialise variables to 0 if we don't have values
|
matthiasm@8
|
12 % now...
|
matthiasm@8
|
13
|
matthiasm@8
|
14 info = {};
|
matthiasm@8
|
15 %%
|
matthiasm@8
|
16 info.filename = filename;
|
matthiasm@8
|
17 % info.filename = '/Volumes/Music/Music/Beatles/12_-_Let_It_Be/wav/06_-_Let_It_Be.wav';
|
matthiasm@8
|
18 % info.filename = '/Volumes/Music/Music/Beatles/unrevised/01wave/01_-_I_Saw_Her_Standing_There.wav';
|
matthiasm@8
|
19 info.undertest = ''; % which algorithms are run
|
matthiasm@8
|
20
|
matthiasm@8
|
21 % Signal Parameters:
|
matthiasm@8
|
22 info.fs = 44100; % Sampling freq of audio file
|
matthiasm@8
|
23 info.downsample = 4; % downsampling factor
|
matthiasm@8
|
24 info.fsdownsampled = ...
|
matthiasm@8
|
25 info.fs / info.downsample; % fs after downsampling
|
matthiasm@8
|
26 info.preprocessing = 'downsample'; % What kind of preprocessing?
|
matthiasm@8
|
27 info.numberframes = 0; % number of frames calculated
|
matthiasm@8
|
28 info.windowlength = 0; % window length in samples
|
matthiasm@8
|
29 info.overlap = ...
|
matthiasm@8
|
30 1/8; % window overlap factor
|
matthiasm@8
|
31 info.overl = ...
|
matthiasm@8
|
32 1 - info.overlap;
|
matthiasm@8
|
33 info.hopsize = 0; % window overlap in samples
|
matthiasm@8
|
34 info.framespersecond = 0; % effective frames per second
|
matthiasm@8
|
35
|
matthiasm@8
|
36 % Constant Q parameters:
|
matthiasm@8
|
37 info.binsperoctave = 36; % bins per octave for const q
|
matthiasm@8
|
38 info.fmax = 1760; % top frequency for const q
|
matthiasm@8
|
39 info.fmin = 110; % bottom frequency for const q
|
matthiasm@8
|
40 info.numcqbins = 0; % number of bins in a Constant Q vector
|
matthiasm@8
|
41 info.sparkernelfile = ''; % mat file containing sparse spectral kernels matrix
|
matthiasm@8
|
42 info.sparsethreshold = 0.0054; % sparsekernel threshold
|
matthiasm@8
|
43 info.maxx = maxx;
|
matthiasm@8
|
44 % Get constant Q parameters - need to do this first to set window length
|
matthiasm@8
|
45 info = getcqparameters(info);
|
matthiasm@8
|
46
|
matthiasm@8
|
47 % Prepare chunking
|
matthiasm@8
|
48 info.chunkoverlap = 2 * 1/info.overlap; % frames
|
matthiasm@8
|
49 info.audiofilesize = wavread(info.filename,'size');
|
matthiasm@8
|
50 info.chunksize = 500; % frames
|
matthiasm@8
|
51 info.samplechunksize = (info.chunksize - 1) * ...
|
matthiasm@8
|
52 info.hopsize * info.downsample; % chunk length in original samples
|
matthiasm@8
|
53 info.samplechunkhopsize = (info.chunksize - 1 - info.chunkoverlap) * ...
|
matthiasm@8
|
54 info.hopsize * info.downsample;
|
matthiasm@8
|
55 info.framespersecond = info.fsdownsampled/info.hopsize;
|
matthiasm@8
|
56 %%
|
matthiasm@8
|
57 nChunk = ceil(info.audiofilesize / info.samplechunkhopsize);
|
matthiasm@8
|
58 results = {};
|
matthiasm@8
|
59 iChunk = 0;
|
matthiasm@8
|
60 for iChunk = 1:nChunk
|
matthiasm@8
|
61 %
|
matthiasm@8
|
62 info.startsample = (iChunk - 1) * info.samplechunkhopsize + 1;
|
matthiasm@8
|
63 info.endsample = min(...
|
matthiasm@8
|
64 info.startsample + info.samplechunksize -1, ...
|
matthiasm@8
|
65 info.audiofilesize(1));
|
matthiasm@8
|
66 %
|
matthiasm@8
|
67 [audiodata, info] = readaudiochunk(info);
|
matthiasm@8
|
68
|
matthiasm@8
|
69 % Perform downsampling here if required
|
matthiasm@8
|
70
|
matthiasm@8
|
71 [audiodata, info] = preprocessing(audiodata,info);
|
matthiasm@8
|
72
|
matthiasm@8
|
73 % Perform FFT
|
matthiasm@8
|
74 [fftframes,info] = bigframefft(audiodata,info);
|
matthiasm@8
|
75
|
matthiasm@8
|
76 % Harmonics adjustment
|
matthiasm@8
|
77 if prod
|
matthiasm@8
|
78 [fftframes] = prodfft(fftframes, 3);
|
matthiasm@8
|
79 end
|
matthiasm@8
|
80
|
matthiasm@8
|
81
|
matthiasm@8
|
82 % Perform Constant Q
|
matthiasm@8
|
83 [constqframes, info] = constq(fftframes,info);
|
matthiasm@8
|
84
|
matthiasm@8
|
85 % Smooth constqframes for transient removal (time direction)
|
matthiasm@8
|
86 constqframes = medfilt1(constqframes,round(info.framespersecond/2),[],2);
|
matthiasm@8
|
87
|
matthiasm@8
|
88 % 'Normalise' Constant Q
|
matthiasm@8
|
89 % constqframes = constqframes ./ repmat(sum(abs(constqframes),1),size(constqframes,1),1);
|
matthiasm@8
|
90
|
matthiasm@8
|
91 % fftframes = 10 * log10(abs(fftframes).^2);
|
matthiasm@8
|
92
|
matthiasm@8
|
93 % Calculate HPCP
|
matthiasm@8
|
94 [hpcpframes,info] = hpcp(constqframes,info);
|
matthiasm@8
|
95
|
matthiasm@8
|
96 % Peakpick HPCP
|
matthiasm@8
|
97 % [peakpickframes,info] = framepeakpick(hpcpframes,info);
|
matthiasm@8
|
98
|
matthiasm@8
|
99
|
matthiasm@8
|
100 % Calculate Tuning
|
matthiasm@8
|
101 % [tuningframes,info] = tuning(peakpickframes,info);
|
matthiasm@8
|
102
|
matthiasm@8
|
103 % Calculate slightly adjusted chromagram
|
matthiasm@8
|
104 [chromaframes, info] = tunebyshift(hpcpframes, info);
|
matthiasm@8
|
105 % figure,
|
matthiasm@8
|
106 % imagesc(info.t,[],(chromaframes')), axis xy
|
matthiasm@8
|
107
|
matthiasm@8
|
108 % put results in output structure
|
matthiasm@8
|
109 if iChunk == 1
|
matthiasm@8
|
110 % results.fftframes = fftframes;
|
matthiasm@8
|
111 % results.constqframes = constqframes;
|
matthiasm@8
|
112 % results.hpcpframes = hpcpframes;
|
matthiasm@8
|
113 results.chromaframes = chromaframes;
|
matthiasm@8
|
114 else
|
matthiasm@8
|
115 % results.fftframes = ...
|
matthiasm@8
|
116 % [results.fftframes(:,1:end-info.frameoverlap),...
|
matthiasm@8
|
117 % results.fftframes(:,end-info.frameoverlap+1:end) ...
|
matthiasm@8
|
118 % + fftframes(:,1:info.frameoverlap),...
|
matthiasm@8
|
119 % fftframes(:,info.frameoverlap+1:end)];
|
matthiasm@8
|
120 % results.constqframes = ...
|
matthiasm@8
|
121 % [results.constqframes(:,1:end-info.frameoverlap),...
|
matthiasm@8
|
122 % results.constqframes(:,end-info.frameoverlap+1:end) ...
|
matthiasm@8
|
123 % + constqframes(:,1:info.frameoverlap),...
|
matthiasm@8
|
124 % constqframes(:,info.frameoverlap+1:end)];
|
matthiasm@8
|
125 % results.hpcpframes = ...
|
matthiasm@8
|
126 % [results.hpcpframes(1:end-info.frameoverlap,:);...
|
matthiasm@8
|
127 % results.hpcpframes(end-info.frameoverlap+1:end,:) ...
|
matthiasm@8
|
128 % + hpcpframes(1:info.frameoverlap,:);...
|
matthiasm@8
|
129 % hpcpframes(info.frameoverlap+1:end,:)];
|
matthiasm@8
|
130 x = round(info.chunkoverlap/2);
|
matthiasm@8
|
131 % results.chromaframes = chromaframes;
|
matthiasm@8
|
132 results.chromaframes = ...
|
matthiasm@8
|
133 [results.chromaframes(1:end-info.chunkoverlap+x,:);...
|
matthiasm@8
|
134 chromaframes(2+x:end,:)];
|
matthiasm@8
|
135 end
|
matthiasm@8
|
136 end
|
matthiasm@8
|
137 info.numberframes = size(results.chromaframes,1);
|
matthiasm@8
|
138 info.t = ((0:info.numberframes-1) * info.hopsize) / info.fsdownsampled; |