| @@ -27,11 +27,6 @@ ResamplingAudioSource::ResamplingAudioSource (AudioSource* const inputSource, | |||||
| const bool deleteInputWhenDeleted, | const bool deleteInputWhenDeleted, | ||||
| const int channels) | const int channels) | ||||
| : input (inputSource, deleteInputWhenDeleted), | : input (inputSource, deleteInputWhenDeleted), | ||||
| ratio (1.0), | |||||
| lastRatio (1.0), | |||||
| bufferPos (0), | |||||
| sampsInBuffer (0), | |||||
| subSampleOffset (0), | |||||
| numChannels (channels) | numChannels (channels) | ||||
| { | { | ||||
| jassert (input != nullptr); | jassert (input != nullptr); | ||||
| @@ -67,6 +62,8 @@ void ResamplingAudioSource::prepareToPlay (int samplesPerBlockExpected, double s | |||||
| void ResamplingAudioSource::flushBuffers() | void ResamplingAudioSource::flushBuffers() | ||||
| { | { | ||||
| const ScopedLock sl (callbackLock); | |||||
| buffer.clear(); | buffer.clear(); | ||||
| bufferPos = 0; | bufferPos = 0; | ||||
| sampsInBuffer = 0; | sampsInBuffer = 0; | ||||
| @@ -82,10 +79,12 @@ void ResamplingAudioSource::releaseResources() | |||||
| void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info) | void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& info) | ||||
| { | { | ||||
| const ScopedLock sl (callbackLock); | |||||
| double localRatio; | double localRatio; | ||||
| { | { | ||||
| const SpinLock::ScopedLockType sl (ratioLock); | |||||
| const SpinLock::ScopedLockType ratioSl (ratioLock); | |||||
| localRatio = ratio; | localRatio = ratio; | ||||
| } | } | ||||
| @@ -76,12 +76,13 @@ public: | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| OptionalScopedPointer<AudioSource> input; | OptionalScopedPointer<AudioSource> input; | ||||
| double ratio, lastRatio; | |||||
| double ratio = 1.0, lastRatio = 1.0; | |||||
| AudioBuffer<float> buffer; | AudioBuffer<float> buffer; | ||||
| int bufferPos, sampsInBuffer; | |||||
| double subSampleOffset; | |||||
| int bufferPos = 0, sampsInBuffer = 0; | |||||
| double subSampleOffset = 0.0; | |||||
| double coefficients[6]; | double coefficients[6]; | ||||
| SpinLock ratioLock; | SpinLock ratioLock; | ||||
| CriticalSection callbackLock; | |||||
| const int numChannels; | const int numChannels; | ||||
| HeapBlock<float*> destBuffers; | HeapBlock<float*> destBuffers; | ||||
| HeapBlock<const float*> srcBuffers; | HeapBlock<const float*> srcBuffers; | ||||
| @@ -125,10 +125,7 @@ void AudioTransportSource::stop() | |||||
| { | { | ||||
| if (playing) | if (playing) | ||||
| { | { | ||||
| { | |||||
| const ScopedLock sl (callbackLock); | |||||
| playing = false; | |||||
| } | |||||
| playing = false; | |||||
| int n = 500; | int n = 500; | ||||
| while (--n >= 0 && ! stopped) | while (--n >= 0 && ! stopped) | ||||
| @@ -167,7 +167,7 @@ private: | |||||
| CriticalSection callbackLock; | CriticalSection callbackLock; | ||||
| float gain = 1.0f, lastGain = 1.0f; | float gain = 1.0f, lastGain = 1.0f; | ||||
| bool playing = false, stopped = true; | |||||
| std::atomic<bool> playing { false }, stopped { true }; | |||||
| double sampleRate = 44100.0, sourceSampleRate = 0; | double sampleRate = 44100.0, sourceSampleRate = 0; | ||||
| int blockSize = 128, readAheadBufferSize = 0; | int blockSize = 128, readAheadBufferSize = 0; | ||||
| bool isPrepared = false, inputStreamEOF = false; | bool isPrepared = false, inputStreamEOF = false; | ||||
| @@ -214,7 +214,7 @@ private: | |||||
| std::unique_ptr<InputSource> source; | std::unique_ptr<InputSource> source; | ||||
| std::unique_ptr<AudioFormatReader> reader; | std::unique_ptr<AudioFormatReader> reader; | ||||
| CriticalSection readerLock; | CriticalSection readerLock; | ||||
| uint32 lastReaderUseTime = 0; | |||||
| std::atomic<uint32> lastReaderUseTime { 0 }; | |||||
| void createReader() | void createReader() | ||||
| { | { | ||||
| @@ -645,6 +645,7 @@ bool AudioThumbnail::setDataSource (LevelDataSource* newSource) | |||||
| JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED | JUCE_ASSERT_MESSAGE_MANAGER_IS_LOCKED | ||||
| numSamplesFinished = 0; | numSamplesFinished = 0; | ||||
| auto wasSuccessful = [&] { return sampleRate > 0 && totalSamples > 0; }; | |||||
| if (cache.loadThumb (*this, newSource->hashCode) && isFullyLoaded()) | if (cache.loadThumb (*this, newSource->hashCode) && isFullyLoaded()) | ||||
| { | { | ||||
| @@ -654,22 +655,22 @@ bool AudioThumbnail::setDataSource (LevelDataSource* newSource) | |||||
| source->sampleRate = sampleRate; | source->sampleRate = sampleRate; | ||||
| source->numChannels = (unsigned int) numChannels; | source->numChannels = (unsigned int) numChannels; | ||||
| source->numSamplesFinished = numSamplesFinished; | source->numSamplesFinished = numSamplesFinished; | ||||
| return wasSuccessful(); | |||||
| } | } | ||||
| else | |||||
| { | |||||
| source.reset (newSource); // (make sure this isn't done before loadThumb is called) | |||||
| const ScopedLock sl (lock); | |||||
| source->initialise (numSamplesFinished); | |||||
| source.reset (newSource); | |||||
| totalSamples = source->lengthInSamples; | |||||
| sampleRate = source->sampleRate; | |||||
| numChannels = (int32) source->numChannels; | |||||
| const ScopedLock sl (lock); | |||||
| source->initialise (numSamplesFinished); | |||||
| createChannels (1 + (int) (totalSamples / samplesPerThumbSample)); | |||||
| } | |||||
| totalSamples = source->lengthInSamples; | |||||
| sampleRate = source->sampleRate; | |||||
| numChannels = (int32) source->numChannels; | |||||
| createChannels (1 + (int) (totalSamples / samplesPerThumbSample)); | |||||
| return sampleRate > 0 && totalSamples > 0; | |||||
| return wasSuccessful(); | |||||
| } | } | ||||
| bool AudioThumbnail::setSource (InputSource* const newSource) | bool AudioThumbnail::setSource (InputSource* const newSource) | ||||