| @@ -8282,18 +8282,18 @@ void TemporaryFile::createTempFile (const File& parentDirectory, String name, | |||||
| TemporaryFile::~TemporaryFile() | TemporaryFile::~TemporaryFile() | ||||
| { | { | ||||
| // Have a few attempts at deleting the file before giving up.. | |||||
| for (int i = 5; --i >= 0;) | |||||
| if (! deleteTemporaryFile()) | |||||
| { | { | ||||
| if (temporaryFile.deleteFile()) | |||||
| return; | |||||
| /* Failed to delete our temporary file! The most likely reason for this would be | |||||
| that you've not closed an output stream that was being used to write to file. | |||||
| Thread::sleep (50); | |||||
| If you find that something beyond your control is changing permissions on | |||||
| your temporary files and preventing them from being deleted, you may want to | |||||
| call TemporaryFile::deleteTemporaryFile() to detect those error cases and | |||||
| handle them appropriately. | |||||
| */ | |||||
| jassertfalse; | |||||
| } | } | ||||
| // Failed to delete our temporary file! Check that you've deleted all the | |||||
| // file output streams that were using it! | |||||
| jassertfalse; | |||||
| } | } | ||||
| bool TemporaryFile::overwriteTargetFileWithTemporary() const | bool TemporaryFile::overwriteTargetFileWithTemporary() const | ||||
| @@ -8323,6 +8323,20 @@ bool TemporaryFile::overwriteTargetFileWithTemporary() const | |||||
| return false; | return false; | ||||
| } | } | ||||
| bool TemporaryFile::deleteTemporaryFile() const | |||||
| { | |||||
| // Have a few attempts at deleting the file before giving up.. | |||||
| for (int i = 5; --i >= 0;) | |||||
| { | |||||
| if (temporaryFile.deleteFile()) | |||||
| return true; | |||||
| Thread::sleep (50); | |||||
| } | |||||
| return false; | |||||
| } | |||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| /*** End of inlined file: juce_TemporaryFile.cpp ***/ | /*** End of inlined file: juce_TemporaryFile.cpp ***/ | ||||
| @@ -260050,6 +260064,7 @@ public: | |||||
| : handle (0), | : handle (0), | ||||
| bitDepth (16), | bitDepth (16), | ||||
| numChannelsRunning (0), | numChannelsRunning (0), | ||||
| latency (0), | |||||
| isInput (forInput), | isInput (forInput), | ||||
| sampleFormat (AudioDataConverters::int16LE) | sampleFormat (AudioDataConverters::int16LE) | ||||
| { | { | ||||
| @@ -260125,6 +260140,14 @@ public: | |||||
| return false; | return false; | ||||
| } | } | ||||
| snd_pcm_uframes_t frames = 0; | |||||
| if (failed (snd_pcm_hw_params_get_period_size (hwParams, &frames, &dir)) | |||||
| || failed (snd_pcm_hw_params_get_periods (hwParams, &periods, &dir))) | |||||
| latency = 0; | |||||
| else | |||||
| latency = frames * (periods - 1); // (this is the method JACK uses to guess the latency..) | |||||
| snd_pcm_sw_params_t* swParams; | snd_pcm_sw_params_t* swParams; | ||||
| snd_pcm_sw_params_alloca (&swParams); | snd_pcm_sw_params_alloca (&swParams); | ||||
| snd_pcm_uframes_t boundary; | snd_pcm_uframes_t boundary; | ||||
| @@ -260241,7 +260264,7 @@ public: | |||||
| snd_pcm_t* handle; | snd_pcm_t* handle; | ||||
| String error; | String error; | ||||
| int bitDepth, numChannelsRunning; | |||||
| int bitDepth, numChannelsRunning, latency; | |||||
| private: | private: | ||||
| const bool isInput; | const bool isInput; | ||||
| @@ -260268,6 +260291,8 @@ public: | |||||
| : Thread ("Juce ALSA"), | : Thread ("Juce ALSA"), | ||||
| sampleRate (0), | sampleRate (0), | ||||
| bufferSize (0), | bufferSize (0), | ||||
| outputLatency (0), | |||||
| inputLatency (0), | |||||
| callback (0), | callback (0), | ||||
| inputId (inputId_), | inputId (inputId_), | ||||
| outputId (outputId_), | outputId (outputId_), | ||||
| @@ -260349,6 +260374,8 @@ public: | |||||
| outputDevice = 0; | outputDevice = 0; | ||||
| return; | return; | ||||
| } | } | ||||
| outputLatency = outputDevice->latency; | |||||
| } | } | ||||
| if (inputChannelDataForCallback.size() > 0 && inputId.isNotEmpty()) | if (inputChannelDataForCallback.size() > 0 && inputId.isNotEmpty()) | ||||
| @@ -260372,6 +260399,8 @@ public: | |||||
| inputDevice = 0; | inputDevice = 0; | ||||
| return; | return; | ||||
| } | } | ||||
| inputLatency = inputDevice->latency; | |||||
| } | } | ||||
| if (outputDevice == 0 && inputDevice == 0) | if (outputDevice == 0 && inputDevice == 0) | ||||
| @@ -260494,7 +260523,7 @@ public: | |||||
| String error; | String error; | ||||
| double sampleRate; | double sampleRate; | ||||
| int bufferSize; | |||||
| int bufferSize, outputLatency, inputLatency; | |||||
| BigInteger currentInputChans, currentOutputChans; | BigInteger currentInputChans, currentOutputChans; | ||||
| Array <int> sampleRates; | Array <int> sampleRates; | ||||
| @@ -260567,30 +260596,14 @@ public: | |||||
| { | { | ||||
| } | } | ||||
| const StringArray getOutputChannelNames() | |||||
| { | |||||
| return internal.channelNamesOut; | |||||
| } | |||||
| const StringArray getOutputChannelNames() { return internal.channelNamesOut; } | |||||
| const StringArray getInputChannelNames() { return internal.channelNamesIn; } | |||||
| const StringArray getInputChannelNames() | |||||
| { | |||||
| return internal.channelNamesIn; | |||||
| } | |||||
| int getNumSampleRates() { return internal.sampleRates.size(); } | |||||
| double getSampleRate (int index) { return internal.sampleRates [index]; } | |||||
| int getNumSampleRates() | |||||
| { | |||||
| return internal.sampleRates.size(); | |||||
| } | |||||
| double getSampleRate (int index) | |||||
| { | |||||
| return internal.sampleRates [index]; | |||||
| } | |||||
| int getNumBufferSizesAvailable() | |||||
| { | |||||
| return 50; | |||||
| } | |||||
| int getDefaultBufferSize() { return 512; } | |||||
| int getNumBufferSizesAvailable() { return 50; } | |||||
| int getBufferSizeSamples (int index) | int getBufferSizeSamples (int index) | ||||
| { | { | ||||
| @@ -260604,11 +260617,6 @@ public: | |||||
| return n; | return n; | ||||
| } | } | ||||
| int getDefaultBufferSize() | |||||
| { | |||||
| return 512; | |||||
| } | |||||
| const String open (const BigInteger& inputChannels, | const String open (const BigInteger& inputChannels, | ||||
| const BigInteger& outputChannels, | const BigInteger& outputChannels, | ||||
| double sampleRate, | double sampleRate, | ||||
| @@ -260645,45 +260653,19 @@ public: | |||||
| isOpen_ = false; | isOpen_ = false; | ||||
| } | } | ||||
| bool isOpen() | |||||
| { | |||||
| return isOpen_; | |||||
| } | |||||
| int getCurrentBufferSizeSamples() | |||||
| { | |||||
| return internal.bufferSize; | |||||
| } | |||||
| double getCurrentSampleRate() | |||||
| { | |||||
| return internal.sampleRate; | |||||
| } | |||||
| int getCurrentBitDepth() | |||||
| { | |||||
| return internal.getBitDepth(); | |||||
| } | |||||
| const BigInteger getActiveOutputChannels() const | |||||
| { | |||||
| return internal.currentOutputChans; | |||||
| } | |||||
| bool isOpen() { return isOpen_; } | |||||
| bool isPlaying() { return isStarted && internal.error.isEmpty(); } | |||||
| const String getLastError() { return internal.error; } | |||||
| const BigInteger getActiveInputChannels() const | |||||
| { | |||||
| return internal.currentInputChans; | |||||
| } | |||||
| int getCurrentBufferSizeSamples() { return internal.bufferSize; } | |||||
| double getCurrentSampleRate() { return internal.sampleRate; } | |||||
| int getCurrentBitDepth() { return internal.getBitDepth(); } | |||||
| int getOutputLatencyInSamples() | |||||
| { | |||||
| return 0; | |||||
| } | |||||
| const BigInteger getActiveOutputChannels() const { return internal.currentOutputChans; } | |||||
| const BigInteger getActiveInputChannels() const { return internal.currentInputChans; } | |||||
| int getInputLatencyInSamples() | |||||
| { | |||||
| return 0; | |||||
| } | |||||
| int getOutputLatencyInSamples() { return internal.outputLatency; } | |||||
| int getInputLatencyInSamples() { return internal.inputLatency; } | |||||
| void start (AudioIODeviceCallback* callback) | void start (AudioIODeviceCallback* callback) | ||||
| { | { | ||||
| @@ -260708,16 +260690,6 @@ public: | |||||
| oldCallback->audioDeviceStopped(); | oldCallback->audioDeviceStopped(); | ||||
| } | } | ||||
| bool isPlaying() | |||||
| { | |||||
| return isStarted && internal.error.isEmpty(); | |||||
| } | |||||
| const String getLastError() | |||||
| { | |||||
| return internal.error; | |||||
| } | |||||
| String inputId, outputId; | String inputId, outputId; | ||||
| private: | private: | ||||
| @@ -260750,8 +260722,8 @@ public: | |||||
| outputNames.clear(); | outputNames.clear(); | ||||
| outputIds.clear(); | outputIds.clear(); | ||||
| snd_ctl_t* handle; | |||||
| snd_ctl_card_info_t* info; | |||||
| snd_ctl_t* handle = 0; | |||||
| snd_ctl_card_info_t* info = 0; | |||||
| snd_ctl_card_info_alloca (&info); | snd_ctl_card_info_alloca (&info); | ||||
| int cardNum = -1; | int cardNum = -1; | ||||
| @@ -64,7 +64,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
| #define JUCE_BUILDNUMBER 51 | |||||
| #define JUCE_BUILDNUMBER 52 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -15897,6 +15897,11 @@ public: | |||||
| */ | */ | ||||
| bool overwriteTargetFileWithTemporary() const; | bool overwriteTargetFileWithTemporary() const; | ||||
| /** Attempts to delete the temporary file, if it exists. | |||||
| @returns true if the file is successfully deleted (or if it didn't exist). | |||||
| */ | |||||
| bool deleteTemporaryFile() const; | |||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| private: | private: | ||||
| @@ -19140,6 +19145,10 @@ public: | |||||
| This is only needed in special circumstances for up-to-date modifier information | This is only needed in special circumstances for up-to-date modifier information | ||||
| at times when the app's event loop isn't running normally. | at times when the app's event loop isn't running normally. | ||||
| Another reason to avoid this method is that it's not stateless, and calling it may | |||||
| update the value returned by getCurrentModifiers(), which could cause subtle changes | |||||
| in the behaviour of some components. | |||||
| */ | */ | ||||
| static const ModifierKeys getCurrentModifiersRealtime() throw(); | static const ModifierKeys getCurrentModifiersRealtime() throw(); | ||||
| @@ -33,7 +33,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
| #define JUCE_BUILDNUMBER 51 | |||||
| #define JUCE_BUILDNUMBER 52 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -191,6 +191,10 @@ public: | |||||
| This is only needed in special circumstances for up-to-date modifier information | This is only needed in special circumstances for up-to-date modifier information | ||||
| at times when the app's event loop isn't running normally. | at times when the app's event loop isn't running normally. | ||||
| Another reason to avoid this method is that it's not stateless, and calling it may | |||||
| update the value returned by getCurrentModifiers(), which could cause subtle changes | |||||
| in the behaviour of some components. | |||||
| */ | */ | ||||
| static const ModifierKeys getCurrentModifiersRealtime() throw(); | static const ModifierKeys getCurrentModifiersRealtime() throw(); | ||||
| @@ -64,18 +64,18 @@ void TemporaryFile::createTempFile (const File& parentDirectory, String name, | |||||
| TemporaryFile::~TemporaryFile() | TemporaryFile::~TemporaryFile() | ||||
| { | { | ||||
| // Have a few attempts at deleting the file before giving up.. | |||||
| for (int i = 5; --i >= 0;) | |||||
| if (! deleteTemporaryFile()) | |||||
| { | { | ||||
| if (temporaryFile.deleteFile()) | |||||
| return; | |||||
| Thread::sleep (50); | |||||
| /* Failed to delete our temporary file! The most likely reason for this would be | |||||
| that you've not closed an output stream that was being used to write to file. | |||||
| If you find that something beyond your control is changing permissions on | |||||
| your temporary files and preventing them from being deleted, you may want to | |||||
| call TemporaryFile::deleteTemporaryFile() to detect those error cases and | |||||
| handle them appropriately. | |||||
| */ | |||||
| jassertfalse; | |||||
| } | } | ||||
| // Failed to delete our temporary file! Check that you've deleted all the | |||||
| // file output streams that were using it! | |||||
| jassertfalse; | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -106,5 +106,18 @@ bool TemporaryFile::overwriteTargetFileWithTemporary() const | |||||
| return false; | return false; | ||||
| } | } | ||||
| bool TemporaryFile::deleteTemporaryFile() const | |||||
| { | |||||
| // Have a few attempts at deleting the file before giving up.. | |||||
| for (int i = 5; --i >= 0;) | |||||
| { | |||||
| if (temporaryFile.deleteFile()) | |||||
| return true; | |||||
| Thread::sleep (50); | |||||
| } | |||||
| return false; | |||||
| } | |||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| @@ -143,6 +143,11 @@ public: | |||||
| */ | */ | ||||
| bool overwriteTargetFileWithTemporary() const; | bool overwriteTargetFileWithTemporary() const; | ||||
| /** Attempts to delete the temporary file, if it exists. | |||||
| @returns true if the file is successfully deleted (or if it didn't exist). | |||||
| */ | |||||
| bool deleteTemporaryFile() const; | |||||
| //============================================================================== | //============================================================================== | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| @@ -123,6 +123,7 @@ public: | |||||
| : handle (0), | : handle (0), | ||||
| bitDepth (16), | bitDepth (16), | ||||
| numChannelsRunning (0), | numChannelsRunning (0), | ||||
| latency (0), | |||||
| isInput (forInput), | isInput (forInput), | ||||
| sampleFormat (AudioDataConverters::int16LE) | sampleFormat (AudioDataConverters::int16LE) | ||||
| { | { | ||||
| @@ -198,6 +199,14 @@ public: | |||||
| return false; | return false; | ||||
| } | } | ||||
| snd_pcm_uframes_t frames = 0; | |||||
| if (failed (snd_pcm_hw_params_get_period_size (hwParams, &frames, &dir)) | |||||
| || failed (snd_pcm_hw_params_get_periods (hwParams, &periods, &dir))) | |||||
| latency = 0; | |||||
| else | |||||
| latency = frames * (periods - 1); // (this is the method JACK uses to guess the latency..) | |||||
| snd_pcm_sw_params_t* swParams; | snd_pcm_sw_params_t* swParams; | ||||
| snd_pcm_sw_params_alloca (&swParams); | snd_pcm_sw_params_alloca (&swParams); | ||||
| snd_pcm_uframes_t boundary; | snd_pcm_uframes_t boundary; | ||||
| @@ -316,7 +325,7 @@ public: | |||||
| snd_pcm_t* handle; | snd_pcm_t* handle; | ||||
| String error; | String error; | ||||
| int bitDepth, numChannelsRunning; | |||||
| int bitDepth, numChannelsRunning, latency; | |||||
| //============================================================================== | //============================================================================== | ||||
| private: | private: | ||||
| @@ -346,6 +355,8 @@ public: | |||||
| : Thread ("Juce ALSA"), | : Thread ("Juce ALSA"), | ||||
| sampleRate (0), | sampleRate (0), | ||||
| bufferSize (0), | bufferSize (0), | ||||
| outputLatency (0), | |||||
| inputLatency (0), | |||||
| callback (0), | callback (0), | ||||
| inputId (inputId_), | inputId (inputId_), | ||||
| outputId (outputId_), | outputId (outputId_), | ||||
| @@ -427,6 +438,8 @@ public: | |||||
| outputDevice = 0; | outputDevice = 0; | ||||
| return; | return; | ||||
| } | } | ||||
| outputLatency = outputDevice->latency; | |||||
| } | } | ||||
| if (inputChannelDataForCallback.size() > 0 && inputId.isNotEmpty()) | if (inputChannelDataForCallback.size() > 0 && inputId.isNotEmpty()) | ||||
| @@ -450,6 +463,8 @@ public: | |||||
| inputDevice = 0; | inputDevice = 0; | ||||
| return; | return; | ||||
| } | } | ||||
| inputLatency = inputDevice->latency; | |||||
| } | } | ||||
| if (outputDevice == 0 && inputDevice == 0) | if (outputDevice == 0 && inputDevice == 0) | ||||
| @@ -573,7 +588,7 @@ public: | |||||
| String error; | String error; | ||||
| double sampleRate; | double sampleRate; | ||||
| int bufferSize; | |||||
| int bufferSize, outputLatency, inputLatency; | |||||
| BigInteger currentInputChans, currentOutputChans; | BigInteger currentInputChans, currentOutputChans; | ||||
| Array <int> sampleRates; | Array <int> sampleRates; | ||||
| @@ -648,30 +663,14 @@ public: | |||||
| { | { | ||||
| } | } | ||||
| const StringArray getOutputChannelNames() | |||||
| { | |||||
| return internal.channelNamesOut; | |||||
| } | |||||
| const StringArray getOutputChannelNames() { return internal.channelNamesOut; } | |||||
| const StringArray getInputChannelNames() { return internal.channelNamesIn; } | |||||
| const StringArray getInputChannelNames() | |||||
| { | |||||
| return internal.channelNamesIn; | |||||
| } | |||||
| int getNumSampleRates() { return internal.sampleRates.size(); } | |||||
| double getSampleRate (int index) { return internal.sampleRates [index]; } | |||||
| int getNumSampleRates() | |||||
| { | |||||
| return internal.sampleRates.size(); | |||||
| } | |||||
| double getSampleRate (int index) | |||||
| { | |||||
| return internal.sampleRates [index]; | |||||
| } | |||||
| int getNumBufferSizesAvailable() | |||||
| { | |||||
| return 50; | |||||
| } | |||||
| int getDefaultBufferSize() { return 512; } | |||||
| int getNumBufferSizesAvailable() { return 50; } | |||||
| int getBufferSizeSamples (int index) | int getBufferSizeSamples (int index) | ||||
| { | { | ||||
| @@ -685,11 +684,6 @@ public: | |||||
| return n; | return n; | ||||
| } | } | ||||
| int getDefaultBufferSize() | |||||
| { | |||||
| return 512; | |||||
| } | |||||
| const String open (const BigInteger& inputChannels, | const String open (const BigInteger& inputChannels, | ||||
| const BigInteger& outputChannels, | const BigInteger& outputChannels, | ||||
| double sampleRate, | double sampleRate, | ||||
| @@ -726,45 +720,19 @@ public: | |||||
| isOpen_ = false; | isOpen_ = false; | ||||
| } | } | ||||
| bool isOpen() | |||||
| { | |||||
| return isOpen_; | |||||
| } | |||||
| bool isOpen() { return isOpen_; } | |||||
| bool isPlaying() { return isStarted && internal.error.isEmpty(); } | |||||
| const String getLastError() { return internal.error; } | |||||
| int getCurrentBufferSizeSamples() | |||||
| { | |||||
| return internal.bufferSize; | |||||
| } | |||||
| int getCurrentBufferSizeSamples() { return internal.bufferSize; } | |||||
| double getCurrentSampleRate() { return internal.sampleRate; } | |||||
| int getCurrentBitDepth() { return internal.getBitDepth(); } | |||||
| double getCurrentSampleRate() | |||||
| { | |||||
| return internal.sampleRate; | |||||
| } | |||||
| int getCurrentBitDepth() | |||||
| { | |||||
| return internal.getBitDepth(); | |||||
| } | |||||
| const BigInteger getActiveOutputChannels() const | |||||
| { | |||||
| return internal.currentOutputChans; | |||||
| } | |||||
| const BigInteger getActiveInputChannels() const | |||||
| { | |||||
| return internal.currentInputChans; | |||||
| } | |||||
| int getOutputLatencyInSamples() | |||||
| { | |||||
| return 0; | |||||
| } | |||||
| const BigInteger getActiveOutputChannels() const { return internal.currentOutputChans; } | |||||
| const BigInteger getActiveInputChannels() const { return internal.currentInputChans; } | |||||
| int getInputLatencyInSamples() | |||||
| { | |||||
| return 0; | |||||
| } | |||||
| int getOutputLatencyInSamples() { return internal.outputLatency; } | |||||
| int getInputLatencyInSamples() { return internal.inputLatency; } | |||||
| void start (AudioIODeviceCallback* callback) | void start (AudioIODeviceCallback* callback) | ||||
| { | { | ||||
| @@ -789,16 +757,6 @@ public: | |||||
| oldCallback->audioDeviceStopped(); | oldCallback->audioDeviceStopped(); | ||||
| } | } | ||||
| bool isPlaying() | |||||
| { | |||||
| return isStarted && internal.error.isEmpty(); | |||||
| } | |||||
| const String getLastError() | |||||
| { | |||||
| return internal.error; | |||||
| } | |||||
| String inputId, outputId; | String inputId, outputId; | ||||
| private: | private: | ||||
| @@ -834,8 +792,8 @@ public: | |||||
| outputNames.clear(); | outputNames.clear(); | ||||
| outputIds.clear(); | outputIds.clear(); | ||||
| snd_ctl_t* handle; | |||||
| snd_ctl_card_info_t* info; | |||||
| snd_ctl_t* handle = 0; | |||||
| snd_ctl_card_info_t* info = 0; | |||||
| snd_ctl_card_info_alloca (&info); | snd_ctl_card_info_alloca (&info); | ||||
| int cardNum = -1; | int cardNum = -1; | ||||