Chris@27: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@27: Chris@27: /* Chris@27: Sonic Visualiser Chris@27: An audio file viewer and annotation editor. Chris@27: Centre for Digital Music, Queen Mary, University of London. Chris@27: This file copyright 2006 Chris Cannam. Chris@27: Chris@27: This program is free software; you can redistribute it and/or Chris@27: modify it under the terms of the GNU General Public License as Chris@27: published by the Free Software Foundation; either version 2 of the Chris@27: License, or (at your option) any later version. See the file Chris@27: COPYING included with this distribution for more information. Chris@27: */ Chris@27: Chris@27: #ifndef _INTEGER_TIME_STRETCHER_H_ Chris@27: #define _INTEGER_TIME_STRETCHER_H_ Chris@27: Chris@27: #include "base/Window.h" Chris@27: #include "base/RingBuffer.h" Chris@27: Chris@27: #include Chris@27: Chris@27: /** Chris@27: * A time stretcher that slows down audio by an integer multiple of Chris@27: * its original duration, preserving pitch. This uses the simple Chris@27: * phase vocoder technique from DAFX pp275-276, adding a block-based Chris@27: * stream oriented API. Chris@27: * Chris@27: * Causes significant transient smearing, but sounds good for steady Chris@27: * notes and is generally predictable. Chris@27: */ Chris@27: Chris@27: class IntegerTimeStretcher Chris@27: { Chris@27: public: Chris@27: IntegerTimeStretcher(size_t ratio, Chris@27: size_t maxProcessInputBlockSize, Chris@27: size_t inputIncrement = 64, Chris@27: size_t windowSize = 2048, Chris@27: WindowType windowType = HanningWindow); Chris@27: virtual ~IntegerTimeStretcher(); Chris@27: Chris@27: void process(double *input, double *output, size_t samples); Chris@27: Chris@27: /** Chris@27: * Get the hop size for input. Smaller values may produce better Chris@27: * results, at a cost in processing time. Larger values are Chris@27: * faster but increase the likelihood of echo-like effects. The Chris@27: * default is 64, which is usually pretty good, though heavy on Chris@27: * processor power. Chris@27: */ Chris@27: size_t getInputIncrement() const { return m_n1; } Chris@27: Chris@27: /** Chris@27: * Get the window size for FFT processing. Must be larger than Chris@27: * the input and output increments. The default is 2048. Chris@27: */ Chris@27: size_t getWindowSize() const { return m_wlen; } Chris@27: Chris@27: /** Chris@27: * Get the window type. The default is a Hanning window. Chris@27: */ Chris@27: WindowType getWindowType() const { return m_window->getType(); } Chris@27: Chris@27: size_t getRatio() const { return m_ratio; } Chris@27: size_t getOutputIncrement() const { return getInputIncrement() * getRatio(); } Chris@27: size_t getProcessingLatency() const; Chris@27: Chris@27: protected: Chris@27: void processBlock(double *in, double *out); Chris@27: Chris@27: size_t m_ratio; Chris@27: size_t m_n1; Chris@27: size_t m_n2; Chris@27: size_t m_wlen; Chris@27: Window *m_window; Chris@27: Chris@27: fftw_complex *m_time; Chris@27: fftw_complex *m_freq; Chris@27: double *m_dbuf; Chris@27: Chris@27: fftw_plan m_plan; Chris@27: fftw_plan m_iplan; Chris@27: Chris@27: RingBuffer m_inbuf; Chris@27: RingBuffer m_outbuf; Chris@27: double *m_mashbuf; Chris@27: }; Chris@27: Chris@27: #endif