Mercurial > hg > camir-aes2014
diff toolboxes/MIRtoolbox1.3.2/MIRToolbox/@mircepstrum/mircepstrum.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/MIRtoolbox1.3.2/MIRToolbox/@mircepstrum/mircepstrum.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,149 @@ +function varargout = mircepstrum(orig,varargin) +% s = mircepstrum(x) computes the cepstrum, which indicates +% periodicities, and is used for instance for pitch detection. +% x can be either a spectrum, an audio signal, or the name of an audio file. +% Optional parameter: +% mircepstrum(...,'Min',min) specifies the lowest delay taken into +% consideration, in seconds. +% Default value: 0.0002 s (corresponding to a maximum frequency of +% 5 kHz). +% mircepstrum(...,'Max',max) specifies the highest delay taken into +% consideration, in seconds. +% Default value: 0.05 s (corresponding to a minimum frequency of +% 20 Hz). +% mircepstrum(...,'Freq') represents the cepstrum in the frequency +% domain. + + mi.key = 'Min'; + mi.type = 'Integer'; + mi.default = 0.0002; + mi.unit = {'s','Hz'}; + mi.defaultunit = 's'; + mi.opposite = 'ma'; + option.mi = mi; + + ma.key = 'Max'; + ma.type = 'Integer'; + ma.default = .05; + ma.unit = {'s','Hz'}; + ma.defaultunit = 's'; + ma.opposite = 'mi'; + option.ma = ma; + + fr.key = 'Freq'; + fr.type = 'Boolean'; + fr.default = 0; + option.fr = fr; + + complex.key = 'Complex'; + complex.type = 'Boolean'; + complex.default = 0; + option.complex = complex; + +specif.option = option; + +specif.defaultframelength = 0.05; +specif.defaultframehop = 0.5; + +varargout = mirfunction(@mircepstrum,orig,varargin,nargout,specif,@init,@main); + + +function [x type] = init(x,option) +if not(isamir(x,'mircepstrum')) + x = mirspectrum(x); +end +type = 'mircepstrum'; + + +function c = main(orig,option,postoption) +if iscell(orig) + orig = orig{1}; +end +c.phase = []; +if isa(orig,'mircepstrum') + c.freq = orig.freq; +else + c.freq = 0; +end +c = class(c,'mircepstrum',mirdata(orig)); +c = purgedata(c); +c = set(c,'Title','Cepstrum','Abs','quefrency (s)','Ord','magnitude'); + +if isa(orig,'mircepstrum') + if option.ma < Inf || option.mi > 0 || get(orig,'FreqDomain') + mag = get(orig,'Magnitude'); + pha = get(orig,'Phase'); + que = get(orig,'Quefrency'); + for h = 1:length(mag) + for k = 1:length(mag{h}) + if get(orig,'FreqDomain') + mag{h}{k} = flipud(mag{h}{k}); + que{h}{k} = flipud(1./que{h}{k}); + pha{h}{k} = flipud(pha{h}{k}); + end + range = find(que{h}{k}(:,1,1) <= option.ma & ... + que{h}{k}(:,1,1) >= option.mi); + mag{h}{k} = mag{h}{k}(range,:,:); + pha{h}{k} = pha{h}{k}(range,:,:); + que{h}{k} = que{h}{k}(range,:,:); + end + end + c = set(c,'Magnitude',mag,'Phase',pha,'Quefrency',que,'FreqDomain',0); + end + c = modif(c,option); +elseif isa(orig,'mirspectrum') + mag = get(orig,'Magnitude'); + pha = get(orig,'Phase'); + f = get(orig,'Sampling'); + q = cell(1,length(mag)); + for h = 1:length(mag) + len = ceil(option.ma*f{h}); + start = ceil(option.mi*f{h})+1; + q{h} = cell(1,length(mag{h})); + for k = 1:length(mag{h}) + m = mag{h}{k}.*exp(1i*pha{h}{k}); + m = [m(1:end-1,:) ; conj(flipud(m))]; % Reconstitution of the complete abs(FFT) + if not(option.complex) + m = abs(m); + end + m = log(m); + c0=fft(m); + q0=repmat((0:(size(c0,1)-1))'/f{k},[1,size(m,2),size(m,3)]); + len = min(len,floor(size(c0,1)/2)); + mag{h}{k} = abs(c0(start:len,:,:)); + if option.complex + pha{h}{k} = unwrap(angle(c0(start:len,:,:))); + else + pha{h}{k} = nan(size(c0(start:len,:,:))); + end + q{h}{k} = q0(start:len,:,:); + end + end + c = set(c,'Magnitude',mag,'Phase',pha,'Quefrency',q); + c = modif(c,option); +end + + +function c = modif(c,option) +mag = get(c,'Magnitude'); +que = get(c,'Quefrency'); +if option.fr && not(get(c,'FreqDomain')) + for k = 1:length(mag) + for l = 1:length(mag{k}) + m = mag{k}{l}; + q = que{k}{l}; + if not(isempty(m)) + if q(1,1) == 0 + m = m(2:end,:,:); + q = q(2:end,:,:); + end + m = flipud(m); + q = flipud(1./q); + end + mag{k}{l} = m; + que{k}{l} = q; + end + end + c = set(c,'FreqDomain',1,'Abs','frequency (Hz)'); +end +c = set(c,'Magnitude',mag,'Quefrency',que,'Freq'); \ No newline at end of file