Home > ACA-Code > ComputeKey.m

ComputeKey

PURPOSE ^

computes the key of the input audio (super simple variant)

SYNOPSIS ^

function [cKey] = ComputeKey (x, f_s, afWindow, iBlockLength, iHopLength)

DESCRIPTION ^

computes the key of the input audio (super simple variant)
>
> @param x: time domain sample data, dimension samples X channels
> @param f_s: sample rate of audio data
> @param afWindow: FFT window of length iBlockLength (default: hann), can be [] empty
> @param iBlockLength: internal block length (default: 4096 samples)
> @param iHopLength: internal hop length (default: 2048 samples)
>
> @retval cKey key string
 ======================================================================

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 %computes the key of the input audio (super simple variant)
0002 %>
0003 %> @param x: time domain sample data, dimension samples X channels
0004 %> @param f_s: sample rate of audio data
0005 %> @param afWindow: FFT window of length iBlockLength (default: hann), can be [] empty
0006 %> @param iBlockLength: internal block length (default: 4096 samples)
0007 %> @param iHopLength: internal hop length (default: 2048 samples)
0008 %>
0009 %> @retval cKey key string
0010 % ======================================================================
0011 function [cKey] = ComputeKey (x, f_s, afWindow, iBlockLength, iHopLength)
0012 
0013     % set default parameters if necessary
0014     if (nargin < 5)
0015         iHopLength = 2048;
0016     end
0017     if (nargin < 4)
0018         iBlockLength = 4096;
0019     end
0020 
0021     if (nargin < 3 || isempty(afWindow))
0022         afWindow = hann(iBlockLength, 'periodic');
0023     end
0024 
0025     % key names
0026     cMajor  = char ('C Maj','C# Maj','D Maj','D# Maj','E Maj','F Maj',...
0027         'F# Maj','G Maj','G# Maj','A Maj','A# Maj','B Maj');
0028     cMinor  = char ('c min','c# min','d min','d# min','e min','f min',...
0029         'f# min','g min','g# min','a min','a# min','b min');
0030     
0031     % template pitch chroma (Krumhansl major/minor)
0032     t_pc = [6.35 2.23 3.48 2.33 4.38 4.09 2.52 5.19 2.39 3.66 2.29 2.88
0033             6.33 2.68 3.52 5.38 2.60 3.53 2.54 4.75 3.98 2.69 3.34 3.17];
0034     t_pc = diag(1 ./ sum(t_pc, 2)) * t_pc;
0035     
0036     % compute FFT window function
0037     if (length(afWindow) ~= iBlockLength)
0038         error('window length mismatch');
0039     end        
0040 
0041     % extract audio pitch chroma
0042     [v_pc, t] = computeFeature("SpectralPitchChroma", x, f_s, afWindow, iBlockLength, iHopLength);
0043 
0044     % average pitch chroma
0045     v_pc = mean(v_pc, 2);
0046     
0047     % compute manhattan distances for major and minor
0048     d = zeros(2,12);
0049     for (i = 0:11)
0050         d(:,i+1)= sum(abs(repmat(v_pc', 2, 1)-circshift(t_pc, [0 i])), 2);
0051     end
0052     [dist,iKeyIdx] = min(d,[],2);
0053     if (dist(1) < dist(2))
0054         cKey = deblank(cMajor(iKeyIdx(1), :));
0055     else
0056         cKey = deblank(cMinor(iKeyIdx(2), :));
0057     end    
0058 end

Generated on Fri 22-Apr-2022 20:59:51 by m2html © 2005