# HG changeset patch # User cannam # Date 1213796340 0 # Node ID 76e255118810b212489b04c9bae8ef6392759c7c # Parent 84d41c790d4f75cb7ff3af590cd6d6963ef62bb0 * Update to current libxtract SVN; add patch from Dan S for MFCC range diff -r 84d41c790d4f -r 76e255118810 libmain.cpp --- a/libmain.cpp Thu Feb 28 12:31:03 2008 +0000 +++ b/libmain.cpp Wed Jun 18 13:39:00 2008 +0000 @@ -46,9 +46,8 @@ static std::map pluginAdapterMap; -// Define this if libxtract has been compiled with XTRACT_FFT and +// Note: libxtract must have been compiled with XTRACT_FFT and // linked with fftw3 -#define HAVE_XTRACT_FFT 1 const VampPluginDescriptor *vampGetPluginDescriptor(unsigned int vampApiVersion, unsigned int index) @@ -66,21 +65,19 @@ const unsigned int missingFeatures[] = { XTRACT_SPECTRAL_MEAN, // Just a wrapper for XTRACT_SPECTRAL_CENTROID + XTRACT_FLATNESS_DB, // appears to implement only the db part XTRACT_POWER, // not implemented XTRACT_HPS, // "this function doesn't work properly" + XTRACT_LNORM, // not quite sure what it is or its parameters XTRACT_FLUX, // not implemented XTRACT_ATTACK_TIME, // not implemented XTRACT_DECAY_TIME, // not implemented - XTRACT_DELTA_FEATURE, // not implemented (and not meaningful?) - -#ifndef HAVE_XTRACT_FFT - XTRACT_MAGNITUDE_SPECTRUM, // requires fftw -#endif - XTRACT_AUTOCORRELATION_FFT, // requires fftw -- also erroneous -#ifndef HAVE_XTRACT_FFT - XTRACT_MFCC, // requires fftw - XTRACT_DCT, // requires fftw -#endif + XTRACT_DIFFERENCE_VECTOR, // not meaningful (this used to be XTRACT_DELTA_FEATURE) + XTRACT_AUTOCORRELATION_FFT, // apparently erroneous + XTRACT_LPC, // not meaningful and/or not implemented here + XTRACT_LPCC, // not meaningful and/or not implemented here + XTRACT_SUBBANDS, // not meaningful in isolation + XTRACT_WINDOWED // not meaningful }; for (unsigned int i = 0; diff -r 84d41c790d4f -r 76e255118810 plugins/XTractPlugin.cpp --- a/plugins/XTractPlugin.cpp Thu Feb 28 12:31:03 2008 +0000 +++ b/plugins/XTractPlugin.cpp Wed Jun 18 13:39:00 2008 +0000 @@ -42,7 +42,9 @@ m_harmonicThreshold(.1), m_minFreq(80), m_maxFreq(18000), - m_coeffCount(20), + m_coeffCount(40), + m_highestCoef(20), + m_lowestCoef(0), m_mfccFilters(0), m_mfccStyle((int)XTRACT_EQUAL_GAIN), m_barkBandLimits(0), @@ -109,16 +111,22 @@ string XTractPlugin::getCopyright() const { - char year[12]; string text = "Copyright 2006 Jamie Bullock, plugin Copyright 2006 Queen Mary, University of London. "; string method = ""; method += xtDescriptor()->algo.author; - sprintf(year, " (%d)", xtDescriptor()->algo.year); - method += year; - if (method != "") text += "Method from " + method + ". "; + if (method != "") { + int year = xtDescriptor()->algo.year; + if (year != 0) { + char yearstr[12]; + sprintf(yearstr, " (%d)", year); + method += yearstr; + } + text += "Method from " + method + ". "; + } + text += "Distributed under the GNU General Public License"; return text; } @@ -134,6 +142,7 @@ } +bool XTractPlugin::m_anyInitialised = false; bool XTractPlugin::initialise(size_t channels, size_t stepSize, size_t blockSize) @@ -145,10 +154,26 @@ if (channels < getMinChannelCount() || channels > getMaxChannelCount()) return false; + if (blockSize != getPreferredBlockSize()) { + cerr << "XTractPlugin::initialise: ERROR: " + << "Only the standard block size of " << getPreferredBlockSize() + << " is supported (owing to global FFT initialisation requirements)" << endl; + return false; + } + m_channels = channels; m_stepSize = stepSize; m_blockSize = blockSize; + if (!m_anyInitialised) { + m_anyInitialised = true; + // initialise libxtract + xtract_init_fft(m_blockSize, XTRACT_SPECTRUM); + xtract_init_fft(m_blockSize, XTRACT_AUTOCORRELATION_FFT); + xtract_init_fft(m_blockSize, XTRACT_DCT); + xtract_init_fft(m_blockSize, XTRACT_MFCC); + } + if (donor == XTRACT_INIT_MFCC) { m_mfccFilters = new float *[m_coeffCount]; @@ -192,7 +217,8 @@ case XTRACT_ASDF: m_outputBinCount = m_blockSize; break; case XTRACT_MFCC: - m_outputBinCount = m_coeffCount; break; + m_outputBinCount = (m_highestCoef - m_lowestCoef)+1; break; + //m_outputBinCount = m_coeffCount; break; case XTRACT_BARK_COEFFICIENTS: m_outputBinCount = XTRACT_BARK_BANDS; break; default: @@ -265,9 +291,29 @@ list.push_back(desc); desc.identifier = "bands"; - desc.name = "Mel Frequency Bands"; + desc.name = "# Mel Frequency Bands"; desc.minValue = 10; - desc.maxValue = 30; + desc.maxValue = 80; + desc.defaultValue = 40; + desc.unit = ""; + desc.isQuantized = true; + desc.quantizeStep = 1; + list.push_back(desc); + + desc.identifier = "lowestcoef"; + desc.name = "Lowest Coefficient Returned"; + desc.minValue = 0; + desc.maxValue = 80; + desc.defaultValue = 0; + desc.unit = ""; + desc.isQuantized = true; + desc.quantizeStep = 1; + list.push_back(desc); + + desc.identifier = "highestcoef"; + desc.name = "Highest Coefficient Returned"; + desc.minValue = 0; + desc.maxValue = 80; desc.defaultValue = 20; desc.unit = ""; desc.isQuantized = true; @@ -335,6 +381,8 @@ if (param == "minfreq") return m_minFreq; if (param == "maxfreq") return m_maxFreq; if (param == "bands") return m_coeffCount; + if (param == "lowestcoef") return m_lowestCoef; + if (param == "highestcoef") return m_highestCoef; if (param == "style") return m_mfccStyle; } @@ -352,6 +400,16 @@ if (param == "minfreq") m_minFreq = value; else if (param == "maxfreq") m_maxFreq = value; else if (param == "bands") m_coeffCount = lrintf(value + .1); + else if (param == "lowestcoef"){ + m_lowestCoef = lrintf(value + .1); + if(m_lowestCoef >= m_coeffCount) m_lowestCoef = m_coeffCount - 1; + if(m_lowestCoef > m_highestCoef) m_lowestCoef = m_highestCoef; + } + else if (param == "highestcoef"){ + m_highestCoef = lrintf(value + .1); + if(m_highestCoef >= m_coeffCount) m_highestCoef = m_coeffCount - 1; + if(m_highestCoef < m_lowestCoef) m_highestCoef = m_lowestCoef; + } else if (param == "style") m_mfccStyle = lrintf(value + .1); } @@ -382,7 +440,7 @@ d.isQuantized = false; d.sampleType = OutputDescriptor::OneSamplePerStep; - if(xtFd->is_scalar){ + if (xtFd->is_scalar){ switch(xtFd->result.scalar.unit){ case XTRACT_HERTZ: d.unit = "Hz"; break; case XTRACT_DBFS: d.unit = "dB"; break; @@ -396,8 +454,6 @@ d.identifier = "amplitudes"; d.name = "Peak Amplitudes"; d.description = ""; - m_outputDescriptors.push_back(d); - } } @@ -613,7 +669,7 @@ data_temp = new float[N]; if (m_xtFeature == XTRACT_ROLLOFF || - m_xtFeature == XTRACT_PEAK_SPECTRUM || needPeaks) { + m_xtFeature == XTRACT_PEAK_SPECTRUM || needPeaks) { argf[0] = m_inputSampleRate / N; if(m_xtFeature == XTRACT_ROLLOFF) argf[1] = m_rolloffThreshold; @@ -748,7 +804,7 @@ bool good = true; for (size_t n = 0; n < m_outputDescriptors[output].binCount; ++n) { - float value = m_resultBuffer[index]; + float value = m_resultBuffer[index + m_lowestCoef]; if (isnan(value) || isinf(value)) { good = false; index += (m_outputDescriptors[output].binCount - n); diff -r 84d41c790d4f -r 76e255118810 plugins/XTractPlugin.h --- a/plugins/XTractPlugin.h Thu Feb 28 12:31:03 2008 +0000 +++ b/plugins/XTractPlugin.h Wed Jun 18 13:39:00 2008 +0000 @@ -79,7 +79,9 @@ float m_minFreq; float m_maxFreq; - size_t m_coeffCount; + int m_coeffCount; + int m_highestCoef; + int m_lowestCoef; float **m_mfccFilters; int m_mfccStyle; @@ -96,6 +98,7 @@ size_t m_outputBinCount; bool m_initialised; + static bool m_anyInitialised; }; diff -r 84d41c790d4f -r 76e255118810 vamp-libxtract.cat --- a/vamp-libxtract.cat Thu Feb 28 12:31:03 2008 +0000 +++ b/vamp-libxtract.cat Wed Jun 18 13:39:00 2008 +0000 @@ -18,7 +18,7 @@ vamp:vamp-libxtract:smoothness::Low Level Features vamp:vamp-libxtract:spread::Low Level Features vamp:vamp-libxtract:zcr::Low Level Features -vamp:vamp-libxtract:spectral_rolloff::Low Level Features +vamp:vamp-libxtract:rolloff::Low Level Features vamp:vamp-libxtract:loudness::Low Level Features vamp:vamp-libxtract:flatness::Low Level Features vamp:vamp-libxtract:tonality::Low Level Features