Code covered by the BSD License  

Highlights from
MIRtoolbox

image thumbnail
from MIRtoolbox by Olivier Lartillot
An innovative environment, on top of Matlab, for music and audio analysis

mircepstrum(orig,varargin)
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');

Contact us at files@mathworks.com