c@225: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ c@225: /* c@225: QM DSP Library c@225: c@225: Centre for Digital Music, Queen Mary, University of London. c@225: This file copyright 2005-2006 Christian Landone. c@225: All rights reserved. c@225: */ c@225: c@225: #include "ConstantQ.h" c@225: #include "dsp/transforms/FFT.h" c@225: c@225: //--------------------------------------------------------------------------- c@225: // nextpow2 returns the smallest integer n such that 2^n >= x. c@225: static double nextpow2(double x) { c@225: double y = ceil(log(x)/log(2.0)); c@225: return(y); c@225: } c@225: c@225: static double squaredModule(const double & xx, const double & yy) { c@225: return xx*xx + yy*yy; c@225: } c@225: c@225: //---------------------------------------------------------------------------- c@225: c@225: ConstantQ::ConstantQ( CQConfig Config ) c@225: { c@225: initialise( Config ); c@225: } c@225: c@225: ConstantQ::~ConstantQ() c@225: { c@225: deInitialise(); c@225: } c@225: c@225: //---------------------------------------------------------------------------- c@225: void ConstantQ::sparsekernel() c@225: { c@225: //generates spectral kernel matrix (upside down?) c@225: // initialise temporal kernel with zeros, twice length to deal w. complex numbers c@225: c@225: double* hammingWindowRe = new double [ m_FFTLength ]; c@225: double* hammingWindowIm = new double [ m_FFTLength ]; c@225: double* transfHammingWindowRe = new double [ m_FFTLength ]; c@225: double* transfHammingWindowIm = new double [ m_FFTLength ]; c@225: c@225: for (unsigned u=0; u < m_FFTLength; u++) c@225: { c@225: hammingWindowRe[u] = 0; c@225: hammingWindowIm[u] = 0; c@225: } c@225: c@225: c@225: // Here, fftleng*2 is a guess of the number of sparse cells in the matrix c@225: // The matrix K x fftlength but the non-zero cells are an antialiased c@225: // square root function. So mostly is a line, with some grey point. c@225: m_sparseKernelIs.reserve( m_FFTLength*2 ); c@225: m_sparseKernelJs.reserve( m_FFTLength*2 ); c@225: m_sparseKernelRealValues.reserve( m_FFTLength*2 ); c@225: m_sparseKernelImagValues.reserve( m_FFTLength*2 ); c@225: c@225: // for each bin value K, calculate temporal kernel, take its fft to c@225: //calculate the spectral kernel then threshold it to make it sparse and c@225: //add it to the sparse kernels matrix c@225: double squareThreshold = m_CQThresh * m_CQThresh; c@225: c@225: FFT m_FFT; c@225: c@225: for (unsigned k = m_uK; k--; ) c@225: { c@225: // Computing a hamming window c@225: const unsigned hammingLength = (int) ceil( m_dQ * m_FS / ( m_FMin * pow(2,((double)(k))/(double)m_BPO))); c@225: for (unsigned i=0; i