Chris@738
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@738
|
2
|
Chris@738
|
3 /*
|
Chris@738
|
4 Sonic Visualiser
|
Chris@738
|
5 An audio file viewer and annotation editor.
|
Chris@738
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@738
|
7
|
Chris@738
|
8 This program is free software; you can redistribute it and/or
|
Chris@738
|
9 modify it under the terms of the GNU General Public License as
|
Chris@738
|
10 published by the Free Software Foundation; either version 2 of the
|
Chris@738
|
11 License, or (at your option) any later version. See the file
|
Chris@738
|
12 COPYING included with this distribution for more information.
|
Chris@738
|
13 */
|
Chris@738
|
14
|
Chris@738
|
15 #ifndef SV_TIME_STRETCH_WRAPPER_H
|
Chris@738
|
16 #define SV_TIME_STRETCH_WRAPPER_H
|
Chris@738
|
17
|
Chris@738
|
18 #include "bqaudioio/ApplicationPlaybackSource.h"
|
Chris@738
|
19
|
Chris@738
|
20 #include "base/BaseTypes.h"
|
Chris@738
|
21
|
Chris@738
|
22 #include <vector>
|
Chris@738
|
23 #include <mutex>
|
Chris@738
|
24
|
Chris@738
|
25 namespace RubberBand {
|
Chris@738
|
26 class RubberBandStretcher;
|
Chris@738
|
27 }
|
Chris@738
|
28
|
Chris@738
|
29 /**
|
Chris@738
|
30 * A breakfastquay::ApplicationPlaybackSource wrapper that implements
|
Chris@738
|
31 * time-stretching using Rubber Band. Note that the stretcher is
|
Chris@738
|
32 * bypassed entirely when a ratio of 1.0 is set; this means it's
|
Chris@738
|
33 * (almost) free to use one of these wrappers normally, but it also
|
Chris@738
|
34 * means you can't switch from 1.0 to another ratio (or back again)
|
Chris@738
|
35 * without some audible artifacts.
|
Chris@738
|
36 *
|
Chris@738
|
37 * This is real-time safe while the ratio is fixed, and may perform
|
Chris@738
|
38 * reallocations when the ratio changes.
|
Chris@738
|
39 */
|
Chris@738
|
40 class TimeStretchWrapper : public breakfastquay::ApplicationPlaybackSource
|
Chris@738
|
41 {
|
Chris@738
|
42 public:
|
Chris@738
|
43 /**
|
Chris@738
|
44 * Create a wrapper around the given ApplicationPlaybackSource,
|
Chris@738
|
45 * implementing another ApplicationPlaybackSource interface that
|
Chris@738
|
46 * draws from the same source data but with a time-stretcher
|
Chris@738
|
47 * optionally applied.
|
Chris@738
|
48 *
|
Chris@738
|
49 * The wrapper does not take ownership of the wrapped
|
Chris@738
|
50 * ApplicationPlaybackSource, whose lifespan must exceed that of
|
Chris@738
|
51 * this object.
|
Chris@738
|
52 */
|
Chris@738
|
53 TimeStretchWrapper(ApplicationPlaybackSource *source);
|
Chris@738
|
54 ~TimeStretchWrapper();
|
Chris@738
|
55
|
Chris@738
|
56 /**
|
Chris@738
|
57 * Set a time stretch factor, i.e. playback speed, where 1.0 is
|
Chris@738
|
58 * normal speed
|
Chris@738
|
59 */
|
Chris@738
|
60 void setTimeStretchRatio(double ratio);
|
Chris@738
|
61
|
Chris@738
|
62 /**
|
Chris@738
|
63 * Clear stretcher buffers.
|
Chris@738
|
64 */
|
Chris@738
|
65 void reset();
|
Chris@738
|
66
|
Chris@738
|
67 // These functions are passed through to the wrapped
|
Chris@738
|
68 // ApplicationPlaybackSource
|
Chris@738
|
69
|
Chris@738
|
70 std::string getClientName() const override;
|
Chris@738
|
71 int getApplicationSampleRate() const override;
|
Chris@738
|
72 int getApplicationChannelCount() const override;
|
Chris@738
|
73
|
Chris@738
|
74 void setSystemPlaybackBlockSize(int) override;
|
Chris@738
|
75 void setSystemPlaybackSampleRate(int) override;
|
Chris@738
|
76 void setSystemPlaybackChannelCount(int) override;
|
Chris@738
|
77 void setSystemPlaybackLatency(int) override;
|
Chris@738
|
78
|
Chris@738
|
79 void setOutputLevels(float peakLeft, float peakRight) override;
|
Chris@738
|
80 void audioProcessingOverload() override;
|
Chris@738
|
81
|
Chris@738
|
82 /**
|
Chris@738
|
83 * Request some samples from the wrapped
|
Chris@738
|
84 * ApplicationPlaybackSource, time-stretch if appropriate, and
|
Chris@738
|
85 * return them to the target
|
Chris@738
|
86 */
|
Chris@738
|
87 int getSourceSamples(float *const *samples, int nchannels, int nframes)
|
Chris@738
|
88 override;
|
Chris@738
|
89
|
Chris@738
|
90 private:
|
Chris@738
|
91 ApplicationPlaybackSource *m_source;
|
Chris@738
|
92 RubberBand::RubberBandStretcher *m_stretcher;
|
Chris@738
|
93 double m_timeRatio;
|
Chris@738
|
94 std::vector<std::vector<float>> m_inputs;
|
Chris@738
|
95 std::mutex m_mutex;
|
Chris@740
|
96 int m_stretcherInputSize;
|
Chris@738
|
97 int m_channelCount;
|
Chris@738
|
98 sv_samplerate_t m_sampleRate;
|
Chris@738
|
99
|
Chris@738
|
100 void checkStretcher(); // call without m_mutex held
|
Chris@738
|
101
|
Chris@738
|
102 TimeStretchWrapper(const TimeStretchWrapper &)=delete;
|
Chris@738
|
103 TimeStretchWrapper &operator=(const TimeStretchWrapper &)=delete;
|
Chris@738
|
104 };
|
Chris@738
|
105
|
Chris@738
|
106 #endif
|
Chris@738
|
107
|
Chris@738
|
108
|