view audioio/IntegerTimeStretcher.h @ 38:54287e5e7451 sv1-v0.9rc1 sv1-v0.9rc2

* Make vertical scale alignment modes work in note layer as well as time-value layer, and several significant fixes to it * Make it possible to draw notes properly on the note layer * Show units (and frequencies etc in note layer's case) in the time-value and note layer description boxes * Minor fix to item edit dialog layout * Some minor menu rearrangement * Comment out a lot of debug output * Add SV website and reference URLs to Help menu, and add code to (attempt to) open them in the user's preferred browser
author Chris Cannam
date Fri, 12 May 2006 14:40:43 +0000
parents 2eb25a26390f
children 4ed2448582cc
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */

/*
    Sonic Visualiser
    An audio file viewer and annotation editor.
    Centre for Digital Music, Queen Mary, University of London.
    This file copyright 2006 Chris Cannam.
    
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of the
    License, or (at your option) any later version.  See the file
    COPYING included with this distribution for more information.
*/

#ifndef _INTEGER_TIME_STRETCHER_H_
#define _INTEGER_TIME_STRETCHER_H_

#include "base/Window.h"
#include "base/RingBuffer.h"

#include <fftw3.h>

/**
 * A time stretcher that slows down audio by an integer multiple of
 * its original duration, preserving pitch.  This uses the simple
 * phase vocoder technique from DAFX pp275-276, adding a block-based
 * stream oriented API.
 *
 * Causes significant transient smearing, but sounds good for steady
 * notes and is generally predictable.
 */

class IntegerTimeStretcher
{
public:
    IntegerTimeStretcher(size_t ratio,
			 size_t maxProcessInputBlockSize,
			 size_t inputIncrement = 64,
			 size_t windowSize = 2048,
			 WindowType windowType = HanningWindow);
    virtual ~IntegerTimeStretcher();

    void process(double *input, double *output, size_t samples);

    /**
     * Get the hop size for input.  Smaller values may produce better
     * results, at a cost in processing time.  Larger values are
     * faster but increase the likelihood of echo-like effects.  The
     * default is 64, which is usually pretty good, though heavy on
     * processor power.
     */
    size_t getInputIncrement() const { return m_n1; }

    /**
     * Get the window size for FFT processing.  Must be larger than
     * the input and output increments.  The default is 2048.
     */
    size_t getWindowSize() const { return m_wlen; }

    /**
     * Get the window type.  The default is a Hanning window.
     */
    WindowType getWindowType() const { return m_window->getType(); }

    size_t getRatio() const { return m_ratio; }
    size_t getOutputIncrement() const { return getInputIncrement() * getRatio(); }
    size_t getProcessingLatency() const;

protected:
    void processBlock(double *in, double *out);

    size_t m_ratio;
    size_t m_n1;
    size_t m_n2;
    size_t m_wlen;
    Window<double> *m_window;

    fftw_complex *m_time;
    fftw_complex *m_freq;
    double *m_dbuf;

    fftw_plan m_plan;
    fftw_plan m_iplan;
    
    RingBuffer<double> m_inbuf;
    RingBuffer<double> m_outbuf;
    double *m_mashbuf;
};

#endif