| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library.
 -    Copyright (c) 2022 - Raw Material Software Limited
 - 
 -    JUCE is an open source library subject to commercial or open-source
 -    licensing.
 - 
 -    The code included in this file is provided under the terms of the ISC license
 -    http://www.isc.org/downloads/software-support-policy/isc-license. Permission
 -    To use, copy, modify, and/or distribute this software for any purpose with or
 -    without fee is hereby granted provided that the above copyright notice and
 -    this permission notice appear in all copies.
 - 
 -    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 -    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 -    DISCLAIMED.
 - 
 -   ==============================================================================
 - */
 - 
 - namespace juce
 - {
 - 
 - AudioTransportSource::AudioTransportSource()
 - {
 - }
 - 
 - AudioTransportSource::~AudioTransportSource()
 - {
 -     setSource (nullptr);
 -     releaseMasterResources();
 - }
 - 
 - void AudioTransportSource::setSource (PositionableAudioSource* const newSource,
 -                                       int readAheadSize, TimeSliceThread* readAheadThread,
 -                                       double sourceSampleRateToCorrectFor, int maxNumChannels)
 - {
 -     if (source == newSource)
 -     {
 -         if (source == nullptr)
 -             return;
 - 
 -         setSource (nullptr, 0, nullptr); // deselect and reselect to avoid releasing resources wrongly
 -     }
 - 
 -     ResamplingAudioSource* newResamplerSource = nullptr;
 -     BufferingAudioSource* newBufferingSource = nullptr;
 -     PositionableAudioSource* newPositionableSource = nullptr;
 -     AudioSource* newMasterSource = nullptr;
 - 
 -     std::unique_ptr<ResamplingAudioSource> oldResamplerSource (resamplerSource);
 -     std::unique_ptr<BufferingAudioSource> oldBufferingSource (bufferingSource);
 -     AudioSource* oldMasterSource = masterSource;
 - 
 -     if (newSource != nullptr)
 -     {
 -         newPositionableSource = newSource;
 - 
 -         if (readAheadSize > 0)
 -         {
 -             // If you want to use a read-ahead buffer, you must also provide a TimeSliceThread
 -             // for it to use!
 -             jassert (readAheadThread != nullptr);
 - 
 -             newPositionableSource = newBufferingSource
 -                 = new BufferingAudioSource (newPositionableSource, *readAheadThread,
 -                                             false, readAheadSize, maxNumChannels);
 -         }
 - 
 -         newPositionableSource->setNextReadPosition (0);
 - 
 -         if (sourceSampleRateToCorrectFor > 0)
 -             newMasterSource = newResamplerSource
 -                 = new ResamplingAudioSource (newPositionableSource, false, maxNumChannels);
 -         else
 -             newMasterSource = newPositionableSource;
 - 
 -         if (isPrepared)
 -         {
 -             if (newResamplerSource != nullptr && sourceSampleRateToCorrectFor > 0 && sampleRate > 0)
 -                 newResamplerSource->setResamplingRatio (sourceSampleRateToCorrectFor / sampleRate);
 - 
 -             newMasterSource->prepareToPlay (blockSize, sampleRate);
 -         }
 -     }
 - 
 -     {
 -         const ScopedLock sl (callbackLock);
 - 
 -         source = newSource;
 -         resamplerSource = newResamplerSource;
 -         bufferingSource = newBufferingSource;
 -         masterSource = newMasterSource;
 -         positionableSource = newPositionableSource;
 -         readAheadBufferSize = readAheadSize;
 -         sourceSampleRate = sourceSampleRateToCorrectFor;
 - 
 -         playing = false;
 -     }
 - 
 -     if (oldMasterSource != nullptr)
 -         oldMasterSource->releaseResources();
 - }
 - 
 - void AudioTransportSource::start()
 - {
 -     if ((! playing) && masterSource != nullptr)
 -     {
 -         {
 -             const ScopedLock sl (callbackLock);
 -             playing = true;
 -             stopped = false;
 -         }
 - 
 -         sendChangeMessage();
 -     }
 - }
 - 
 - void AudioTransportSource::stop()
 - {
 -     if (playing)
 -     {
 -         playing = false;
 - 
 -         int n = 500;
 -         while (--n >= 0 && ! stopped)
 -             Thread::sleep (2);
 - 
 -         sendChangeMessage();
 -     }
 - }
 - 
 - void AudioTransportSource::setPosition (double newPosition)
 - {
 -     if (sampleRate > 0.0)
 -         setNextReadPosition ((int64) (newPosition * sampleRate));
 - }
 - 
 - double AudioTransportSource::getCurrentPosition() const
 - {
 -     if (sampleRate > 0.0)
 -         return (double) getNextReadPosition() / sampleRate;
 - 
 -     return 0.0;
 - }
 - 
 - double AudioTransportSource::getLengthInSeconds() const
 - {
 -     if (sampleRate > 0.0)
 -         return (double) getTotalLength() / sampleRate;
 - 
 -     return 0.0;
 - }
 - 
 - bool AudioTransportSource::hasStreamFinished() const noexcept
 - {
 -     return positionableSource->getNextReadPosition() > positionableSource->getTotalLength() + 1
 -               && ! positionableSource->isLooping();
 - }
 - 
 - void AudioTransportSource::setNextReadPosition (int64 newPosition)
 - {
 -     if (positionableSource != nullptr)
 -     {
 -         if (sampleRate > 0 && sourceSampleRate > 0)
 -             newPosition = (int64) ((double) newPosition * sourceSampleRate / sampleRate);
 - 
 -         positionableSource->setNextReadPosition (newPosition);
 - 
 -         if (resamplerSource != nullptr)
 -             resamplerSource->flushBuffers();
 -     }
 - }
 - 
 - int64 AudioTransportSource::getNextReadPosition() const
 - {
 -     const ScopedLock sl (callbackLock);
 - 
 -     if (positionableSource != nullptr)
 -     {
 -         const double ratio = (sampleRate > 0 && sourceSampleRate > 0) ? sampleRate / sourceSampleRate : 1.0;
 -         return (int64) ((double) positionableSource->getNextReadPosition() * ratio);
 -     }
 - 
 -     return 0;
 - }
 - 
 - int64 AudioTransportSource::getTotalLength() const
 - {
 -     const ScopedLock sl (callbackLock);
 - 
 -     if (positionableSource != nullptr)
 -     {
 -         const double ratio = (sampleRate > 0 && sourceSampleRate > 0) ? sampleRate / sourceSampleRate : 1.0;
 -         return (int64) ((double) positionableSource->getTotalLength() * ratio);
 -     }
 - 
 -     return 0;
 - }
 - 
 - bool AudioTransportSource::isLooping() const
 - {
 -     const ScopedLock sl (callbackLock);
 -     return positionableSource != nullptr && positionableSource->isLooping();
 - }
 - 
 - void AudioTransportSource::setGain (const float newGain) noexcept
 - {
 -     gain = newGain;
 - }
 - 
 - void AudioTransportSource::prepareToPlay (int samplesPerBlockExpected, double newSampleRate)
 - {
 -     const ScopedLock sl (callbackLock);
 - 
 -     sampleRate = newSampleRate;
 -     blockSize = samplesPerBlockExpected;
 - 
 -     if (masterSource != nullptr)
 -         masterSource->prepareToPlay (samplesPerBlockExpected, sampleRate);
 - 
 -     if (resamplerSource != nullptr && sourceSampleRate > 0)
 -         resamplerSource->setResamplingRatio (sourceSampleRate / sampleRate);
 - 
 -     isPrepared = true;
 - }
 - 
 - void AudioTransportSource::releaseMasterResources()
 - {
 -     const ScopedLock sl (callbackLock);
 - 
 -     if (masterSource != nullptr)
 -         masterSource->releaseResources();
 - 
 -     isPrepared = false;
 - }
 - 
 - void AudioTransportSource::releaseResources()
 - {
 -     releaseMasterResources();
 - }
 - 
 - void AudioTransportSource::getNextAudioBlock (const AudioSourceChannelInfo& info)
 - {
 -     const ScopedLock sl (callbackLock);
 - 
 -     if (masterSource != nullptr && ! stopped)
 -     {
 -         masterSource->getNextAudioBlock (info);
 - 
 -         if (! playing)
 -         {
 -             // just stopped playing, so fade out the last block..
 -             for (int i = info.buffer->getNumChannels(); --i >= 0;)
 -                 info.buffer->applyGainRamp (i, info.startSample, jmin (256, info.numSamples), 1.0f, 0.0f);
 - 
 -             if (info.numSamples > 256)
 -                 info.buffer->clear (info.startSample + 256, info.numSamples - 256);
 -         }
 - 
 -         if (hasStreamFinished())
 -         {
 -             playing = false;
 -             sendChangeMessage();
 -         }
 - 
 -         stopped = ! playing;
 - 
 -         for (int i = info.buffer->getNumChannels(); --i >= 0;)
 -             info.buffer->applyGainRamp (i, info.startSample, info.numSamples, lastGain, gain);
 -     }
 -     else
 -     {
 -         info.clearActiveBufferRegion();
 -         stopped = true;
 -     }
 - 
 -     lastGain = gain;
 - }
 - 
 - } // namespace juce
 
 
  |