Daniel@0: function varargout = mirtonalcentroid(orig,varargin) Daniel@0: % c = mirtonalcentroid(x) calculates the 6-dimensional tonal centroid Daniel@0: % vector from the chromagram. Daniel@0: % It corresponds to a projection of the chords along circles of fifths, Daniel@0: % of minor thirds, and of major thirds. Daniel@0: % [c ch] = mirtonalcentroid(x) also returns the intermediate chromagram. Daniel@0: % Daniel@0: % C. A. Harte and M. B. Sandler, Detecting harmonic change in musical Daniel@0: % audio, in Proceedings of Audio and Music Computing for Multimedia Daniel@0: % Workshop, Santa Barbara, CA, 2006. Daniel@0: Daniel@0: frame.key = 'Frame'; Daniel@0: frame.type = 'Integer'; Daniel@0: frame.number = 2; Daniel@0: frame.default = [0 0]; Daniel@0: frame.keydefault = [.743 .1]; Daniel@0: option.frame = frame; Daniel@0: Daniel@0: specif.option = option; Daniel@0: Daniel@0: varargout = mirfunction(@mirtonalcentroid,orig,varargin,nargout,specif,@init,@main); Daniel@0: Daniel@0: Daniel@0: function [c type] = init(orig,option) Daniel@0: if option.frame.length.val Daniel@0: c = mirchromagram(orig,'Frame',option.frame.length.val,... Daniel@0: option.frame.length.unit,... Daniel@0: option.frame.hop.val,... Daniel@0: option.frame.hop.unit); Daniel@0: else Daniel@0: c = mirchromagram(orig); Daniel@0: end Daniel@0: type = 'mirtonalcentroid'; Daniel@0: Daniel@0: Daniel@0: function tc = main(ch,option,postoption) Daniel@0: if iscell(ch) Daniel@0: ch = ch{1}; Daniel@0: end Daniel@0: if isa(ch,'mirtonalcentroid') Daniel@0: tc = orig; Daniel@0: ch = []; Daniel@0: else Daniel@0: x1 = sin(pi*7*(0:11)/6)'; Daniel@0: y1 = cos(pi*7*(0:11)/6)'; Daniel@0: % minor thirds circle Daniel@0: x2 = sin(pi*3*(0:11)/2)'; Daniel@0: y2 = cos(pi*3*(0:11)/2)'; Daniel@0: % major thirds circle Daniel@0: x3 = 0.5 * sin(pi*2*(0:11)/3)'; Daniel@0: y3 = 0.5 * cos(pi*2*(0:11)/3)'; Daniel@0: c = [x1 y1 x2 y2 x3 y3]; Daniel@0: c = c'; Daniel@0: tc = class(struct,'mirtonalcentroid',mirdata(ch)); Daniel@0: tc = purgedata(tc); Daniel@0: tc = set(tc,'Title','Tonal centroid','Abs','dimensions','Ord','position'); Daniel@0: m = get(ch,'Magnitude'); Daniel@0: %disp('Computing tonal centroid...') Daniel@0: n = cell(1,length(m)); % The final structured list of magnitudes. Daniel@0: d = cell(1,length(m)); % The final structured list of centroid dimensions. Daniel@0: for i = 1:length(m) Daniel@0: mi = m{i}; Daniel@0: if not(iscell(mi)) Daniel@0: mi = {mi}; Daniel@0: end Daniel@0: ni = cell(1,length(mi)); % The list of magnitudes. Daniel@0: di = cell(1,length(mi)); % The list of centroid dimensions. Daniel@0: for j = 1:length(mi) Daniel@0: mj = mi{j}; Daniel@0: ni{j} = zeros(6,size(mj,2),size(mi,3)); Daniel@0: for k = 1:size(mj,3) Daniel@0: ni{j}(:,:,k) = c * mj(:,:,k); Daniel@0: end Daniel@0: di{j} = repmat((1:6)',[1,size(mj,2),size(mi,3)]); Daniel@0: end Daniel@0: n{i} = ni; Daniel@0: d{i} = di; Daniel@0: end Daniel@0: tc = set(tc,'Positions',n,'Dimensions',d); Daniel@0: end Daniel@0: tc = {tc,ch};