function [ logFreqLogMagA, logFreqAxis ] = logFreqLogMag( A, deltaF, binsPerOctave, upperFreq, lowerFreq, logComp ) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Name: logFreqLogMag % Date: April 2018 % Programmer: Christian Dittmar % % Given a magnitude spectrogram, this function maps it onto a compact % representation with logarithmically spaced frequency axis and logarithmic % magnitude compression. % % Input: A the real-valued magnitude spectrogram oriented as % numBins x numFrames, it can also be given as a % cell-array containing mutiple spectrograms % deltaF the spectral resolution of the spectrogram % binsPerOctave the spectral selectivity of the log-freq axis % upperFreq the lower frequency border % lowerFreq the upper frequency border % % Output: % logFreqLogMagA the log-magnitude spectrogram on logarithmically % spaced frequency axis % logFreqAxis a vector giving the center frequencies of each bin % along the logarithmically spaced frequency axis % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % If you use the 'NMF toolbox' please refer to: % [1] Patricio López-Serrano, Christian Dittmar, Yiğitcan Özer, and Meinard % Müller % NMF Toolbox: Music Processing Applications of Nonnegative Matrix % Factorization % In Proceedings of the International Conference on Digital Audio Effects % (DAFx), 2019. % % License: % This file is part of 'NMF toolbox'. % https://www.audiolabs-erlangen.de/resources/MIR/NMFtoolbox/ % 'NMF 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 % the Free Software Foundation, either version 3 of the License, or (at % your option) any later version. % % 'NMF 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 'NMF toolbox'. If not, see http://www.gnu.org/licenses/. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Check parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% if ~exist('binsPerOctave') | isempty(binsPerOctave) binsPerOctave = 36; end if ~exist('upperFreq') | isempty(upperFreq) upperFreq = 22050; % should be checked end if ~exist('lowerFreq') | isempty(lowerFreq) lowerFreq = midi2freq(24); end if ~exist('logComp', 'var') || isempty(logComp) logComp = 1; end % convert to cell array if necessary if ~iscell(A) wasMatInput = true; A = mat2cell(A,size(A,1),size(A,2)); else wasMatInput = false; end % get number of components numComp = length(A); for k = 1:numComp % get component spectrogram compA = A{k}; % get dimensions [numLinBins, numFrames] = size(compA); % set up linear frequency axis linFreqAxis = [0:numLinBins-1]*deltaF; % get upper limit upperFreq = linFreqAxis(end); % set up logarithmic frequency axis numLogBins = ceil( binsPerOctave*log2( upperFreq / lowerFreq )); logFreqAxis = [0:numLogBins-1]'; logFreqAxis = lowerFreq * power(2.0, logFreqAxis / binsPerOctave); % map to logarithmic axis by means of linear interpolation logBinAxis = logFreqAxis / deltaF; % do not use the interp1 function, since it requires the Signal % Processing Toolbox floorBinAxis = floor(logBinAxis); ceilBinAxis = floorBinAxis+1; fraction = logBinAxis-floorBinAxis; % get magnitude values floorMag = compA(floorBinAxis,:); ceilMag = compA(ceilBinAxis,:); % compute weighted sum logFreqA = bsxfun(@times,floorMag,(1-fraction)) + bsxfun(@times,ceilMag,fraction); % apply magnitude compression logFreqLogMagA{k} = log(1 + (logComp .* logFreqA)); end % revert back to matrix if necessary if wasMatInput logFreqLogMagA = cell2mat(logFreqLogMagA); end end