diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 28662be92b..61239dadcc 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -8282,18 +8282,18 @@ void TemporaryFile::createTempFile (const File& parentDirectory, String name, 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 @@ -8323,6 +8323,20 @@ bool TemporaryFile::overwriteTargetFileWithTemporary() const 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 of inlined file: juce_TemporaryFile.cpp ***/ @@ -260050,6 +260064,7 @@ public: : handle (0), bitDepth (16), numChannelsRunning (0), + latency (0), isInput (forInput), sampleFormat (AudioDataConverters::int16LE) { @@ -260125,6 +260140,14 @@ public: 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_alloca (&swParams); snd_pcm_uframes_t boundary; @@ -260241,7 +260264,7 @@ public: snd_pcm_t* handle; String error; - int bitDepth, numChannelsRunning; + int bitDepth, numChannelsRunning, latency; private: const bool isInput; @@ -260268,6 +260291,8 @@ public: : Thread ("Juce ALSA"), sampleRate (0), bufferSize (0), + outputLatency (0), + inputLatency (0), callback (0), inputId (inputId_), outputId (outputId_), @@ -260349,6 +260374,8 @@ public: outputDevice = 0; return; } + + outputLatency = outputDevice->latency; } if (inputChannelDataForCallback.size() > 0 && inputId.isNotEmpty()) @@ -260372,6 +260399,8 @@ public: inputDevice = 0; return; } + + inputLatency = inputDevice->latency; } if (outputDevice == 0 && inputDevice == 0) @@ -260494,7 +260523,7 @@ public: String error; double sampleRate; - int bufferSize; + int bufferSize, outputLatency, inputLatency; BigInteger currentInputChans, currentOutputChans; Array 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) { @@ -260604,11 +260617,6 @@ public: return n; } - int getDefaultBufferSize() - { - return 512; - } - const String open (const BigInteger& inputChannels, const BigInteger& outputChannels, double sampleRate, @@ -260645,45 +260653,19 @@ public: 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) { @@ -260708,16 +260690,6 @@ public: oldCallback->audioDeviceStopped(); } - bool isPlaying() - { - return isStarted && internal.error.isEmpty(); - } - - const String getLastError() - { - return internal.error; - } - String inputId, outputId; private: @@ -260750,8 +260722,8 @@ public: outputNames.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); int cardNum = -1; diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 38b834deab..b1e14199dc 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -64,7 +64,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 52 -#define JUCE_BUILDNUMBER 51 +#define JUCE_BUILDNUMBER 52 /** Current Juce version number. @@ -15897,6 +15897,11 @@ public: */ 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 private: @@ -19140,6 +19145,10 @@ public: 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. + + 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(); diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 35aa0019a6..793cea0fbf 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 52 -#define JUCE_BUILDNUMBER 51 +#define JUCE_BUILDNUMBER 52 /** Current Juce version number. diff --git a/src/gui/components/keyboard/juce_ModifierKeys.h b/src/gui/components/keyboard/juce_ModifierKeys.h index e8a023b2dc..34717b75b5 100644 --- a/src/gui/components/keyboard/juce_ModifierKeys.h +++ b/src/gui/components/keyboard/juce_ModifierKeys.h @@ -191,6 +191,10 @@ public: 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. + + 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(); diff --git a/src/io/files/juce_TemporaryFile.cpp b/src/io/files/juce_TemporaryFile.cpp index 1fabfe1069..c2d2b6d01b 100644 --- a/src/io/files/juce_TemporaryFile.cpp +++ b/src/io/files/juce_TemporaryFile.cpp @@ -64,18 +64,18 @@ void TemporaryFile::createTempFile (const File& parentDirectory, String name, 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; } +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 diff --git a/src/io/files/juce_TemporaryFile.h b/src/io/files/juce_TemporaryFile.h index 5c57e96ab5..407b9f4441 100644 --- a/src/io/files/juce_TemporaryFile.h +++ b/src/io/files/juce_TemporaryFile.h @@ -143,6 +143,11 @@ public: */ 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 diff --git a/src/native/linux/juce_linux_Audio.cpp b/src/native/linux/juce_linux_Audio.cpp index ac1adeeec6..84a9b659b1 100644 --- a/src/native/linux/juce_linux_Audio.cpp +++ b/src/native/linux/juce_linux_Audio.cpp @@ -123,6 +123,7 @@ public: : handle (0), bitDepth (16), numChannelsRunning (0), + latency (0), isInput (forInput), sampleFormat (AudioDataConverters::int16LE) { @@ -198,6 +199,14 @@ public: 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_alloca (&swParams); snd_pcm_uframes_t boundary; @@ -316,7 +325,7 @@ public: snd_pcm_t* handle; String error; - int bitDepth, numChannelsRunning; + int bitDepth, numChannelsRunning, latency; //============================================================================== private: @@ -346,6 +355,8 @@ public: : Thread ("Juce ALSA"), sampleRate (0), bufferSize (0), + outputLatency (0), + inputLatency (0), callback (0), inputId (inputId_), outputId (outputId_), @@ -427,6 +438,8 @@ public: outputDevice = 0; return; } + + outputLatency = outputDevice->latency; } if (inputChannelDataForCallback.size() > 0 && inputId.isNotEmpty()) @@ -450,6 +463,8 @@ public: inputDevice = 0; return; } + + inputLatency = inputDevice->latency; } if (outputDevice == 0 && inputDevice == 0) @@ -573,7 +588,7 @@ public: String error; double sampleRate; - int bufferSize; + int bufferSize, outputLatency, inputLatency; BigInteger currentInputChans, currentOutputChans; Array 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) { @@ -685,11 +684,6 @@ public: return n; } - int getDefaultBufferSize() - { - return 512; - } - const String open (const BigInteger& inputChannels, const BigInteger& outputChannels, double sampleRate, @@ -726,45 +720,19 @@ public: 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) { @@ -789,16 +757,6 @@ public: oldCallback->audioDeviceStopped(); } - bool isPlaying() - { - return isStarted && internal.error.isEmpty(); - } - - const String getLastError() - { - return internal.error; - } - String inputId, outputId; private: @@ -834,8 +792,8 @@ public: outputNames.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); int cardNum = -1;