remove unnecessary gcc 4.7 "fix"
[ardour.git] / libs / rubberband / src / StretcherImpl.h
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2
3 /*
4     Rubber Band
5     An audio time-stretching and pitch-shifting library.
6     Copyright 2007-2008 Chris Cannam.
7     
8     This program is free software; you can redistribute it and/or
9     modify it under the terms of the GNU General Public License as
10     published by the Free Software Foundation; either version 2 of the
11     License, or (at your option) any later version.  See the file
12     COPYING included with this distribution for more information.
13 */
14
15 #ifndef _RUBBERBAND_STRETCHERIMPL_H_
16 #define _RUBBERBAND_STRETCHERIMPL_H_
17
18 #include "RubberBandStretcher.h"
19
20 #include "Window.h"
21 #include "Thread.h"
22 #include "RingBuffer.h"
23 #include "FFT.h"
24 #include "sysutils.h"
25
26 #include <set>
27
28 namespace RubberBand
29 {
30
31 class AudioCurve;
32 class StretchCalculator;
33
34 class RubberBandStretcher::Impl
35 {
36 public:
37     Impl(size_t sampleRate, size_t channels, Options options,
38          double initialTimeRatio, double initialPitchScale);
39     ~Impl();
40     
41     void reset();
42     void setTimeRatio(double ratio);
43     void setPitchScale(double scale);
44
45     double getTimeRatio() const;
46     double getPitchScale() const;
47
48     size_t getLatency() const;
49
50     void setTransientsOption(Options);
51     void setPhaseOption(Options);
52     void setFormantOption(Options);
53     void setPitchOption(Options);
54
55     void setExpectedInputDuration(size_t samples);
56     void setMaxProcessSize(size_t samples);
57
58     size_t getSamplesRequired() const;
59
60     void study(const float *const *input, size_t samples, bool final);
61     void process(const float *const *input, size_t samples, bool final);
62
63     int available() const;
64     size_t retrieve(float *const *output, size_t samples) const;
65
66     float getFrequencyCutoff(int n) const;
67     void setFrequencyCutoff(int n, float f);
68
69     size_t getInputIncrement() const {
70         return m_increment;
71     }
72
73     std::vector<int> getOutputIncrements() const;
74     std::vector<float> getPhaseResetCurve() const;
75     std::vector<int> getExactTimePoints() const;
76
77     size_t getChannelCount() const {
78         return m_channels;
79     }
80     
81     void calculateStretch();
82
83     void setDebugLevel(int level);
84     static void setDefaultDebugLevel(int level) { m_defaultDebugLevel = level; }
85
86 protected:
87     size_t m_sampleRate;
88     size_t m_channels;
89
90     size_t consumeChannel(size_t channel, const float *input,
91                           size_t samples, bool final);
92     void processChunks(size_t channel, bool &any, bool &last);
93     bool processOneChunk(); // across all channels, for real time use
94     bool processChunkForChannel(size_t channel, size_t phaseIncrement,
95                                 size_t shiftIncrement, bool phaseReset);
96     bool testInbufReadSpace(size_t channel);
97     void calculateIncrements(size_t &phaseIncrement,
98                              size_t &shiftIncrement, bool &phaseReset);
99     bool getIncrements(size_t channel, size_t &phaseIncrement,
100                        size_t &shiftIncrement, bool &phaseReset);
101     void analyseChunk(size_t channel);
102     void modifyChunk(size_t channel, size_t outputIncrement, bool phaseReset);
103     void formantShiftChunk(size_t channel);
104     void synthesiseChunk(size_t channel);
105     void writeChunk(size_t channel, size_t shiftIncrement, bool last);
106
107     void calculateSizes();
108     void configure();
109     void reconfigure();
110
111     double getEffectiveRatio() const;
112     
113     size_t roundUp(size_t value); // to next power of two
114
115     bool resampleBeforeStretching() const;
116     
117     double m_timeRatio;
118     double m_pitchScale;
119
120     size_t m_windowSize;
121     size_t m_increment;
122     size_t m_outbufSize;
123
124     size_t m_maxProcessSize;
125     size_t m_expectedInputDuration;
126     
127     bool m_threaded;
128     bool m_realtime;
129     Options m_options;
130     int m_debugLevel;
131
132     enum ProcessMode {
133         JustCreated,
134         Studying,
135         Processing,
136         Finished
137     };
138
139     ProcessMode m_mode;
140
141     std::map<size_t, Window<float> *> m_windows;
142     Window<float> *m_window;
143     FFT *m_studyFFT;
144
145     Condition m_spaceAvailable;
146     
147     class ProcessThread : public Thread
148     {
149     public:
150         ProcessThread(Impl *s, size_t c);
151         void run();
152         void signalDataAvailable();
153         void abandon();
154     private:
155         Impl *m_s;
156         size_t m_channel;
157         Condition m_dataAvailable;
158         bool m_abandoning;
159     };
160
161     mutable Mutex m_threadSetMutex;
162     typedef std::set<ProcessThread *> ThreadSet;
163     ThreadSet m_threadSet;
164     
165
166     size_t m_inputDuration;
167     std::vector<float> m_phaseResetDf;
168     std::vector<float> m_stretchDf;
169     std::vector<bool> m_silence;
170     int m_silentHistory;
171
172     class ChannelData; 
173     std::vector<ChannelData *> m_channelData;
174
175     std::vector<int> m_outputIncrements;
176
177     mutable RingBuffer<int> m_lastProcessOutputIncrements;
178     mutable RingBuffer<float> m_lastProcessPhaseResetDf;
179
180     AudioCurve *m_phaseResetAudioCurve;
181     AudioCurve *m_stretchAudioCurve;
182     AudioCurve *m_silentAudioCurve;
183     StretchCalculator *m_stretchCalculator;
184
185     float m_freq0;
186     float m_freq1;
187     float m_freq2;
188
189     size_t m_baseWindowSize;
190     float m_rateMultiple;
191
192     void writeOutput(RingBuffer<float> &to, float *from,
193                      size_t qty, size_t &outCount, size_t theoreticalOut);
194
195     static int m_defaultDebugLevel;
196     static const size_t m_defaultIncrement;
197     static const size_t m_defaultWindowSize;
198 };
199
200 }
201
202 #endif