OpenShot Audio Library | OpenShotAudio 0.3.2

Loading...
Searching...
No Matches
juce_AudioTransportSource.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2017 - ROLI Ltd.
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23 namespace juce
24{
25
26 AudioTransportSource::AudioTransportSource()
27{
28}
29
30 AudioTransportSource::~AudioTransportSource()
31{
32 setSource (nullptr);
33 releaseMasterResources();
34}
35
36 void AudioTransportSource::setSource (PositionableAudioSource* const newSource,
37 int readAheadSize, TimeSliceThread* readAheadThread,
38 double sourceSampleRateToCorrectFor, int maxNumChannels)
39{
40 if (source == newSource)
41 {
42 if (source == nullptr)
43 return;
44
45 setSource (nullptr, 0, nullptr); // deselect and reselect to avoid releasing resources wrongly
46 }
47
48 readAheadBufferSize = readAheadSize;
49 sourceSampleRate = sourceSampleRateToCorrectFor;
50
51 ResamplingAudioSource* newResamplerSource = nullptr;
52 BufferingAudioSource* newBufferingSource = nullptr;
53 PositionableAudioSource* newPositionableSource = nullptr;
54 AudioSource* newMasterSource = nullptr;
55
56 std::unique_ptr<ResamplingAudioSource> oldResamplerSource (resamplerSource);
57 std::unique_ptr<BufferingAudioSource> oldBufferingSource (bufferingSource);
58 AudioSource* oldMasterSource = masterSource;
59
60 if (newSource != nullptr)
61 {
62 newPositionableSource = newSource;
63
64 if (readAheadSize > 0)
65 {
66 // If you want to use a read-ahead buffer, you must also provide a TimeSliceThread
67 // for it to use!
68 jassert (readAheadThread != nullptr);
69
70 newPositionableSource = newBufferingSource
71 = new BufferingAudioSource (newPositionableSource, *readAheadThread,
72 false, readAheadSize, maxNumChannels);
73 }
74
75 newPositionableSource->setNextReadPosition (0);
76
77 if (sourceSampleRateToCorrectFor > 0)
78 newMasterSource = newResamplerSource
79 = new ResamplingAudioSource (newPositionableSource, false, maxNumChannels);
80 else
81 newMasterSource = newPositionableSource;
82
83 if (isPrepared)
84 {
85 if (newResamplerSource != nullptr && sourceSampleRate > 0 && sampleRate > 0)
86 newResamplerSource->setResamplingRatio (sourceSampleRate / sampleRate);
87
88 newMasterSource->prepareToPlay (blockSize, sampleRate);
89 }
90 }
91
92 {
93 const ScopedLock sl (callbackLock);
94
95 source = newSource;
96 resamplerSource = newResamplerSource;
97 bufferingSource = newBufferingSource;
98 masterSource = newMasterSource;
99 positionableSource = newPositionableSource;
100
101 inputStreamEOF = false;
102 playing = false;
103 }
104
105 if (oldMasterSource != nullptr)
106 oldMasterSource->releaseResources();
107}
108
109 void AudioTransportSource::start()
110{
111 if ((! playing) && masterSource != nullptr)
112 {
113 {
114 const ScopedLock sl (callbackLock);
115 playing = true;
116 stopped = false;
117 inputStreamEOF = false;
118 }
119
120 sendChangeMessage();
121 }
122}
123
124 void AudioTransportSource::stop()
125{
126 if (playing)
127 {
128 playing = false;
129
130 int n = 500;
131 while (--n >= 0 && ! stopped)
132 Thread::sleep (2);
133
134 sendChangeMessage();
135 }
136}
137
138 void AudioTransportSource::setPosition (double newPosition)
139{
140 if (sampleRate > 0.0)
141 setNextReadPosition ((int64) (newPosition * sampleRate));
142}
143
144 double AudioTransportSource::getCurrentPosition() const
145{
146 if (sampleRate > 0.0)
147 return (double) getNextReadPosition() / sampleRate;
148
149 return 0.0;
150}
151
152 double AudioTransportSource::getLengthInSeconds() const
153{
154 if (sampleRate > 0.0)
155 return (double) getTotalLength() / sampleRate;
156
157 return 0.0;
158}
159
160 void AudioTransportSource::setNextReadPosition (int64 newPosition)
161{
162 if (positionableSource != nullptr)
163 {
164 if (sampleRate > 0 && sourceSampleRate > 0)
165 newPosition = (int64) ((double) newPosition * sourceSampleRate / sampleRate);
166
167 positionableSource->setNextReadPosition (newPosition);
168
169 if (resamplerSource != nullptr)
170 resamplerSource->flushBuffers();
171
172 inputStreamEOF = false;
173 }
174}
175
176int64 AudioTransportSource::getNextReadPosition() const
177{
178 if (positionableSource != nullptr)
179 {
180 const double ratio = (sampleRate > 0 && sourceSampleRate > 0) ? sampleRate / sourceSampleRate : 1.0;
181 return (int64) ((double) positionableSource->getNextReadPosition() * ratio);
182 }
183
184 return 0;
185}
186
187int64 AudioTransportSource::getTotalLength() const
188{
189 const ScopedLock sl (callbackLock);
190
191 if (positionableSource != nullptr)
192 {
193 const double ratio = (sampleRate > 0 && sourceSampleRate > 0) ? sampleRate / sourceSampleRate : 1.0;
194 return (int64) ((double) positionableSource->getTotalLength() * ratio);
195 }
196
197 return 0;
198}
199
200 bool AudioTransportSource::isLooping() const
201{
202 const ScopedLock sl (callbackLock);
203 return positionableSource != nullptr && positionableSource->isLooping();
204}
205
206 void AudioTransportSource::setGain (const float newGain) noexcept
207{
208 gain = newGain;
209}
210
211 void AudioTransportSource::prepareToPlay (int samplesPerBlockExpected, double newSampleRate)
212{
213 const ScopedLock sl (callbackLock);
214
215 sampleRate = newSampleRate;
216 blockSize = samplesPerBlockExpected;
217
218 if (masterSource != nullptr)
219 masterSource->prepareToPlay (samplesPerBlockExpected, sampleRate);
220
221 if (resamplerSource != nullptr && sourceSampleRate > 0)
222 resamplerSource->setResamplingRatio (sourceSampleRate / sampleRate);
223
224 inputStreamEOF = false;
225 isPrepared = true;
226}
227
228 void AudioTransportSource::releaseMasterResources()
229{
230 const ScopedLock sl (callbackLock);
231
232 if (masterSource != nullptr)
233 masterSource->releaseResources();
234
235 isPrepared = false;
236}
237
238 void AudioTransportSource::releaseResources()
239{
240 releaseMasterResources();
241}
242
243 void AudioTransportSource::getNextAudioBlock (const AudioSourceChannelInfo& info)
244{
245 const ScopedLock sl (callbackLock);
246
247 if (masterSource != nullptr && ! stopped)
248 {
249 masterSource->getNextAudioBlock (info);
250
251 if (! playing)
252 {
253 // just stopped playing, so fade out the last block..
254 for (int i = info.buffer->getNumChannels(); --i >= 0;)
255 info.buffer->applyGainRamp (i, info.startSample, jmin (256, info.numSamples), 1.0f, 0.0f);
256
257 if (info.numSamples > 256)
258 info.buffer->clear (info.startSample + 256, info.numSamples - 256);
259 }
260
261 if (positionableSource->getNextReadPosition() > positionableSource->getTotalLength() + 1
262 && ! positionableSource->isLooping())
263 {
264 playing = false;
265 inputStreamEOF = true;
266 sendChangeMessage();
267 }
268
269 stopped = ! playing;
270
271 for (int i = info.buffer->getNumChannels(); --i >= 0;)
272 info.buffer->applyGainRamp (i, info.startSample, info.numSamples, lastGain, gain);
273 }
274 else
275 {
276 info.clearActiveBufferRegion();
277 stopped = true;
278 }
279
280 lastGain = gain;
281}
282
283} // namespace juce
juce::AudioBuffer::getNumChannels
int getNumChannels() const noexcept
Definition: juce_AudioSampleBuffer.h:233
juce::AudioBuffer::clear
void clear() noexcept
Definition: juce_AudioSampleBuffer.h:506
juce::AudioBuffer::applyGainRamp
void applyGainRamp(int channel, int startSample, int numSamples, Type startGain, Type endGain) noexcept
Definition: juce_AudioSampleBuffer.h:644
juce::AudioSource
Definition: juce_AudioSource.h:110
juce::AudioSource::releaseResources
virtual void releaseResources()=0
juce::AudioSource::prepareToPlay
virtual void prepareToPlay(int samplesPerBlockExpected, double sampleRate)=0
juce::AudioSource::getNextAudioBlock
virtual void getNextAudioBlock(const AudioSourceChannelInfo &bufferToFill)=0
juce::AudioTransportSource::stop
void stop()
Definition: juce_AudioTransportSource.cpp:124
juce::AudioTransportSource::prepareToPlay
void prepareToPlay(int samplesPerBlockExpected, double sampleRate) override
Definition: juce_AudioTransportSource.cpp:211
juce::AudioTransportSource::getNextReadPosition
int64 getNextReadPosition() const override
Definition: juce_AudioTransportSource.cpp:176
juce::AudioTransportSource::getCurrentPosition
double getCurrentPosition() const
Definition: juce_AudioTransportSource.cpp:144
juce::AudioTransportSource::releaseResources
void releaseResources() override
Definition: juce_AudioTransportSource.cpp:238
juce::AudioTransportSource::getNextAudioBlock
void getNextAudioBlock(const AudioSourceChannelInfo &) override
Definition: juce_AudioTransportSource.cpp:243
juce::AudioTransportSource::getTotalLength
int64 getTotalLength() const override
Definition: juce_AudioTransportSource.cpp:187
juce::AudioTransportSource::~AudioTransportSource
~AudioTransportSource() override
Definition: juce_AudioTransportSource.cpp:30
juce::AudioTransportSource::setPosition
void setPosition(double newPosition)
Definition: juce_AudioTransportSource.cpp:138
juce::AudioTransportSource::getLengthInSeconds
double getLengthInSeconds() const
Definition: juce_AudioTransportSource.cpp:152
juce::AudioTransportSource::setGain
void setGain(float newGain) noexcept
Definition: juce_AudioTransportSource.cpp:206
juce::AudioTransportSource::setSource
void setSource(PositionableAudioSource *newSource, int readAheadBufferSize=0, TimeSliceThread *readAheadThread=nullptr, double sourceSampleRateToCorrectFor=0.0, int maxNumChannels=2)
Definition: juce_AudioTransportSource.cpp:36
juce::AudioTransportSource::isLooping
bool isLooping() const override
Definition: juce_AudioTransportSource.cpp:200
juce::AudioTransportSource::AudioTransportSource
AudioTransportSource()
Definition: juce_AudioTransportSource.cpp:26
juce::AudioTransportSource::start
void start()
Definition: juce_AudioTransportSource.cpp:109
juce::AudioTransportSource::setNextReadPosition
void setNextReadPosition(int64 newPosition) override
Definition: juce_AudioTransportSource.cpp:160
juce::BufferingAudioSource
Definition: juce_BufferingAudioSource.h:40
juce::ChangeBroadcaster::sendChangeMessage
void sendChangeMessage()
Definition: juce_ChangeBroadcaster.cpp:65
juce::GenericScopedLock
Definition: juce_ScopedLock.h:55
juce::PositionableAudioSource
Definition: juce_PositionableAudioSource.h:39
juce::PositionableAudioSource::isLooping
virtual bool isLooping() const =0
juce::PositionableAudioSource::getNextReadPosition
virtual int64 getNextReadPosition() const =0
juce::PositionableAudioSource::getTotalLength
virtual int64 getTotalLength() const =0
juce::PositionableAudioSource::setNextReadPosition
virtual void setNextReadPosition(int64 newPosition)=0
juce::ResamplingAudioSource
Definition: juce_ResamplingAudioSource.h:35
juce::ResamplingAudioSource::flushBuffers
void flushBuffers()
Definition: juce_ResamplingAudioSource.cpp:63
juce::ResamplingAudioSource::setResamplingRatio
void setResamplingRatio(double samplesInPerOutputSample)
Definition: juce_ResamplingAudioSource.cpp:38
juce::Thread::sleep
static void JUCE_CALLTYPE sleep(int milliseconds)
juce::TimeSliceThread
Definition: juce_TimeSliceThread.h:83
juce::AudioSourceChannelInfo
Definition: juce_AudioSource.h:33
juce::AudioSourceChannelInfo::numSamples
int numSamples
Definition: juce_AudioSource.h:81
juce::AudioSourceChannelInfo::clearActiveBufferRegion
void clearActiveBufferRegion() const
Definition: juce_AudioSource.h:84
juce::AudioSourceChannelInfo::buffer
AudioBuffer< float > * buffer
Definition: juce_AudioSource.h:73
juce::AudioSourceChannelInfo::startSample
int startSample
Definition: juce_AudioSource.h:77