sotomie
Newbie level 6
- Joined
- Apr 5, 2013
- Messages
- 13
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,281
- Activity points
- 1,376
I've been trying to get familiar with chroma toolbox (MATLAB) ,and from where I've downloaded it,they have provided a demo program ,but i am unable to run it ..there was a command 'spectrogram' in one of the functions in that toolbox which is not supported by my version of MATLAB so after searching this problem up i got another command 'specgram' but this is also resulting in error and i've no idea how to correct it..so if anyone of you kindly help me i would be very grateful .Thanks A Lot.
error i'm getting when using 'specgram' in line 127 of function 'estimatetuning'
??? Error using ==> specgram
Requires NOVERLAP to be strictly less than the window length.
Error in ==> estimateTuning at 127
[s,f,t] = specgram(f_input, parameter.windowFunction(parameter.fftWindowLength), parameter.fftWindowLength/2, parameter.fftWindowLength, 22050);
Error in ==> demoChromaToolbox at 6
shiftFB = estimateTuning(f_audio);
error i'm getting when using 'specgram' in line 127 of function 'estimatetuning'
??? Error using ==> specgram
Requires NOVERLAP to be strictly less than the window length.
Error in ==> estimateTuning at 127
[s,f,t] = specgram(f_input, parameter.windowFunction(parameter.fftWindowLength), parameter.fftWindowLength/2, parameter.fftWindowLength, 22050);
Error in ==> demoChromaToolbox at 6
shiftFB = estimateTuning(f_audio);
Code:
clear
close all
filename = 'Systematic_Chord-C-Major_Eight-Instruments.wav';
[f_audio,sideinfo] = wav_to_audio(C:\Users\sotomie\Desktop\MATLAB-Chroma-Toolbox_2.0\'', 'data_WAV\', filename);
shiftFB = estimateTuning(f_audio);
paramPitch.winLenSTMSP = 4410;
paramPitch.shiftFB = shiftFB;
paramPitch.visualize = 1;
[f_pitch,sideinfo] = ...
audio_to_pitch_via_FB(f_audio,paramPitch,sideinfo);
paramCP.applyLogCompr = 0;
paramCP.visualize = 1;
paramCP.inputFeatureRate = sideinfo.pitch.featureRate;
[f_CP,sideinfo] = pitch_to_chroma(f_pitch,paramCP,sideinfo);
paramCLP.applyLogCompr = 1;
paramCLP.factorLogCompr = 100;
paramCLP.visualize = 1;
paramCLP.inputFeatureRate = sideinfo.pitch.featureRate;
[f_CLP,sideinfo] = pitch_to_chroma(f_pitch,paramCLP,sideinfo);
paramCENS.winLenSmooth = 21;
paramCENS.downsampSmooth = 5;
paramCENS.visualize = 1;
paramCENS.inputFeatureRate = sideinfo.pitch.featureRate;
[f_CENS,sideinfo] = pitch_to_CENS(f_pitch,paramCENS,sideinfo);
paramCRP.coeffsToKeep = [55:120];
paramCRP.visualize = 1;
paramCRP.inputFeatureRate = sideinfo.pitch.featureRate;
[f_CRP,sideinfo] = pitch_to_CRP(f_pitch,paramCRP,sideinfo);
paramSmooth.winLenSmooth = 21;
paramSmooth.downsampSmooth = 5;
paramSmooth.inputFeatureRate = sideinfo.CRP.featureRate;
[f_CRPSmoothed, featureRateSmoothed] = ...
smoothDownsampleFeature(f_CRP,paramSmooth);
parameterVis.featureRate = featureRateSmoothed;
visualizeCRP(f_CRPSmoothed,parameterVis);
Code:
function [shiftFB,centerA4,tuningSemitones,sideinfo] = estimateTuning(f_input,parameter,sideinfo)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Name: estimateTuning
% Date of Revision: 2011-03
% Programmer: Sebastian Ewert
%
% Description:
% - input is either a mono audio signal or a real valued spectrogram (magnitude or power)
% - if input is a spectrogram you have to set parameter.timeinfo and
% parameter.freqinfo (vectors defining the time and freq centers for each spectrogram bin)
% - if input is an audio signal, a sampling freq of 22050 Hz is assumed
% - guesses the tuning according to a simple energy maximizing criterion
% - output is either: what shiftFB is best to use (shiftFB \in [0:5]).
% Alternatively, the center freq for A4 is given which can be used to
% specify a filterbank on your own. The second option is more fine
% grained.
% Alternatively, it gives a tuning in semitones, which can
% easily be shifted cyclicly. For example: a tuning of -19/20 is more likely to be
% +1/20 Tuning difference.
% - parameter.numAdditionalTunings: how many tunings besides the fixed shiftFB ones
% to test. For example: If set to 3, than three additional tuning settings are
% tested for, located at 1/4, 2/4 and 3/4 semitones below the reference
% tuning. If set to 5, then at 1/6, 2/6,..., 5/6 semitones.
% - parameter.pitchRange specifies which pitches are considered for the
% tuning estimation.
% - parameter.pitchWeights: each pitch is considered according to a weight
% - Middle pitches are considered as being more important per default because
% here the frequency resolution is high enough. Additionally the piano has
% a consistent tuning only for middle pitches.
%
% Input:
% f_input
% parameter.numAdditionalTunings = 0;
% parameter.pitchRange = [21:108];
% parameter.pitchWeights = gausswin(length(parameter.pitchRange)).^2;
% parameter.fftWindowLength = 8192;
% parameter.windowFunction = @hanning;
% sideinfo
%
% Output:
% shiftFB
% centerA4
% tuningSemitones
% sideinfo
%
% License:
% This file is part of 'Chroma Toolbox'.
%
% 'Chroma Toolbox' is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 2 of the License, or
% (at your option) any later version.
%
% 'Chroma Toolbox' is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with 'Chroma Toolbox'. If not, see <http://www.gnu.org/licenses/>.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Check parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if nargin<2
parameter=[];
end
if nargin<1
error('Please specify input data');
end
if isfield(parameter,'numAdditionalTunings')==0
parameter.numAdditionalTunings = 0;
end
if isfield(parameter,'pitchRange')==0
% Which pitches to consider during the estimation
parameter.pitchRange = [21:108];
end
if isfield(parameter,'pitchWeights')==0
% assign a weight to each pitch specified in parameter.pitchRange to
% specify it's importance
parameter.pitchWeights = gausswin(length(parameter.pitchRange)).^2;
end
% the following parameters are only for audio signal input
if isfield(parameter,'fftWindowLength')==0
parameter.fftWindowLength = 8192;
end
if isfield(parameter,'windowFunction')==0
parameter.windowFunction = @hanning; % only tested with hanning.
end
if min(size(f_input)) == 1
inputIsAudioSignal = 1;
else
inputIsAudioSignal = 0;
end
if ~inputIsAudioSignal
if isfield(parameter,'freqinfo')==0
error('When using a spectrogram input you have to set parameter.freqinfo');
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Main program
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
numTunings = 6 + parameter.numAdditionalTunings;
referenceFreqsA4 = zeros(numTunings,1);
tunings = zeros(numTunings,1);
tunings(1) = 0;
tunings(2) = -1/4;
tunings(3) = -1/3;
tunings(4) = -1/2;
tunings(5) = -2/3;
tunings(6) = -3/4;
for k=1:parameter.numAdditionalTunings
tunings(k+6) = -k/(parameter.numAdditionalTunings+1);
end
referenceFreqsA4 = 2.^((69-69+tunings)/12) * 440;
if inputIsAudioSignal
[s,f,t] = spectrogram(f_input, parameter.windowFunction(parameter.fftWindowLength), parameter.fftWindowLength/2, parameter.fftWindowLength, 22050);
else
s = f_input;
f = parameter.freqinfo;
end
s = abs(s);
directFreqBinSearch = 0;
if all( (f(2:end)-f(1:end-1)) - (f(2)-f(1)) < eps )
directFreqBinSearch = 1;
end
averagedPowerSpectrogram = sum(s.^2,2);
totalPitchEnergyViaSpec = zeros(numTunings,1);
for tu=1:numTunings
centerfreqs = 2.^((parameter.pitchRange-69)/12) * referenceFreqsA4(tu);
upperborderfreqs = 2.^((parameter.pitchRange-68.5)/12) * referenceFreqsA4(tu);
lowerborderfreqs = 2.^((parameter.pitchRange-69.5)/12) * referenceFreqsA4(tu);
% build triangular filterbank for magnitude spectrogram
spectrogramFilter = zeros(length(f),1);
for k=1:length(parameter.pitchRange)
c = getCorrespondingBin(f,centerfreqs(k),directFreqBinSearch);
u = getCorrespondingBin(f,upperborderfreqs(k),directFreqBinSearch);
l = getCorrespondingBin(f,lowerborderfreqs(k),directFreqBinSearch);
% order is important here. If third parameter is < 2, then linspace
% returns the second parameter
spectrogramFilter(c:u) = parameter.pitchWeights(k) * linspace(1,0,u-c+1);
spectrogramFilter(l:c) = parameter.pitchWeights(k) * linspace(0,1,c-l+1);
end
totalPitchEnergyViaSpec(tu) = sum(spectrogramFilter.^2 .* averagedPowerSpectrogram);
end
[ignoreMe, maxIndex] = max(totalPitchEnergyViaSpec(1:6));
shiftFB = maxIndex-1;
[ignoreMe, maxIndex] = max(totalPitchEnergyViaSpec);
centerA4 = referenceFreqsA4(maxIndex);
tuningSemitones = tunings(maxIndex);
sideinfo.tuning.shiftFB = shiftFB;
sideinfo.tuning.centerA4 = centerA4;
sideinfo.tuning.tuningSemitones = tuningSemitones;
sideinfo.tuning.method = 'estimateTuningV1';
sideinfo.tuning.numAdditionalTunings = parameter.numAdditionalTunings;
sideinfo.tuning.pitchRange = parameter.pitchRange;
sideinfo.tuning.pitchWeights = parameter.pitchWeights;
sideinfo.tuning.fftWindowLength = parameter.fftWindowLength;
sideinfo.tuning.windowFunction = parameter.windowFunction;
sideinfo.tuning.inputWasAudioSignal = inputIsAudioSignal;
end
function index = getCorrespondingBin(x,sval,directSearch)
% - Finds the entry in x with the smallest absolute distance to sval.
% - x is assumed to be sorted (ascending)
% - 'directSearch' means that all values in x are equally spaced
% - x is assumed to be at least of length 2.
% - If directSearch==0 then we use binary seach to find the entry
%
% You can test the correctness of this procedure by comparing it against
% the result of: [ignoreMe index] = min(abs(x-sval))
%
% Author: Sebastian Ewert
if sval >= x(end)
index = length(x);
return;
elseif sval <= x(1)
index = 1;
return;
end
if directSearch
index = round( (sval-x(1)) / (x(2)-x(1))) + 1;
else
from=1;
to=length(x);
while from<=to
mid = round((from + to)/2);
diff = x(mid)-sval;
if diff<0 % x(mid) < sval
from=mid;
else % x(mid) => sval
to=mid;
end
if to-from==1
break;
end
end
if abs(x(from)-sval) < abs(x(to)-sval)
index = from;
else
index = to;
end
end
end