| @@ -6,7 +6,7 @@ JUCE_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/DISTRHO/libs/juce/source/module | |||
| CARLA_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/Carla/source/modules" | |||
| # MODULES=("juce_audio_basics juce_audio_devices juce_audio_formats juce_audio_processors juce_core juce_data_structures juce_events juce_graphics juce_gui_basics") | |||
| MODULES=("juce_audio_basics") | |||
| MODULES=("juce_audio_devices") | |||
| for M in $MODULES; do | |||
| echo $M; | |||
| @@ -361,8 +361,8 @@ void AudioDeviceManager::getAudioDeviceSetup (AudioDeviceSetup& setup) | |||
| void AudioDeviceManager::deleteCurrentDevice() | |||
| { | |||
| currentAudioDevice = nullptr; | |||
| currentSetup.inputDeviceName = String::empty; | |||
| currentSetup.outputDeviceName = String::empty; | |||
| currentSetup.inputDeviceName.clear(); | |||
| currentSetup.outputDeviceName.clear(); | |||
| } | |||
| void AudioDeviceManager::setCurrentAudioDeviceType (const String& type, | |||
| @@ -408,15 +408,15 @@ String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& newSetup | |||
| jassert (&newSetup != ¤tSetup); // this will have no effect | |||
| if (newSetup == currentSetup && currentAudioDevice != nullptr) | |||
| return String::empty; | |||
| return String(); | |||
| if (! (newSetup == currentSetup)) | |||
| sendChangeMessage(); | |||
| stopDevice(); | |||
| const String newInputDeviceName (numInputChansNeeded == 0 ? String::empty : newSetup.inputDeviceName); | |||
| const String newOutputDeviceName (numOutputChansNeeded == 0 ? String::empty : newSetup.outputDeviceName); | |||
| const String newInputDeviceName (numInputChansNeeded == 0 ? String() : newSetup.inputDeviceName); | |||
| const String newOutputDeviceName (numOutputChansNeeded == 0 ? String() : newSetup.outputDeviceName); | |||
| String error; | |||
| AudioIODeviceType* type = getCurrentDeviceTypeObject(); | |||
| @@ -428,7 +428,7 @@ String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& newSetup | |||
| if (treatAsChosenDevice) | |||
| updateXml(); | |||
| return String::empty; | |||
| return String(); | |||
| } | |||
| if (currentSetup.inputDeviceName != newInputDeviceName | |||
| @@ -524,16 +524,16 @@ double AudioDeviceManager::chooseBestSampleRate (double rate) const | |||
| { | |||
| jassert (currentAudioDevice != nullptr); | |||
| if (rate > 0) | |||
| for (int i = currentAudioDevice->getNumSampleRates(); --i >= 0;) | |||
| if (currentAudioDevice->getSampleRate (i) == rate) | |||
| return rate; | |||
| const Array<double> rates (currentAudioDevice->getAvailableSampleRates()); | |||
| if (rate > 0 && rates.contains (rate)) | |||
| return rate; | |||
| double lowestAbove44 = 0.0; | |||
| for (int i = currentAudioDevice->getNumSampleRates(); --i >= 0;) | |||
| for (int i = rates.size(); --i >= 0;) | |||
| { | |||
| const double sr = currentAudioDevice->getSampleRate (i); | |||
| const double sr = rates[i]; | |||
| if (sr >= 44100.0 && (lowestAbove44 < 1.0 || sr < lowestAbove44)) | |||
| lowestAbove44 = sr; | |||
| @@ -542,17 +542,15 @@ double AudioDeviceManager::chooseBestSampleRate (double rate) const | |||
| if (lowestAbove44 > 0.0) | |||
| return lowestAbove44; | |||
| return currentAudioDevice->getSampleRate (0); | |||
| return rates[0]; | |||
| } | |||
| int AudioDeviceManager::chooseBestBufferSize (int bufferSize) const | |||
| { | |||
| jassert (currentAudioDevice != nullptr); | |||
| if (bufferSize > 0) | |||
| for (int i = currentAudioDevice->getNumBufferSizesAvailable(); --i >= 0;) | |||
| if (currentAudioDevice->getBufferSizeSamples(i) == bufferSize) | |||
| return bufferSize; | |||
| if (bufferSize > 0 && currentAudioDevice->getAvailableBufferSizes().contains (bufferSize)) | |||
| return bufferSize; | |||
| return currentAudioDevice->getDefaultBufferSize(); | |||
| } | |||
| @@ -190,7 +190,7 @@ public: | |||
| int numOutputChannelsNeeded, | |||
| const XmlElement* savedState, | |||
| bool selectDefaultDeviceOnFailure, | |||
| const String& preferredDefaultDeviceName = String::empty, | |||
| const String& preferredDefaultDeviceName = String(), | |||
| const AudioDeviceSetup* preferredSetupOptions = 0); | |||
| /** Returns some XML representing the current state of the manager. | |||
| @@ -157,47 +157,19 @@ public: | |||
| virtual StringArray getInputChannelNames() = 0; | |||
| //============================================================================== | |||
| /** Returns the number of sample-rates this device supports. | |||
| To find out which rates are available on this device, use this method to | |||
| find out how many there are, and getSampleRate() to get the rates. | |||
| @see getSampleRate | |||
| */ | |||
| virtual int getNumSampleRates() = 0; | |||
| /** Returns one of the sample-rates this device supports. | |||
| To find out which rates are available on this device, use getNumSampleRates() to | |||
| find out how many there are, and getSampleRate() to get the individual rates. | |||
| The sample rate is set by the open() method. | |||
| (Note that for DirectSound some rates might not work, depending on combinations | |||
| of i/o channels that are being opened). | |||
| @see getNumSampleRates | |||
| /** Returns the set of sample-rates this device supports. | |||
| @see getCurrentSampleRate | |||
| */ | |||
| virtual double getSampleRate (int index) = 0; | |||
| /** Returns the number of sizes of buffer that are available. | |||
| virtual Array<double> getAvailableSampleRates() = 0; | |||
| @see getBufferSizeSamples, getDefaultBufferSize | |||
| /** Returns the set of buffer sizes that are available. | |||
| @see getCurrentBufferSizeSamples, getDefaultBufferSize | |||
| */ | |||
| virtual int getNumBufferSizesAvailable() = 0; | |||
| /** Returns one of the possible buffer-sizes. | |||
| @param index the index of the buffer-size to use, from 0 to getNumBufferSizesAvailable() - 1 | |||
| @returns a number of samples | |||
| @see getNumBufferSizesAvailable, getDefaultBufferSize | |||
| */ | |||
| virtual int getBufferSizeSamples (int index) = 0; | |||
| virtual Array<int> getAvailableBufferSizes() = 0; | |||
| /** Returns the default buffer-size to use. | |||
| @returns a number of samples | |||
| @see getNumBufferSizesAvailable, getBufferSizeSamples | |||
| @see getAvailableBufferSizes | |||
| */ | |||
| virtual int getDefaultBufferSize() = 0; | |||
| @@ -209,9 +181,9 @@ public: | |||
| @param outputChannels a BigInteger in which a set bit indicates that the corresponding | |||
| output channel should be enabled | |||
| @param sampleRate the sample rate to try to use - to find out which rates are | |||
| available, see getNumSampleRates() and getSampleRate() | |||
| available, see getAvailableSampleRates() | |||
| @param bufferSizeSamples the size of i/o buffer to use - to find out the available buffer | |||
| sizes, see getNumBufferSizesAvailable() and getBufferSizeSamples() | |||
| sizes, see getAvailableBufferSizes() | |||
| @returns an error description if there's a problem, or an empty string if it succeeds in | |||
| opening the device | |||
| @see close | |||
| @@ -105,7 +105,7 @@ public: | |||
| close(); | |||
| } | |||
| StringArray getOutputChannelNames() | |||
| StringArray getOutputChannelNames() override | |||
| { | |||
| StringArray s; | |||
| s.add ("Left"); | |||
| @@ -113,7 +113,7 @@ public: | |||
| return s; | |||
| } | |||
| StringArray getInputChannelNames() | |||
| StringArray getInputChannelNames() override | |||
| { | |||
| StringArray s; | |||
| @@ -130,36 +130,43 @@ public: | |||
| return s; | |||
| } | |||
| int getNumSampleRates() { return 1;} | |||
| double getSampleRate (int index) { return sampleRate; } | |||
| int getDefaultBufferSize() { return 2048; } | |||
| int getNumBufferSizesAvailable() { return 50; } | |||
| Array<double> getAvailableSampleRates() override | |||
| { | |||
| Array<double> r; | |||
| r.add ((double) sampleRate); | |||
| return r; | |||
| } | |||
| int getBufferSizeSamples (int index) | |||
| Array<int> getAvailableBufferSizes() override | |||
| { | |||
| Array<int> b; | |||
| int n = 16; | |||
| for (int i = 0; i < index; ++i) | |||
| for (int i = 0; i < 50; ++i) | |||
| { | |||
| b.add (n); | |||
| n += n < 64 ? 16 | |||
| : (n < 512 ? 32 | |||
| : (n < 1024 ? 64 | |||
| : (n < 2048 ? 128 : 256))); | |||
| } | |||
| return n; | |||
| return b; | |||
| } | |||
| int getDefaultBufferSize() override { return 2048; } | |||
| String open (const BigInteger& inputChannels, | |||
| const BigInteger& outputChannels, | |||
| double requestedSampleRate, | |||
| int bufferSize) | |||
| int bufferSize) override | |||
| { | |||
| close(); | |||
| if (sampleRate != (int) requestedSampleRate) | |||
| return "Sample rate not allowed"; | |||
| lastError = String::empty; | |||
| lastError.clear(); | |||
| int preferredBufferSize = (bufferSize <= 0) ? getDefaultBufferSize() : bufferSize; | |||
| numDeviceInputChannels = 0; | |||
| @@ -227,7 +234,7 @@ public: | |||
| return lastError; | |||
| } | |||
| void close() | |||
| void close() override | |||
| { | |||
| if (isRunning) | |||
| { | |||
| @@ -237,18 +244,18 @@ public: | |||
| } | |||
| } | |||
| int getOutputLatencyInSamples() { return (minBufferSizeOut * 3) / 4; } | |||
| int getInputLatencyInSamples() { return (minBufferSizeIn * 3) / 4; } | |||
| bool isOpen() { return isRunning; } | |||
| int getCurrentBufferSizeSamples() { return actualBufferSize; } | |||
| int getCurrentBitDepth() { return 16; } | |||
| double getCurrentSampleRate() { return sampleRate; } | |||
| BigInteger getActiveOutputChannels() const { return activeOutputChans; } | |||
| BigInteger getActiveInputChannels() const { return activeInputChans; } | |||
| String getLastError() { return lastError; } | |||
| bool isPlaying() { return isRunning && callback != 0; } | |||
| void start (AudioIODeviceCallback* newCallback) | |||
| int getOutputLatencyInSamples() override { return (minBufferSizeOut * 3) / 4; } | |||
| int getInputLatencyInSamples() override { return (minBufferSizeIn * 3) / 4; } | |||
| bool isOpen() override { return isRunning; } | |||
| int getCurrentBufferSizeSamples() override { return actualBufferSize; } | |||
| int getCurrentBitDepth() override { return 16; } | |||
| double getCurrentSampleRate() override { return sampleRate; } | |||
| BigInteger getActiveOutputChannels() const override { return activeOutputChans; } | |||
| BigInteger getActiveInputChannels() const override { return activeInputChans; } | |||
| String getLastError() override { return lastError; } | |||
| bool isPlaying() override { return isRunning && callback != 0; } | |||
| void start (AudioIODeviceCallback* newCallback) override | |||
| { | |||
| if (isRunning && callback != newCallback) | |||
| { | |||
| @@ -260,7 +267,7 @@ public: | |||
| } | |||
| } | |||
| void stop() | |||
| void stop() override | |||
| { | |||
| if (isRunning) | |||
| { | |||
| @@ -30,9 +30,6 @@ bool isOpenSLAvailable() | |||
| return library.open ("libOpenSLES.so"); | |||
| } | |||
| const unsigned short openSLRates[] = { 8000, 16000, 32000, 44100, 48000 }; | |||
| const unsigned short openSLBufferSizes[] = { 256, 512, 768, 1024, 1280, 1600 }; // must all be multiples of the block size | |||
| //============================================================================== | |||
| class OpenSLAudioIODevice : public AudioIODevice, | |||
| public Thread | |||
| @@ -66,7 +63,7 @@ public: | |||
| bool openedOk() const { return engine.outputMixObject != nullptr; } | |||
| StringArray getOutputChannelNames() | |||
| StringArray getOutputChannelNames() override | |||
| { | |||
| StringArray s; | |||
| s.add ("Left"); | |||
| @@ -74,38 +71,33 @@ public: | |||
| return s; | |||
| } | |||
| StringArray getInputChannelNames() | |||
| StringArray getInputChannelNames() override | |||
| { | |||
| StringArray s; | |||
| s.add ("Audio Input"); | |||
| return s; | |||
| } | |||
| int getNumSampleRates() { return numElementsInArray (openSLRates); } | |||
| double getSampleRate (int index) | |||
| Array<double> getAvailableSampleRates() override | |||
| { | |||
| jassert (index >= 0 && index < getNumSampleRates()); | |||
| return (int) openSLRates [index]; | |||
| static const double rates[] = { 8000.0, 16000.0, 32000.0, 44100.0, 48000.0 }; | |||
| return Array<double> (rates, numElementsInArray (rates)); | |||
| } | |||
| int getDefaultBufferSize() { return 1024; } | |||
| int getNumBufferSizesAvailable() { return numElementsInArray (openSLBufferSizes); } | |||
| int getBufferSizeSamples (int index) | |||
| Array<int> getAvailableBufferSizes() override | |||
| { | |||
| jassert (index >= 0 && index < getNumBufferSizesAvailable()); | |||
| return (int) openSLBufferSizes [index]; | |||
| static const int sizes[] = { 256, 512, 768, 1024, 1280, 1600 }; // must all be multiples of the block size | |||
| return Array<int> (sizes, numElementsInArray (sizes)); | |||
| } | |||
| String open (const BigInteger& inputChannels, | |||
| const BigInteger& outputChannels, | |||
| double requestedSampleRate, | |||
| int bufferSize) | |||
| int bufferSize) override | |||
| { | |||
| close(); | |||
| lastError = String::empty; | |||
| lastError.clear(); | |||
| sampleRate = (int) requestedSampleRate; | |||
| int preferredBufferSize = (bufferSize <= 0) ? getDefaultBufferSize() : bufferSize; | |||
| @@ -133,7 +125,7 @@ public: | |||
| return lastError; | |||
| } | |||
| void close() | |||
| void close() override | |||
| { | |||
| stop(); | |||
| stopThread (6000); | |||
| @@ -142,18 +134,19 @@ public: | |||
| player = nullptr; | |||
| } | |||
| int getOutputLatencyInSamples() { return outputLatency; } | |||
| int getInputLatencyInSamples() { return inputLatency; } | |||
| bool isOpen() { return deviceOpen; } | |||
| int getCurrentBufferSizeSamples() { return actualBufferSize; } | |||
| int getCurrentBitDepth() { return 16; } | |||
| double getCurrentSampleRate() { return sampleRate; } | |||
| BigInteger getActiveOutputChannels() const { return activeOutputChans; } | |||
| BigInteger getActiveInputChannels() const { return activeInputChans; } | |||
| String getLastError() { return lastError; } | |||
| bool isPlaying() { return callback != nullptr; } | |||
| void start (AudioIODeviceCallback* newCallback) | |||
| int getDefaultBufferSize() override { return 1024; } | |||
| int getOutputLatencyInSamples() override { return outputLatency; } | |||
| int getInputLatencyInSamples() override { return inputLatency; } | |||
| bool isOpen() override { return deviceOpen; } | |||
| int getCurrentBufferSizeSamples() override { return actualBufferSize; } | |||
| int getCurrentBitDepth() override { return 16; } | |||
| double getCurrentSampleRate() override { return sampleRate; } | |||
| BigInteger getActiveOutputChannels() const override { return activeOutputChans; } | |||
| BigInteger getActiveInputChannels() const override { return activeInputChans; } | |||
| String getLastError() override { return lastError; } | |||
| bool isPlaying() override { return callback != nullptr; } | |||
| void start (AudioIODeviceCallback* newCallback) override | |||
| { | |||
| stop(); | |||
| @@ -166,7 +159,7 @@ public: | |||
| } | |||
| } | |||
| void stop() | |||
| void stop() override | |||
| { | |||
| if (AudioIODeviceCallback* const oldCallback = setCallback (nullptr)) | |||
| oldCallback->audioDeviceStopped(); | |||
| @@ -48,7 +48,7 @@ public: | |||
| close(); | |||
| } | |||
| StringArray getOutputChannelNames() | |||
| StringArray getOutputChannelNames() override | |||
| { | |||
| StringArray s; | |||
| s.add ("Left"); | |||
| @@ -56,7 +56,7 @@ public: | |||
| return s; | |||
| } | |||
| StringArray getInputChannelNames() | |||
| StringArray getInputChannelNames() override | |||
| { | |||
| StringArray s; | |||
| if (audioInputIsAvailable) | |||
| @@ -67,20 +67,27 @@ public: | |||
| return s; | |||
| } | |||
| int getNumSampleRates() { return jmax (1, sampleRates.size()); } | |||
| double getSampleRate (int index) { return sampleRates.size() > 0 ? sampleRates [index] : sampleRate; } | |||
| Array<double> getAvailableSampleRates() override { return sampleRates; } | |||
| int getNumBufferSizesAvailable() { return 6; } | |||
| int getBufferSizeSamples (int index) { return 1 << (jlimit (0, 5, index) + 6); } | |||
| int getDefaultBufferSize() { return 1024; } | |||
| Array<int> getAvailableBufferSizes() override | |||
| { | |||
| Array<int> r; | |||
| for (int i = 6; i < 12; ++i) | |||
| r.add (1 << i); | |||
| return r; | |||
| } | |||
| int getDefaultBufferSize() override { return 1024; } | |||
| String open (const BigInteger& inputChannelsWanted, | |||
| const BigInteger& outputChannelsWanted, | |||
| double targetSampleRate, int bufferSize) | |||
| double targetSampleRate, int bufferSize) override | |||
| { | |||
| close(); | |||
| lastError = String::empty; | |||
| lastError.clear(); | |||
| preferredBufferSize = (bufferSize <= 0) ? getDefaultBufferSize() : bufferSize; | |||
| // xxx set up channel mapping | |||
| @@ -115,7 +122,7 @@ public: | |||
| setSessionFloat64Property (kAudioSessionProperty_PreferredHardwareSampleRate, targetSampleRate); | |||
| updateSampleRates(); | |||
| setSessionFloat64Property (kAudioSessionProperty_PreferredHardwareIOBufferDuration, preferredBufferSize / sampleRate); | |||
| setSessionFloat32Property (kAudioSessionProperty_PreferredHardwareIOBufferDuration, preferredBufferSize / sampleRate); | |||
| updateCurrentBufferSize(); | |||
| prepareFloatBuffers (actualBufferSize); | |||
| @@ -127,7 +134,7 @@ public: | |||
| return lastError; | |||
| } | |||
| void close() | |||
| void close() override | |||
| { | |||
| if (isRunning) | |||
| { | |||
| @@ -146,19 +153,19 @@ public: | |||
| } | |||
| } | |||
| bool isOpen() { return isRunning; } | |||
| bool isOpen() override { return isRunning; } | |||
| int getCurrentBufferSizeSamples() { return actualBufferSize; } | |||
| double getCurrentSampleRate() { return sampleRate; } | |||
| int getCurrentBitDepth() { return 16; } | |||
| int getCurrentBufferSizeSamples() override { return actualBufferSize; } | |||
| double getCurrentSampleRate() override { return sampleRate; } | |||
| int getCurrentBitDepth() override { return 16; } | |||
| BigInteger getActiveOutputChannels() const { return activeOutputChans; } | |||
| BigInteger getActiveInputChannels() const { return activeInputChans; } | |||
| BigInteger getActiveOutputChannels() const override { return activeOutputChans; } | |||
| BigInteger getActiveInputChannels() const override { return activeInputChans; } | |||
| int getOutputLatencyInSamples() { return 0; } //xxx | |||
| int getInputLatencyInSamples() { return 0; } //xxx | |||
| int getOutputLatencyInSamples() override { return 0; } //xxx | |||
| int getInputLatencyInSamples() override { return 0; } //xxx | |||
| void start (AudioIODeviceCallback* newCallback) | |||
| void start (AudioIODeviceCallback* newCallback) override | |||
| { | |||
| if (isRunning && callback != newCallback) | |||
| { | |||
| @@ -170,7 +177,7 @@ public: | |||
| } | |||
| } | |||
| void stop() | |||
| void stop() override | |||
| { | |||
| if (isRunning) | |||
| { | |||
| @@ -187,8 +194,8 @@ public: | |||
| } | |||
| } | |||
| bool isPlaying() { return isRunning && callback != nullptr; } | |||
| String getLastError() { return lastError; } | |||
| bool isPlaying() override { return isRunning && callback != nullptr; } | |||
| String getLastError() override { return lastError; } | |||
| private: | |||
| //================================================================================================== | |||
| @@ -240,8 +247,8 @@ private: | |||
| if (callback != nullptr) | |||
| { | |||
| // This shouldn't ever get triggered, but please let me know if it does! | |||
| jassert ((int) numFrames <= floatData.getNumSamples()); | |||
| if ((int) numFrames > floatData.getNumSamples()) | |||
| prepareFloatBuffers ((int) numFrames); | |||
| if (audioInputIsAvailable && numInputChannels > 0) | |||
| { | |||
| @@ -436,6 +443,11 @@ private: | |||
| isRunning = true; | |||
| AudioSessionSetActive (true); | |||
| AudioOutputUnitStart (audioUnit); | |||
| const ScopedLock sl (callbackLock); | |||
| if (callback != nullptr) | |||
| callback->audioDeviceError ("iOS audio session resumed"); | |||
| } | |||
| } | |||
| @@ -541,6 +553,7 @@ private: | |||
| } | |||
| static void setSessionUInt32Property (AudioSessionPropertyID propID, UInt32 v) noexcept { AudioSessionSetProperty (propID, sizeof (v), &v); } | |||
| static void setSessionFloat32Property (AudioSessionPropertyID propID, Float32 v) noexcept { AudioSessionSetProperty (propID, sizeof (v), &v); } | |||
| static void setSessionFloat64Property (AudioSessionPropertyID propID, Float64 v) noexcept { AudioSessionSetProperty (propID, sizeof (v), &v); } | |||
| JUCE_DECLARE_NON_COPYABLE (iOSAudioIODevice) | |||
| @@ -47,7 +47,7 @@ namespace | |||
| #define JUCE_ALSA_FAILED(x) failed (x) | |||
| static void getDeviceSampleRates (snd_pcm_t* handle, Array <int>& rates) | |||
| static void getDeviceSampleRates (snd_pcm_t* handle, Array<double>& rates) | |||
| { | |||
| const int ratesToTry[] = { 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 0 }; | |||
| @@ -59,7 +59,7 @@ static void getDeviceSampleRates (snd_pcm_t* handle, Array <int>& rates) | |||
| if (snd_pcm_hw_params_any (handle, hwParams) >= 0 | |||
| && snd_pcm_hw_params_test_rate (handle, hwParams, ratesToTry[i], 0) == 0) | |||
| { | |||
| rates.addIfNotAlreadyThere (ratesToTry[i]); | |||
| rates.addIfNotAlreadyThere ((double) ratesToTry[i]); | |||
| } | |||
| } | |||
| } | |||
| @@ -91,7 +91,7 @@ static void getDeviceProperties (const String& deviceID, | |||
| unsigned int& maxChansOut, | |||
| unsigned int& minChansIn, | |||
| unsigned int& maxChansIn, | |||
| Array <int>& rates, | |||
| Array<double>& rates, | |||
| bool testOutput, | |||
| bool testInput) | |||
| { | |||
| @@ -482,7 +482,7 @@ public: | |||
| { | |||
| close(); | |||
| error = String::empty; | |||
| error.clear(); | |||
| sampleRate = newSampleRate; | |||
| bufferSize = newBufferSize; | |||
| @@ -722,7 +722,7 @@ public: | |||
| int bufferSize, outputLatency, inputLatency; | |||
| BigInteger currentInputChans, currentOutputChans; | |||
| Array <int> sampleRates; | |||
| Array<double> sampleRates; | |||
| StringArray channelNamesOut, channelNamesIn; | |||
| AudioIODeviceCallback* callback; | |||
| @@ -798,31 +798,34 @@ public: | |||
| close(); | |||
| } | |||
| StringArray getOutputChannelNames() { return internal.channelNamesOut; } | |||
| StringArray getInputChannelNames() { return internal.channelNamesIn; } | |||
| StringArray getOutputChannelNames() override { return internal.channelNamesOut; } | |||
| StringArray getInputChannelNames() override { return internal.channelNamesIn; } | |||
| int getNumSampleRates() { return internal.sampleRates.size(); } | |||
| double getSampleRate (int index) { return internal.sampleRates [index]; } | |||
| Array<double> getAvailableSampleRates() override { return internal.sampleRates; } | |||
| int getDefaultBufferSize() { return 512; } | |||
| int getNumBufferSizesAvailable() { return 50; } | |||
| int getBufferSizeSamples (int index) | |||
| Array<int> getAvailableBufferSizes() override | |||
| { | |||
| Array<int> r; | |||
| int n = 16; | |||
| for (int i = 0; i < index; ++i) | |||
| for (int i = 0; i < 50; ++i) | |||
| { | |||
| r.add (n); | |||
| n += n < 64 ? 16 | |||
| : (n < 512 ? 32 | |||
| : (n < 1024 ? 64 | |||
| : (n < 2048 ? 128 : 256))); | |||
| } | |||
| return n; | |||
| return r; | |||
| } | |||
| int getDefaultBufferSize() override { return 512; } | |||
| String open (const BigInteger& inputChannels, | |||
| const BigInteger& outputChannels, | |||
| double sampleRate, | |||
| int bufferSizeSamples) | |||
| int bufferSizeSamples) override | |||
| { | |||
| close(); | |||
| @@ -831,11 +834,13 @@ public: | |||
| if (sampleRate <= 0) | |||
| { | |||
| for (int i = 0; i < getNumSampleRates(); ++i) | |||
| for (int i = 0; i < internal.sampleRates.size(); ++i) | |||
| { | |||
| if (getSampleRate (i) >= 44100) | |||
| double rate = internal.sampleRates[i]; | |||
| if (rate >= 44100) | |||
| { | |||
| sampleRate = getSampleRate (i); | |||
| sampleRate = rate; | |||
| break; | |||
| } | |||
| } | |||
| @@ -848,28 +853,28 @@ public: | |||
| return internal.error; | |||
| } | |||
| void close() | |||
| void close() override | |||
| { | |||
| stop(); | |||
| internal.close(); | |||
| isOpen_ = false; | |||
| } | |||
| bool isOpen() { return isOpen_; } | |||
| bool isPlaying() { return isStarted && internal.error.isEmpty(); } | |||
| String getLastError() { return internal.error; } | |||
| bool isOpen() override { return isOpen_; } | |||
| bool isPlaying() override { return isStarted && internal.error.isEmpty(); } | |||
| String getLastError() override { return internal.error; } | |||
| int getCurrentBufferSizeSamples() { return internal.bufferSize; } | |||
| double getCurrentSampleRate() { return internal.sampleRate; } | |||
| int getCurrentBitDepth() { return internal.getBitDepth(); } | |||
| int getCurrentBufferSizeSamples() override { return internal.bufferSize; } | |||
| double getCurrentSampleRate() override { return internal.sampleRate; } | |||
| int getCurrentBitDepth() override { return internal.getBitDepth(); } | |||
| BigInteger getActiveOutputChannels() const { return internal.currentOutputChans; } | |||
| BigInteger getActiveInputChannels() const { return internal.currentInputChans; } | |||
| BigInteger getActiveOutputChannels() const override { return internal.currentOutputChans; } | |||
| BigInteger getActiveInputChannels() const override { return internal.currentInputChans; } | |||
| int getOutputLatencyInSamples() { return internal.outputLatency; } | |||
| int getInputLatencyInSamples() { return internal.inputLatency; } | |||
| int getOutputLatencyInSamples() override { return internal.outputLatency; } | |||
| int getInputLatencyInSamples() override { return internal.inputLatency; } | |||
| void start (AudioIODeviceCallback* callback) | |||
| void start (AudioIODeviceCallback* callback) override | |||
| { | |||
| if (! isOpen_) | |||
| callback = nullptr; | |||
| @@ -882,7 +887,7 @@ public: | |||
| isStarted = (callback != nullptr); | |||
| } | |||
| void stop() | |||
| void stop() override | |||
| { | |||
| AudioIODeviceCallback* const oldCallback = internal.callback; | |||
| @@ -1002,7 +1007,7 @@ private: | |||
| { | |||
| unsigned int minChansOut = 0, maxChansOut = 0; | |||
| unsigned int minChansIn = 0, maxChansIn = 0; | |||
| Array <int> rates; | |||
| Array<double> rates; | |||
| bool isInput = inputName.isNotEmpty(), isOutput = outputName.isNotEmpty(); | |||
| getDeviceProperties (id, minChansOut, maxChansOut, minChansIn, maxChansIn, rates, isOutput, isInput); | |||
| @@ -218,16 +218,36 @@ public: | |||
| return names; | |||
| } | |||
| StringArray getOutputChannelNames() { return getChannelNames (false); } | |||
| StringArray getInputChannelNames() { return getChannelNames (true); } | |||
| int getNumSampleRates() { return client != nullptr ? 1 : 0; } | |||
| double getSampleRate (int /*index*/) { return client != nullptr ? juce::jack_get_sample_rate (client) : 0; } | |||
| int getNumBufferSizesAvailable() { return client != nullptr ? 1 : 0; } | |||
| int getBufferSizeSamples (int /*index*/) { return getDefaultBufferSize(); } | |||
| int getDefaultBufferSize() { return client != nullptr ? juce::jack_get_buffer_size (client) : 0; } | |||
| StringArray getOutputChannelNames() override { return getChannelNames (false); } | |||
| StringArray getInputChannelNames() override { return getChannelNames (true); } | |||
| Array<double> getAvailableSampleRates() override | |||
| { | |||
| Array<double> rates; | |||
| if (client != nullptr) | |||
| rates.add (juce::jack_get_sample_rate (client)); | |||
| return rates; | |||
| } | |||
| Array<int> getAvailableBufferSizes() override | |||
| { | |||
| Array<int> sizes; | |||
| if (client != nullptr) | |||
| sizes.add (juce::jack_get_buffer_size (client)); | |||
| return sizes; | |||
| } | |||
| int getDefaultBufferSize() override { return getCurrentBufferSizeSamples(); } | |||
| int getCurrentBufferSizeSamples() override { return client != nullptr ? juce::jack_get_buffer_size (client) : 0; } | |||
| double getCurrentSampleRate() override { return client != nullptr ? juce::jack_get_sample_rate (client) : 0; } | |||
| String open (const BigInteger& inputChannels, const BigInteger& outputChannels, | |||
| double /* sampleRate */, int /* bufferSizeSamples */) | |||
| double /* sampleRate */, int /* bufferSizeSamples */) override | |||
| { | |||
| if (client == nullptr) | |||
| { | |||
| @@ -235,7 +255,7 @@ public: | |||
| return lastError; | |||
| } | |||
| lastError = String::empty; | |||
| lastError.clear(); | |||
| close(); | |||
| juce::jack_set_process_callback (client, processCallback, this); | |||
| @@ -273,7 +293,7 @@ public: | |||
| return lastError; | |||
| } | |||
| void close() | |||
| void close() override | |||
| { | |||
| stop(); | |||
| @@ -288,7 +308,7 @@ public: | |||
| deviceIsOpen = false; | |||
| } | |||
| void start (AudioIODeviceCallback* newCallback) | |||
| void start (AudioIODeviceCallback* newCallback) override | |||
| { | |||
| if (deviceIsOpen && newCallback != callback) | |||
| { | |||
| @@ -307,22 +327,20 @@ public: | |||
| } | |||
| } | |||
| void stop() | |||
| void stop() override | |||
| { | |||
| start (nullptr); | |||
| } | |||
| bool isOpen() { return deviceIsOpen; } | |||
| bool isPlaying() { return callback != nullptr; } | |||
| int getCurrentBufferSizeSamples() { return getBufferSizeSamples (0); } | |||
| double getCurrentSampleRate() { return getSampleRate (0); } | |||
| int getCurrentBitDepth() { return 32; } | |||
| String getLastError() { return lastError; } | |||
| bool isOpen() override { return deviceIsOpen; } | |||
| bool isPlaying() override { return callback != nullptr; } | |||
| int getCurrentBitDepth() override { return 32; } | |||
| String getLastError() override { return lastError; } | |||
| BigInteger getActiveOutputChannels() const { return activeOutputChannels; } | |||
| BigInteger getActiveInputChannels() const { return activeInputChannels; } | |||
| BigInteger getActiveOutputChannels() const override { return activeOutputChannels; } | |||
| BigInteger getActiveInputChannels() const override { return activeInputChannels; } | |||
| int getOutputLatencyInSamples() | |||
| int getOutputLatencyInSamples() override | |||
| { | |||
| int latency = 0; | |||
| @@ -332,7 +350,7 @@ public: | |||
| return latency; | |||
| } | |||
| int getInputLatencyInSamples() | |||
| int getInputLatencyInSamples() override | |||
| { | |||
| int latency = 0; | |||
| @@ -366,13 +366,13 @@ public: | |||
| { | |||
| // find a list of sample rates.. | |||
| const int possibleSampleRates[] = { 44100, 48000, 88200, 96000, 176400, 192000 }; | |||
| Array<int> newRates; | |||
| Array<double> newRates; | |||
| if (asioObject != nullptr) | |||
| { | |||
| for (int index = 0; index < numElementsInArray (possibleSampleRates); ++index) | |||
| if (asioObject->canSampleRate ((double) possibleSampleRates[index]) == 0) | |||
| newRates.add (possibleSampleRates[index]); | |||
| newRates.add ((double) possibleSampleRates[index]); | |||
| } | |||
| if (newRates.size() == 0) | |||
| @@ -398,19 +398,16 @@ public: | |||
| } | |||
| } | |||
| StringArray getOutputChannelNames() { return outputChannelNames; } | |||
| StringArray getInputChannelNames() { return inputChannelNames; } | |||
| StringArray getOutputChannelNames() override { return outputChannelNames; } | |||
| StringArray getInputChannelNames() override { return inputChannelNames; } | |||
| int getNumSampleRates() { return sampleRates.size(); } | |||
| double getSampleRate (int index) { return sampleRates [index]; } | |||
| int getNumBufferSizesAvailable() { return bufferSizes.size(); } | |||
| int getBufferSizeSamples (int index) { return bufferSizes [index]; } | |||
| int getDefaultBufferSize() { return preferredSize; } | |||
| Array<double> getAvailableSampleRates() override { return sampleRates; } | |||
| Array<int> getAvailableBufferSizes() override { return bufferSizes; } | |||
| int getDefaultBufferSize() override { return preferredSize; } | |||
| String open (const BigInteger& inputChannels, | |||
| const BigInteger& outputChannels, | |||
| double sr, int bufferSizeSamples) | |||
| double sr, int bufferSizeSamples) override | |||
| { | |||
| if (isOpen()) | |||
| close(); | |||
| @@ -436,7 +433,7 @@ public: | |||
| bufferSizeSamples = readBufferSizes (bufferSizeSamples); | |||
| int sampleRate = roundToInt (sr); | |||
| double sampleRate = sr; | |||
| currentSampleRate = sampleRate; | |||
| currentBlockSizeSamples = bufferSizeSamples; | |||
| currentChansOut.clear(); | |||
| @@ -451,12 +448,12 @@ public: | |||
| jassert (sampleRate != 0); | |||
| if (sampleRate == 0) | |||
| sampleRate = 44100; | |||
| sampleRate = 44100.0; | |||
| updateClockSources(); | |||
| currentSampleRate = getSampleRate(); | |||
| error = String::empty; | |||
| error.clear(); | |||
| buffersCreated = false; | |||
| setSampleRate (sampleRate); | |||
| @@ -615,9 +612,9 @@ public: | |||
| return error; | |||
| } | |||
| void close() | |||
| void close() override | |||
| { | |||
| error = String::empty; | |||
| error.clear(); | |||
| stopTimer(); | |||
| stop(); | |||
| @@ -643,20 +640,20 @@ public: | |||
| } | |||
| } | |||
| bool isOpen() { return deviceIsOpen || insideControlPanelModalLoop; } | |||
| bool isPlaying() { return asioObject != nullptr && currentCallback != nullptr; } | |||
| bool isOpen() override { return deviceIsOpen || insideControlPanelModalLoop; } | |||
| bool isPlaying() override { return asioObject != nullptr && currentCallback != nullptr; } | |||
| int getCurrentBufferSizeSamples() { return currentBlockSizeSamples; } | |||
| double getCurrentSampleRate() { return currentSampleRate; } | |||
| int getCurrentBitDepth() { return currentBitDepth; } | |||
| int getCurrentBufferSizeSamples() override { return currentBlockSizeSamples; } | |||
| double getCurrentSampleRate() override { return currentSampleRate; } | |||
| int getCurrentBitDepth() override { return currentBitDepth; } | |||
| BigInteger getActiveOutputChannels() const { return currentChansOut; } | |||
| BigInteger getActiveInputChannels() const { return currentChansIn; } | |||
| BigInteger getActiveOutputChannels() const override { return currentChansOut; } | |||
| BigInteger getActiveInputChannels() const override { return currentChansIn; } | |||
| int getOutputLatencyInSamples() { return outputLatency + currentBlockSizeSamples / 4; } | |||
| int getInputLatencyInSamples() { return inputLatency + currentBlockSizeSamples / 4; } | |||
| int getOutputLatencyInSamples() override { return outputLatency + currentBlockSizeSamples / 4; } | |||
| int getInputLatencyInSamples() override { return inputLatency + currentBlockSizeSamples / 4; } | |||
| void start (AudioIODeviceCallback* callback) | |||
| void start (AudioIODeviceCallback* callback) override | |||
| { | |||
| if (callback != nullptr) | |||
| { | |||
| @@ -667,7 +664,7 @@ public: | |||
| } | |||
| } | |||
| void stop() | |||
| void stop() override | |||
| { | |||
| AudioIODeviceCallback* const lastCallback = currentCallback; | |||
| @@ -764,7 +761,8 @@ private: | |||
| long totalNumInputChans, totalNumOutputChans; | |||
| StringArray inputChannelNames, outputChannelNames; | |||
| Array<int> sampleRates, bufferSizes; | |||
| Array<double> sampleRates; | |||
| Array<int> bufferSizes; | |||
| long inputLatency, outputLatency; | |||
| long minSize, maxSize, preferredSize, granularity; | |||
| ASIOClockSource clocks[32]; | |||
| @@ -951,7 +949,7 @@ private: | |||
| return cr; | |||
| } | |||
| void setSampleRate (int newRate) | |||
| void setSampleRate (double newRate) | |||
| { | |||
| if (currentSampleRate != newRate) | |||
| { | |||
| @@ -1181,7 +1179,7 @@ private: | |||
| numActiveOutputChans = 0; | |||
| currentCallback = nullptr; | |||
| error = String::empty; | |||
| error.clear(); | |||
| if (getName().isEmpty()) | |||
| return error; | |||
| @@ -1389,10 +1387,10 @@ private: | |||
| sendResetRequest (deviceIndex); | |||
| } | |||
| static long sendResetRequest (int targetIndex) | |||
| static long sendResetRequest (int index) | |||
| { | |||
| if (currentASIODev[targetIndex] != nullptr) | |||
| currentASIODev[targetIndex]->resetRequest(); | |||
| if (currentASIODev[index] != nullptr) | |||
| currentASIODev[index]->resetRequest(); | |||
| return 1; | |||
| } | |||
| @@ -755,7 +755,7 @@ public: | |||
| String open (const BigInteger& inputChannels, | |||
| const BigInteger& outputChannels, | |||
| double sampleRate, int bufferSizeSamples) | |||
| double sampleRate, int bufferSizeSamples) override | |||
| { | |||
| lastError = openDevice (inputChannels, outputChannels, sampleRate, bufferSizeSamples); | |||
| isOpen_ = lastError.isEmpty(); | |||
| @@ -763,7 +763,7 @@ public: | |||
| return lastError; | |||
| } | |||
| void close() | |||
| void close() override | |||
| { | |||
| stop(); | |||
| @@ -774,38 +774,41 @@ public: | |||
| } | |||
| } | |||
| bool isOpen() { return isOpen_ && isThreadRunning(); } | |||
| int getCurrentBufferSizeSamples() { return bufferSizeSamples; } | |||
| double getCurrentSampleRate() { return sampleRate; } | |||
| BigInteger getActiveOutputChannels() const { return enabledOutputs; } | |||
| BigInteger getActiveInputChannels() const { return enabledInputs; } | |||
| int getOutputLatencyInSamples() { return (int) (getCurrentBufferSizeSamples() * 1.5); } | |||
| int getInputLatencyInSamples() { return getOutputLatencyInSamples(); } | |||
| StringArray getOutputChannelNames() { return outChannels; } | |||
| StringArray getInputChannelNames() { return inChannels; } | |||
| int getNumSampleRates() { return 4; } | |||
| int getDefaultBufferSize() { return 2560; } | |||
| int getNumBufferSizesAvailable() { return 50; } | |||
| double getSampleRate (int index) | |||
| bool isOpen() override { return isOpen_ && isThreadRunning(); } | |||
| int getCurrentBufferSizeSamples() override { return bufferSizeSamples; } | |||
| double getCurrentSampleRate() override { return sampleRate; } | |||
| BigInteger getActiveOutputChannels() const override { return enabledOutputs; } | |||
| BigInteger getActiveInputChannels() const override { return enabledInputs; } | |||
| int getOutputLatencyInSamples() override { return (int) (getCurrentBufferSizeSamples() * 1.5); } | |||
| int getInputLatencyInSamples() override { return getOutputLatencyInSamples(); } | |||
| StringArray getOutputChannelNames() override { return outChannels; } | |||
| StringArray getInputChannelNames() override { return inChannels; } | |||
| Array<double> getAvailableSampleRates() override | |||
| { | |||
| const double samps[] = { 44100.0, 48000.0, 88200.0, 96000.0 }; | |||
| return samps [jlimit (0, 3, index)]; | |||
| static const double rates[] = { 44100.0, 48000.0, 88200.0, 96000.0 }; | |||
| return Array<double> (rates, numElementsInArray (rates)); | |||
| } | |||
| int getBufferSizeSamples (int index) | |||
| Array<int> getAvailableBufferSizes() override | |||
| { | |||
| Array<int> r; | |||
| int n = 64; | |||
| for (int i = 0; i < index; ++i) | |||
| for (int i = 0; i < 50; ++i) | |||
| { | |||
| r.add (n); | |||
| n += (n < 512) ? 32 | |||
| : ((n < 1024) ? 64 | |||
| : ((n < 2048) ? 128 : 256)); | |||
| } | |||
| return n; | |||
| return r; | |||
| } | |||
| int getCurrentBitDepth() | |||
| int getDefaultBufferSize() override { return 2560; } | |||
| int getCurrentBitDepth() override | |||
| { | |||
| int bits = 256; | |||
| @@ -821,7 +824,7 @@ public: | |||
| return bits; | |||
| } | |||
| void start (AudioIODeviceCallback* call) | |||
| void start (AudioIODeviceCallback* call) override | |||
| { | |||
| if (isOpen_ && call != nullptr && ! isStarted) | |||
| { | |||
| @@ -840,7 +843,7 @@ public: | |||
| } | |||
| } | |||
| void stop() | |||
| void stop() override | |||
| { | |||
| if (isStarted) | |||
| { | |||
| @@ -856,8 +859,8 @@ public: | |||
| } | |||
| } | |||
| bool isPlaying() { return isStarted && isOpen_ && isThreadRunning(); } | |||
| String getLastError() { return lastError; } | |||
| bool isPlaying() override { return isStarted && isOpen_ && isThreadRunning(); } | |||
| String getLastError() override { return lastError; } | |||
| //============================================================================== | |||
| StringArray inChannels, outChannels; | |||
| @@ -882,7 +882,7 @@ public: | |||
| return false; | |||
| } | |||
| StringArray getOutputChannelNames() | |||
| StringArray getOutputChannelNames() override | |||
| { | |||
| StringArray outChannels; | |||
| @@ -893,7 +893,7 @@ public: | |||
| return outChannels; | |||
| } | |||
| StringArray getInputChannelNames() | |||
| StringArray getInputChannelNames() override | |||
| { | |||
| StringArray inChannels; | |||
| @@ -904,31 +904,29 @@ public: | |||
| return inChannels; | |||
| } | |||
| int getNumSampleRates() { return sampleRates.size(); } | |||
| double getSampleRate (int index) { return sampleRates [index]; } | |||
| int getNumBufferSizesAvailable() { return bufferSizes.size(); } | |||
| int getBufferSizeSamples (int index) { return bufferSizes [index]; } | |||
| int getDefaultBufferSize() { return defaultBufferSize; } | |||
| Array<double> getAvailableSampleRates() override { return sampleRates; } | |||
| Array<int> getAvailableBufferSizes() override { return bufferSizes; } | |||
| int getDefaultBufferSize() override { return defaultBufferSize; } | |||
| int getCurrentBufferSizeSamples() { return currentBufferSizeSamples; } | |||
| double getCurrentSampleRate() { return currentSampleRate; } | |||
| int getCurrentBitDepth() { return 32; } | |||
| int getOutputLatencyInSamples() { return latencyOut; } | |||
| int getInputLatencyInSamples() { return latencyIn; } | |||
| BigInteger getActiveOutputChannels() const { return outputDevice != nullptr ? outputDevice->channels : BigInteger(); } | |||
| BigInteger getActiveInputChannels() const { return inputDevice != nullptr ? inputDevice->channels : BigInteger(); } | |||
| String getLastError() { return lastError; } | |||
| int getCurrentBufferSizeSamples() override { return currentBufferSizeSamples; } | |||
| double getCurrentSampleRate() override { return currentSampleRate; } | |||
| int getCurrentBitDepth() override { return 32; } | |||
| int getOutputLatencyInSamples() override { return latencyOut; } | |||
| int getInputLatencyInSamples() override { return latencyIn; } | |||
| BigInteger getActiveOutputChannels() const override { return outputDevice != nullptr ? outputDevice->channels : BigInteger(); } | |||
| BigInteger getActiveInputChannels() const override { return inputDevice != nullptr ? inputDevice->channels : BigInteger(); } | |||
| String getLastError() override { return lastError; } | |||
| String open (const BigInteger& inputChannels, const BigInteger& outputChannels, | |||
| double sampleRate, int bufferSizeSamples) | |||
| double sampleRate, int bufferSizeSamples) override | |||
| { | |||
| close(); | |||
| lastError = String::empty; | |||
| lastError.clear(); | |||
| if (sampleRates.size() == 0 && inputDevice != nullptr && outputDevice != nullptr) | |||
| { | |||
| lastError = "The input and output devices don't share a common sample rate!"; | |||
| lastError = TRANS("The input and output devices don't share a common sample rate!"); | |||
| return lastError; | |||
| } | |||
| @@ -939,14 +937,14 @@ public: | |||
| if (inputDevice != nullptr && ! inputDevice->open (currentSampleRate, inputChannels)) | |||
| { | |||
| lastError = "Couldn't open the input device!"; | |||
| lastError = TRANS("Couldn't open the input device!"); | |||
| return lastError; | |||
| } | |||
| if (outputDevice != nullptr && ! outputDevice->open (currentSampleRate, outputChannels)) | |||
| { | |||
| close(); | |||
| lastError = "Couldn't open the output device!"; | |||
| lastError = TRANS("Couldn't open the output device!"); | |||
| return lastError; | |||
| } | |||
| @@ -963,7 +961,7 @@ public: | |||
| if (! check (inputDevice->client->Start())) | |||
| { | |||
| close(); | |||
| lastError = "Couldn't start the input device!"; | |||
| lastError = TRANS("Couldn't start the input device!"); | |||
| return lastError; | |||
| } | |||
| } | |||
| @@ -975,7 +973,7 @@ public: | |||
| if (! check (outputDevice->client->Start())) | |||
| { | |||
| close(); | |||
| lastError = "Couldn't start the output device!"; | |||
| lastError = TRANS("Couldn't start the output device!"); | |||
| return lastError; | |||
| } | |||
| } | |||
| @@ -984,7 +982,7 @@ public: | |||
| return lastError; | |||
| } | |||
| void close() | |||
| void close() override | |||
| { | |||
| stop(); | |||
| signalThreadShouldExit(); | |||
| @@ -1000,10 +998,10 @@ public: | |||
| isOpen_ = false; | |||
| } | |||
| bool isOpen() { return isOpen_ && isThreadRunning(); } | |||
| bool isPlaying() { return isStarted && isOpen_ && isThreadRunning(); } | |||
| bool isOpen() override { return isOpen_ && isThreadRunning(); } | |||
| bool isPlaying() override { return isStarted && isOpen_ && isThreadRunning(); } | |||
| void start (AudioIODeviceCallback* call) | |||
| void start (AudioIODeviceCallback* call) override | |||
| { | |||
| if (isOpen_ && call != nullptr && ! isStarted) | |||
| { | |||
| @@ -1022,7 +1020,7 @@ public: | |||
| } | |||
| } | |||
| void stop() | |||
| void stop() override | |||
| { | |||
| if (isStarted) | |||
| { | |||
| @@ -65,8 +65,7 @@ public: | |||
| void setSource (AudioSource* newSource); | |||
| /** Returns the source that's playing. | |||
| May return 0 if there's no source. | |||
| May return nullptr if there's no source. | |||
| */ | |||
| AudioSource* getCurrentSource() const noexcept { return source; } | |||
| @@ -44,15 +44,12 @@ AudioTransportSource::AudioTransportSource() | |||
| AudioTransportSource::~AudioTransportSource() | |||
| { | |||
| setSource (nullptr); | |||
| releaseMasterResources(); | |||
| } | |||
| void AudioTransportSource::setSource (PositionableAudioSource* const newSource, | |||
| int readAheadBufferSize_, | |||
| TimeSliceThread* readAheadThread, | |||
| double sourceSampleRateToCorrectFor, | |||
| int maxNumChannels) | |||
| int readAheadSize, TimeSliceThread* readAheadThread, | |||
| double sourceSampleRateToCorrectFor, int maxNumChannels) | |||
| { | |||
| if (source == newSource) | |||
| { | |||
| @@ -62,7 +59,7 @@ void AudioTransportSource::setSource (PositionableAudioSource* const newSource, | |||
| setSource (nullptr, 0, nullptr); // deselect and reselect to avoid releasing resources wrongly | |||
| } | |||
| readAheadBufferSize = readAheadBufferSize_; | |||
| readAheadBufferSize = readAheadSize; | |||
| sourceSampleRate = sourceSampleRateToCorrectFor; | |||
| ResamplingAudioSource* newResamplerSource = nullptr; | |||
| @@ -70,15 +67,15 @@ void AudioTransportSource::setSource (PositionableAudioSource* const newSource, | |||
| PositionableAudioSource* newPositionableSource = nullptr; | |||
| AudioSource* newMasterSource = nullptr; | |||
| ScopedPointer <ResamplingAudioSource> oldResamplerSource (resamplerSource); | |||
| ScopedPointer <BufferingAudioSource> oldBufferingSource (bufferingSource); | |||
| ScopedPointer<ResamplingAudioSource> oldResamplerSource (resamplerSource); | |||
| ScopedPointer<BufferingAudioSource> oldBufferingSource (bufferingSource); | |||
| AudioSource* oldMasterSource = masterSource; | |||
| if (newSource != nullptr) | |||
| { | |||
| newPositionableSource = newSource; | |||
| if (readAheadBufferSize_ > 0) | |||
| if (readAheadSize > 0) | |||
| { | |||
| // If you want to use a read-ahead buffer, you must also provide a TimeSliceThread | |||
| // for it to use! | |||
| @@ -86,7 +83,7 @@ void AudioTransportSource::setSource (PositionableAudioSource* const newSource, | |||
| newPositionableSource = newBufferingSource | |||
| = new BufferingAudioSource (newPositionableSource, *readAheadThread, | |||
| false, readAheadBufferSize_, maxNumChannels); | |||
| false, readAheadSize, maxNumChannels); | |||
| } | |||
| newPositionableSource->setNextReadPosition (0); | |||
| @@ -115,6 +112,7 @@ void AudioTransportSource::setSource (PositionableAudioSource* const newSource, | |||
| masterSource = newMasterSource; | |||
| positionableSource = newPositionableSource; | |||
| inputStreamEOF = false; | |||
| playing = false; | |||
| } | |||
| @@ -170,7 +168,10 @@ double AudioTransportSource::getCurrentPosition() const | |||
| double AudioTransportSource::getLengthInSeconds() const | |||
| { | |||
| return getTotalLength() / sampleRate; | |||
| if (sampleRate > 0.0) | |||
| return getTotalLength() / sampleRate; | |||
| return 0.0; | |||
| } | |||
| void AudioTransportSource::setNextReadPosition (int64 newPosition) | |||
| @@ -181,6 +182,7 @@ void AudioTransportSource::setNextReadPosition (int64 newPosition) | |||
| newPosition = (int64) (newPosition * sourceSampleRate / sampleRate); | |||
| positionableSource->setNextReadPosition (newPosition); | |||
| inputStreamEOF = false; | |||
| } | |||
| } | |||
| @@ -189,7 +191,6 @@ int64 AudioTransportSource::getNextReadPosition() const | |||
| if (positionableSource != nullptr) | |||
| { | |||
| const double ratio = (sampleRate > 0 && sourceSampleRate > 0) ? sampleRate / sourceSampleRate : 1.0; | |||
| return (int64) (positionableSource->getNextReadPosition() * ratio); | |||
| } | |||
| @@ -203,7 +204,6 @@ int64 AudioTransportSource::getTotalLength() const | |||
| if (positionableSource != nullptr) | |||
| { | |||
| const double ratio = (sampleRate > 0 && sourceSampleRate > 0) ? sampleRate / sourceSampleRate : 1.0; | |||
| return (int64) (positionableSource->getTotalLength() * ratio); | |||
| } | |||
| @@ -213,9 +213,7 @@ int64 AudioTransportSource::getTotalLength() const | |||
| bool AudioTransportSource::isLooping() const | |||
| { | |||
| const ScopedLock sl (callbackLock); | |||
| return positionableSource != nullptr | |||
| && positionableSource->isLooping(); | |||
| return positionableSource != nullptr && positionableSource->isLooping(); | |||
| } | |||
| void AudioTransportSource::setGain (const float newGain) noexcept | |||
| @@ -236,6 +234,7 @@ void AudioTransportSource::prepareToPlay (int samplesPerBlockExpected, double ne | |||
| if (resamplerSource != nullptr && sourceSampleRate > 0) | |||
| resamplerSource->setResamplingRatio (sourceSampleRate / sampleRate); | |||
| inputStreamEOF = false; | |||
| isPrepared = true; | |||
| } | |||
| @@ -258,8 +257,6 @@ void AudioTransportSource::getNextAudioBlock (const AudioSourceChannelInfo& info | |||
| { | |||
| const ScopedLock sl (callbackLock); | |||
| inputStreamEOF = false; | |||
| if (masterSource != nullptr && ! stopped) | |||
| { | |||
| masterSource->getNextAudioBlock (info); | |||
| @@ -275,7 +272,7 @@ void AudioTransportSource::getNextAudioBlock (const AudioSourceChannelInfo& info | |||
| } | |||
| if (positionableSource->getNextReadPosition() > positionableSource->getTotalLength() + 1 | |||
| && ! positionableSource->isLooping()) | |||
| && ! positionableSource->isLooping()) | |||
| { | |||
| playing = false; | |||
| inputStreamEOF = true; | |||
| @@ -285,10 +282,7 @@ void AudioTransportSource::getNextAudioBlock (const AudioSourceChannelInfo& info | |||
| stopped = ! playing; | |||
| for (int i = info.buffer->getNumChannels(); --i >= 0;) | |||
| { | |||
| info.buffer->applyGainRamp (i, info.startSample, info.numSamples, | |||
| lastGain, gain); | |||
| } | |||
| info.buffer->applyGainRamp (i, info.startSample, info.numSamples, lastGain, gain); | |||
| } | |||
| else | |||
| { | |||
| @@ -45,7 +45,6 @@ class JUCE_API AudioTransportSource : public PositionableAudioSource, | |||
| public: | |||
| //============================================================================== | |||
| /** Creates an AudioTransportSource. | |||
| After creating one of these, use the setSource() method to select an input source. | |||
| */ | |||
| AudioTransportSource(); | |||
| @@ -94,7 +93,6 @@ public: | |||
| void setPosition (double newPosition); | |||
| /** Returns the position that the next data block will be read from | |||
| This is a time in seconds. | |||
| */ | |||
| double getCurrentPosition() const; | |||
| @@ -102,8 +100,7 @@ public: | |||
| /** Returns the stream's length in seconds. */ | |||
| double getLengthInSeconds() const; | |||
| /** Returns true if the player has stopped because its input stream ran out of data. | |||
| */ | |||
| /** Returns true if the player has stopped because its input stream ran out of data. */ | |||
| bool hasStreamFinished() const noexcept { return inputStreamEOF; } | |||
| //============================================================================== | |||
| @@ -126,19 +123,16 @@ public: | |||
| //============================================================================== | |||
| /** Changes the gain to apply to the output. | |||
| @param newGain a factor by which to multiply the outgoing samples, | |||
| so 1.0 = 0dB, 0.5 = -6dB, 2.0 = 6dB, etc. | |||
| */ | |||
| void setGain (float newGain) noexcept; | |||
| /** Returns the current gain setting. | |||
| @see setGain | |||
| */ | |||
| float getGain() const noexcept { return gain; } | |||
| //============================================================================== | |||
| /** Implementation of the AudioSource method. */ | |||
| void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override; | |||
| @@ -175,7 +169,7 @@ private: | |||
| bool volatile playing, stopped; | |||
| double sampleRate, sourceSampleRate; | |||
| int blockSize, readAheadBufferSize; | |||
| bool isPrepared, inputStreamEOF; | |||
| bool volatile isPrepared, inputStreamEOF; | |||
| void releaseMasterResources(); | |||