From 6e5aa7a991b2f431aba4120a89ef815ed5213008 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Mon, 5 Jan 2015 13:35:46 +0000 Subject: [PATCH] - updated git-svn-id: http://moon:8086/svn/software/trunk/projects/mpsk_rx_gui@117 b431acfa-c32f-4a4a-93f1-934dc6c82436 --- JuceLibraryCode/AppConfig.h | 6 +- JuceLibraryCode/JuceHeader.h | 2 - .../effects/juce_IIRFilter.cpp | 6 +- .../juce_audio_basics/effects/juce_Reverb.h | 135 ++-- .../juce_audio_basics/juce_module_info | 2 +- .../sources/juce_ResamplingAudioSource.cpp | 7 +- .../synthesisers/juce_Synthesiser.cpp | 7 +- .../synthesisers/juce_Synthesiser.h | 18 +- .../juce_audio_devices/juce_module_info | 2 +- .../native/juce_linux_ALSA.cpp | 2 +- .../native/juce_linux_Midi.cpp | 15 +- .../native/juce_win32_DirectSound.cpp | 2 +- .../native/juce_win32_WASAPI.cpp | 2 +- .../juce_audio_formats/codecs/flac/all.h | 2 +- .../juce_audio_formats/codecs/flac/alloc.h | 4 +- .../juce_audio_formats/codecs/flac/assert.h | 2 +- .../juce_audio_formats/codecs/flac/callback.h | 2 +- .../juce_audio_formats/codecs/flac/compat.h | 35 +- .../juce_audio_formats/codecs/flac/endswap.h | 30 +- .../juce_audio_formats/codecs/flac/export.h | 6 +- .../juce_audio_formats/codecs/flac/format.h | 6 +- .../codecs/flac/libFLAC/bitmath.c | 5 +- .../codecs/flac/libFLAC/bitreader.c | 16 +- .../codecs/flac/libFLAC/bitwriter.c | 36 +- .../codecs/flac/libFLAC/cpu.c | 637 ++++++++++-------- .../codecs/flac/libFLAC/crc.c | 4 +- .../codecs/flac/libFLAC/fixed.c | 19 +- .../codecs/flac/libFLAC/float.c | 4 +- .../codecs/flac/libFLAC/format.c | 11 +- .../codecs/flac/libFLAC/include/private/all.h | 2 +- .../flac/libFLAC/include/private/bitmath.h | 81 ++- .../flac/libFLAC/include/private/bitreader.h | 13 +- .../flac/libFLAC/include/private/bitwriter.h | 2 +- .../codecs/flac/libFLAC/include/private/cpu.h | 52 +- .../codecs/flac/libFLAC/include/private/crc.h | 4 +- .../flac/libFLAC/include/private/fixed.h | 19 +- .../flac/libFLAC/include/private/float.h | 2 +- .../flac/libFLAC/include/private/format.h | 2 +- .../codecs/flac/libFLAC/include/private/lpc.h | 43 +- .../codecs/flac/libFLAC/include/private/md5.h | 8 +- .../flac/libFLAC/include/private/memory.h | 2 +- .../flac/libFLAC/include/private/metadata.h | 2 +- .../include/private/stream_encoder_framing.h | 2 +- .../flac/libFLAC/include/private/window.h | 4 +- .../flac/libFLAC/include/protected/all.h | 2 +- .../include/protected/stream_decoder.h | 3 +- .../include/protected/stream_encoder.h | 9 +- .../codecs/flac/libFLAC/lpc_flac.c | 30 +- .../codecs/flac/libFLAC/md5.c | 311 ++++++--- .../codecs/flac/libFLAC/memory.c | 29 +- .../codecs/flac/libFLAC/stream_decoder.c | 229 ++++--- .../codecs/flac/libFLAC/stream_encoder.c | 299 ++++++-- .../flac/libFLAC/stream_encoder_framing.c | 4 +- .../codecs/flac/libFLAC/window_flac.c | 81 ++- .../juce_audio_formats/codecs/flac/metadata.h | 4 +- .../juce_audio_formats/codecs/flac/ordinals.h | 2 +- .../codecs/flac/stream_decoder.h | 2 +- .../codecs/flac/stream_encoder.h | 69 +- .../codecs/juce_MP3AudioFormat.cpp | 18 +- .../juce_audio_formats/juce_module_info | 2 +- .../sampler/juce_Sampler.cpp | 2 +- .../format_types/juce_VST3PluginFormat.cpp | 150 +++-- .../format_types/juce_VSTPluginFormat.cpp | 31 +- .../juce_audio_processors/juce_module_info | 2 +- .../juce_GenericAudioProcessorEditor.cpp | 2 +- .../gui/juce_AudioThumbnail.cpp | 4 +- .../gui/juce_MidiKeyboardComponent.cpp | 15 +- .../juce_audio_utils/juce_audio_utils.cpp | 1 + .../juce_audio_utils/juce_audio_utils.h | 1 + .../modules/juce_audio_utils/juce_module_info | 2 +- .../modules/juce_core/containers/juce_Array.h | 6 +- .../files/juce_DirectoryIterator.cpp | 109 +-- .../modules/juce_core/files/juce_File.cpp | 5 + .../modules/juce_core/files/juce_File.h | 8 + .../modules/juce_core/juce_module_info | 2 +- .../juce_core/logging/juce_FileLogger.cpp | 12 +- .../juce_core/logging/juce_FileLogger.h | 8 +- .../juce_core/maths/juce_Expression.cpp | 6 +- .../juce_core/maths/juce_NormalisableRange.h | 4 +- .../native/juce_android_SystemStats.cpp | 2 +- .../juce_core/native/juce_mac_Strings.mm | 18 +- .../juce_core/native/juce_posix_SharedCode.h | 29 +- .../juce_core/native/juce_win32_Files.cpp | 6 + .../modules/juce_core/network/juce_Socket.cpp | 3 + .../modules/juce_core/network/juce_URL.cpp | 15 +- .../modules/juce_core/network/juce_URL.h | 6 + .../juce_core/system/juce_StandardHeader.h | 4 +- .../juce_core/system/juce_SystemStats.h | 37 +- .../modules/juce_core/xml/juce_XmlDocument.h | 4 +- .../juce_cryptography/juce_module_info | 2 +- .../juce_data_structures/juce_module_info | 2 +- .../values/juce_Value.cpp | 6 - .../juce_data_structures/values/juce_Value.h | 6 +- .../modules/juce_events/juce_events.h | 1 + .../modules/juce_events/juce_module_info | 2 +- .../native/juce_android_Messaging.cpp | 2 +- .../native/juce_linux_Messaging.cpp | 4 +- .../native/juce_mac_MessageManager.mm | 51 ++ .../native/juce_win32_HiddenMessageWindow.h | 1 - .../native/juce_win32_Messaging.cpp | 27 + .../modules/juce_events/timers/juce_Timer.cpp | 8 + .../modules/juce_events/timers/juce_Timer.h | 11 +- .../modules/juce_graphics/fonts/juce_Font.cpp | 2 +- .../geometry/juce_AffineTransform.cpp | 12 +- .../juce_graphics/geometry/juce_Path.cpp | 19 +- .../juce_graphics/geometry/juce_Path.h | 12 + .../juce_graphics/images/juce_ImageCache.cpp | 4 +- .../modules/juce_graphics/juce_module_info | 2 +- .../native/juce_freetype_Fonts.cpp | 2 +- .../juce_gui_basics/buttons/juce_TextButton.h | 2 +- .../components/juce_Component.cpp | 18 +- .../components/juce_ModalComponentManager.cpp | 2 +- .../components/juce_ModalComponentManager.h | 2 +- .../drawables/juce_DrawableImage.cpp | 1 + .../drawables/juce_SVGParser.cpp | 26 +- .../modules/juce_gui_basics/juce_module_info | 2 +- .../layout/juce_AnimatedPosition.h | 6 +- .../layout/juce_ComponentAnimator.cpp | 25 +- .../juce_gui_basics/layout/juce_Viewport.cpp | 30 + .../juce_gui_basics/layout/juce_Viewport.h | 3 + .../lookandfeel/juce_LookAndFeel_V2.cpp | 1 - .../mouse/juce_SelectedItemSet.h | 2 - .../native/juce_android_Windowing.cpp | 5 +- .../native/juce_mac_FileChooser.mm | 4 +- .../native/juce_mac_NSViewComponentPeer.mm | 16 +- .../native/juce_mac_Windowing.mm | 50 +- .../native/juce_win32_Windowing.cpp | 13 +- .../positioning/juce_RelativeRectangle.cpp | 2 +- .../positioning/juce_RelativeRectangle.h | 2 +- .../juce_gui_basics/widgets/juce_ComboBox.cpp | 75 ++- .../juce_gui_basics/widgets/juce_ComboBox.h | 4 + .../juce_gui_basics/widgets/juce_ListBox.cpp | 18 +- .../juce_gui_basics/widgets/juce_Slider.h | 15 +- .../windows/juce_ResizableWindow.cpp | 4 + .../windows/juce_TooltipWindow.cpp | 60 +- .../windows/juce_TooltipWindow.h | 7 +- .../windows/juce_TopLevelWindow.cpp | 2 +- .../modules/juce_gui_extra/juce_gui_extra.cpp | 2 + .../modules/juce_gui_extra/juce_gui_extra.h | 1 + .../modules/juce_gui_extra/juce_module_info | 2 +- .../misc/juce_WebBrowserComponent.h | 8 + .../juce_android_WebBrowserComponent.cpp | 4 + .../native/juce_linux_WebBrowserComponent.cpp | 4 + .../native/juce_mac_NSViewComponent.mm | 2 +- .../native/juce_mac_WebBrowserComponent.mm | 119 ++-- .../native/juce_win32_WebBrowserComponent.cpp | 38 +- .../modules/juce_opengl/juce_module_info | 4 +- .../modules/juce_opengl/juce_opengl.cpp | 1 + .../modules/juce_opengl/juce_opengl.h | 9 +- .../juce_opengl/native/juce_OpenGL_osx.h | 1 - .../juce_opengl/opengl/juce_OpenGLContext.cpp | 11 +- .../opengl/juce_OpenGLGraphicsContext.cpp | 43 +- .../opengl/juce_OpenGLShaderProgram.cpp | 4 + .../juce_opengl/opengl/juce_OpenGLTexture.cpp | 19 +- .../modules/juce_video/juce_module_info | 2 +- .../native/juce_win32_DirectShowComponent.cpp | 4 +- 156 files changed, 2332 insertions(+), 1370 deletions(-) diff --git a/JuceLibraryCode/AppConfig.h b/JuceLibraryCode/AppConfig.h index 1782810..0504de2 100644 --- a/JuceLibraryCode/AppConfig.h +++ b/JuceLibraryCode/AppConfig.h @@ -49,15 +49,15 @@ #endif #ifndef JUCE_DIRECTSOUND - //#define JUCE_DIRECTSOUND + #define JUCE_DIRECTSOUND 1 #endif #ifndef JUCE_ALSA - #define JUCE_ALSA 0 + //#define JUCE_ALSA #endif #ifndef JUCE_JACK - #define JUCE_JACK 1 + //#define JUCE_JACK #endif #ifndef JUCE_USE_ANDROID_OPENSLES diff --git a/JuceLibraryCode/JuceHeader.h b/JuceLibraryCode/JuceHeader.h index 44915da..4e8fcc9 100644 --- a/JuceLibraryCode/JuceHeader.h +++ b/JuceLibraryCode/JuceHeader.h @@ -35,13 +35,11 @@ using namespace juce; #endif -#if ! JUCE_DONT_DECLARE_PROJECTINFO namespace ProjectInfo { const char* const projectName = "M-QAM Transceiver"; const char* const versionString = "1.0.0"; const int versionNumber = 0x10000; } -#endif #endif // __APPHEADERFILE_GMZMR9__ diff --git a/JuceLibraryCode/modules/juce_audio_basics/effects/juce_IIRFilter.cpp b/JuceLibraryCode/modules/juce_audio_basics/effects/juce_IIRFilter.cpp index 908a69e..b961a6a 100644 --- a/JuceLibraryCode/modules/juce_audio_basics/effects/juce_IIRFilter.cpp +++ b/JuceLibraryCode/modules/juce_audio_basics/effects/juce_IIRFilter.cpp @@ -23,7 +23,7 @@ */ #if JUCE_INTEL - #define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8 || n > 1.0e-8)) n = 0; + #define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8f || n > 1.0e-8f)) n = 0; #else #define JUCE_SNAP_TO_ZERO(n) #endif @@ -64,7 +64,7 @@ IIRCoefficients IIRCoefficients::makeLowPass (const double sampleRate, { jassert (sampleRate > 0); - const double n = 1.0 / tan (double_Pi * frequency / sampleRate); + const double n = 1.0 / std::tan (double_Pi * frequency / sampleRate); const double nSquared = n * n; const double c1 = 1.0 / (1.0 + std::sqrt (2.0) * n + nSquared); @@ -79,7 +79,7 @@ IIRCoefficients IIRCoefficients::makeLowPass (const double sampleRate, IIRCoefficients IIRCoefficients::makeHighPass (const double sampleRate, const double frequency) noexcept { - const double n = tan (double_Pi * frequency / sampleRate); + const double n = std::tan (double_Pi * frequency / sampleRate); const double nSquared = n * n; const double c1 = 1.0 / (1.0 + std::sqrt (2.0) * n + nSquared); diff --git a/JuceLibraryCode/modules/juce_audio_basics/effects/juce_Reverb.h b/JuceLibraryCode/modules/juce_audio_basics/effects/juce_Reverb.h index 53457a6..c0b7596 100644 --- a/JuceLibraryCode/modules/juce_audio_basics/effects/juce_Reverb.h +++ b/JuceLibraryCode/modules/juce_audio_basics/effects/juce_Reverb.h @@ -82,12 +82,13 @@ public: const float dryScaleFactor = 2.0f; const float wet = newParams.wetLevel * wetScaleFactor; - wet1 = wet * (newParams.width * 0.5f + 0.5f); - wet2 = wet * (1.0f - newParams.width) * 0.5f; - dry = newParams.dryLevel * dryScaleFactor; + dryGain.setValue (newParams.dryLevel * dryScaleFactor); + wetGain1.setValue (0.5f * wet * (1.0f + newParams.width)); + wetGain2.setValue (0.5f * wet * (1.0f - newParams.width)); + gain = isFrozen (newParams.freezeMode) ? 0.0f : 0.015f; parameters = newParams; - shouldUpdateDamping = true; + updateDamping(); } //============================================================================== @@ -115,7 +116,12 @@ public: allPass[1][i].setSize ((intSampleRate * (allPassTunings[i] + stereoSpread)) / 44100); } - shouldUpdateDamping = true; + const double smoothTime = 0.01; + damping .reset (sampleRate, smoothTime); + feedback.reset (sampleRate, smoothTime); + dryGain .reset (sampleRate, smoothTime); + wetGain1.reset (sampleRate, smoothTime); + wetGain2.reset (sampleRate, smoothTime); } /** Clears the reverb's buffers. */ @@ -137,18 +143,18 @@ public: { jassert (left != nullptr && right != nullptr); - if (shouldUpdateDamping) - updateDamping(); - for (int i = 0; i < numSamples; ++i) { const float input = (left[i] + right[i]) * gain; float outL = 0, outR = 0; + const float damp = damping.getNextValue(); + const float feedbck = feedback.getNextValue(); + for (int j = 0; j < numCombs; ++j) // accumulate the comb filters in parallel { - outL += comb[0][j].process (input); - outR += comb[1][j].process (input); + outL += comb[0][j].process (input, damp, feedbck); + outR += comb[1][j].process (input, damp, feedbck); } for (int j = 0; j < numAllPasses; ++j) // run the allpass filters in series @@ -157,6 +163,10 @@ public: outR = allPass[1][j].process (outR); } + const float dry = dryGain.getNextValue(); + const float wet1 = wetGain1.getNextValue(); + const float wet2 = wetGain2.getNextValue(); + left[i] = outL * wet1 + outR * wet2 + left[i] * dry; right[i] = outR * wet1 + outL * wet2 + right[i] * dry; } @@ -167,32 +177,30 @@ public: { jassert (samples != nullptr); - if (shouldUpdateDamping) - updateDamping(); - for (int i = 0; i < numSamples; ++i) { const float input = samples[i] * gain; float output = 0; + const float damp = damping.getNextValue(); + const float feedbck = feedback.getNextValue(); + for (int j = 0; j < numCombs; ++j) // accumulate the comb filters in parallel - output += comb[0][j].process (input); + output += comb[0][j].process (input, damp, feedbck); for (int j = 0; j < numAllPasses; ++j) // run the allpass filters in series output = allPass[0][j].process (output); + const float dry = dryGain.getNextValue(); + const float wet1 = wetGain1.getNextValue(); + samples[i] = output * wet1 + samples[i] * dry; } } private: //============================================================================== - Parameters parameters; - - volatile bool shouldUpdateDamping; - float gain, wet1, wet2, dry; - - inline static bool isFrozen (const float freezeMode) noexcept { return freezeMode >= 0.5f; } + static bool isFrozen (const float freezeMode) noexcept { return freezeMode >= 0.5f; } void updateDamping() noexcept { @@ -200,8 +208,6 @@ private: const float roomOffset = 0.7f; const float dampScaleFactor = 0.4f; - shouldUpdateDamping = false; - if (isFrozen (parameters.freezeMode)) setDamping (0.0f, 1.0f); else @@ -211,19 +217,15 @@ private: void setDamping (const float dampingToUse, const float roomSizeToUse) noexcept { - for (int j = 0; j < numChannels; ++j) - for (int i = numCombs; --i >= 0;) - comb[j][i].setFeedbackAndDamp (roomSizeToUse, dampingToUse); + damping.setValue (dampingToUse); + feedback.setValue (roomSizeToUse); } //============================================================================== class CombFilter { public: - CombFilter() noexcept - : bufferSize (0), bufferIndex (0), - feedback (0), last (0), damp1 (0), damp2 (0) - {} + CombFilter() noexcept : bufferSize (0), bufferIndex (0), last (0) {} void setSize (const int size) { @@ -243,22 +245,15 @@ private: buffer.clear ((size_t) bufferSize); } - void setFeedbackAndDamp (const float f, const float d) noexcept + float process (const float input, const float damp, const float feedbackLevel) noexcept { - damp1 = d; - damp2 = 1.0f - d; - feedback = f; - } - - inline float process (const float input) noexcept - { - const float output = buffer [bufferIndex]; - last = (output * damp2) + (last * damp1); + const float output = buffer[bufferIndex]; + last = (output * (1.0f - damp)) + (last * damp); JUCE_UNDENORMALISE (last); - float temp = input + (last * feedback); + float temp = input + (last * feedbackLevel); JUCE_UNDENORMALISE (temp); - buffer [bufferIndex] = temp; + buffer[bufferIndex] = temp; bufferIndex = (bufferIndex + 1) % bufferSize; return output; } @@ -266,7 +261,7 @@ private: private: HeapBlock buffer; int bufferSize, bufferIndex; - float feedback, last, damp1, damp2; + float last; JUCE_DECLARE_NON_COPYABLE (CombFilter) }; @@ -294,7 +289,7 @@ private: buffer.clear ((size_t) bufferSize); } - inline float process (const float input) noexcept + float process (const float input) noexcept { const float bufferedValue = buffer [bufferIndex]; float temp = input + (bufferedValue * 0.5f); @@ -311,11 +306,65 @@ private: JUCE_DECLARE_NON_COPYABLE (AllPassFilter) }; + //============================================================================== + class LinearSmoothedValue + { + public: + LinearSmoothedValue() noexcept + : currentValue (0), target (0), step (0), countdown (0), stepsToTarget (0) + { + } + + void reset (double sampleRate, double fadeLengthSeconds) noexcept + { + jassert (sampleRate > 0 && fadeLengthSeconds >= 0); + stepsToTarget = (int) std::floor (fadeLengthSeconds * sampleRate); + currentValue = target; + countdown = 0; + } + + void setValue (float newValue) noexcept + { + if (target != newValue) + { + target = newValue; + countdown = stepsToTarget; + + if (countdown <= 0) + currentValue = target; + else + step = (target - currentValue) / countdown; + } + } + + float getNextValue() noexcept + { + if (countdown <= 0) + return target; + + --countdown; + currentValue += step; + return currentValue; + } + + private: + float currentValue, target, step; + int countdown, stepsToTarget; + + JUCE_DECLARE_NON_COPYABLE (LinearSmoothedValue) + }; + + //============================================================================== enum { numCombs = 8, numAllPasses = 4, numChannels = 2 }; + Parameters parameters; + float gain; + CombFilter comb [numChannels][numCombs]; AllPassFilter allPass [numChannels][numAllPasses]; + LinearSmoothedValue damping, feedback, dryGain, wetGain1, wetGain2; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Reverb) }; diff --git a/JuceLibraryCode/modules/juce_audio_basics/juce_module_info b/JuceLibraryCode/modules/juce_audio_basics/juce_module_info index c9cdd3d..01874e6 100644 --- a/JuceLibraryCode/modules/juce_audio_basics/juce_module_info +++ b/JuceLibraryCode/modules/juce_audio_basics/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_basics", "name": "JUCE audio and midi data classes", - "version": "3.0.8", + "version": "3.1.1", "description": "Classes for audio buffer manipulation, midi message handling, synthesis, etc", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp b/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp index 6a0704e..419f008 100644 --- a/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp +++ b/JuceLibraryCode/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp @@ -93,7 +93,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf lastRatio = localRatio; } - const int sampsNeeded = roundToInt (info.numSamples * localRatio) + 2; + const int sampsNeeded = roundToInt (info.numSamples * localRatio) + 3; int bufferSize = buffer.getNumSamples(); @@ -138,8 +138,11 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf } int nextPos = (bufferPos + 1) % bufferSize; + for (int m = info.numSamples; --m >= 0;) { + jassert (sampsInBuffer > 0 && nextPos != endOfBufferPos); + const float alpha = (float) subSampleOffset; for (int channel = 0; channel < channelsToProcess; ++channel) @@ -148,8 +151,6 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf subSampleOffset += localRatio; - jassert (sampsInBuffer > 0); - while (subSampleOffset >= 1.0) { if (++bufferPos >= bufferSize) diff --git a/JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp b/JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp index 6a889b4..81110ed 100644 --- a/JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp +++ b/JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.cpp @@ -50,6 +50,11 @@ void SynthesiserVoice::setCurrentPlaybackSampleRate (const double newRate) currentSampleRate = newRate; } +bool SynthesiserVoice::isVoiceActive() const +{ + return getCurrentlyPlayingNote() >= 0; +} + void SynthesiserVoice::clearCurrentNote() { currentlyPlayingNote = -1; @@ -426,7 +431,7 @@ SynthesiserVoice* Synthesiser::findFreeVoice (SynthesiserSound* soundToPlay, { SynthesiserVoice* const voice = voices.getUnchecked (i); - if (voice->getCurrentlyPlayingNote() < 0 && voice->canPlaySound (soundToPlay)) + if ((! voice->isVoiceActive()) && voice->canPlaySound (soundToPlay)) return voice; } diff --git a/JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h b/JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h index 6a32ced..19bb7a4 100644 --- a/JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h +++ b/JuceLibraryCode/modules/juce_audio_basics/synthesisers/juce_Synthesiser.h @@ -140,6 +140,12 @@ public: */ virtual void stopNote (float velocity, bool allowTailOff) = 0; + /** Returns true if this voice is currently busy playing a sound. + By default this just checks the getCurrentlyPlayingNote() value, but can + be overridden for more advanced checking. + */ + virtual bool isVoiceActive() const; + /** Called to let the voice know that the pitch wheel has been moved. This will be called during the rendering callback, so must be fast and thread-safe. */ @@ -185,17 +191,17 @@ public: */ virtual void setCurrentPlaybackSampleRate (double newRate); - /** Returns the current target sample rate at which rendering is being done. - Subclasses may need to know this so that they can pitch things correctly. - */ - double getSampleRate() const noexcept { return currentSampleRate; } - /** Returns true if the voice is currently playing a sound which is mapped to the given midi channel. If it's not currently playing, this will return false. */ - bool isPlayingChannel (int midiChannel) const; + virtual bool isPlayingChannel (int midiChannel) const; + + /** Returns the current target sample rate at which rendering is being done. + Subclasses may need to know this so that they can pitch things correctly. + */ + double getSampleRate() const noexcept { return currentSampleRate; } /** Returns true if the key that triggered this voice is still held down. Note that the voice may still be playing after the key was released (e.g because the diff --git a/JuceLibraryCode/modules/juce_audio_devices/juce_module_info b/JuceLibraryCode/modules/juce_audio_devices/juce_module_info index 6ef2131..6712c58 100644 --- a/JuceLibraryCode/modules/juce_audio_devices/juce_module_info +++ b/JuceLibraryCode/modules/juce_audio_devices/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_devices", "name": "JUCE audio and midi I/O device classes", - "version": "3.0.8", + "version": "3.1.1", "description": "Classes to play and record from audio and midi i/o devices.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_ALSA.cpp b/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_ALSA.cpp index 091ffba..fbb4010 100644 --- a/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_ALSA.cpp +++ b/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_ALSA.cpp @@ -30,7 +30,7 @@ namespace #endif #if JUCE_ALSA_LOGGING - #define JUCE_ALSA_LOG(dbgtext) { juce::String tempDbgBuf ("ALSA: "); tempDbgBuf << dbgtext; Logger::writeToLog (tempDbgBuf); DBG (tempDbgBuf) } + #define JUCE_ALSA_LOG(dbgtext) { juce::String tempDbgBuf ("ALSA: "); tempDbgBuf << dbgtext; Logger::writeToLog (tempDbgBuf); DBG (tempDbgBuf); } #define JUCE_CHECKED_RESULT(x) (logErrorMessage (x, __LINE__)) static int logErrorMessage (int err, int lineNum) diff --git a/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_Midi.cpp b/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_Midi.cpp index a6799f3..43cb43d 100644 --- a/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_Midi.cpp +++ b/JuceLibraryCode/modules/juce_audio_devices/native/juce_linux_Midi.cpp @@ -419,7 +419,7 @@ public: port.deletePort(); } - void sendMessageNow (const MidiMessage& message) + bool sendMessageNow (const MidiMessage& message) { if (message.getRawDataSize() > maxEventSize) { @@ -435,12 +435,17 @@ public: const uint8* data = message.getRawData(); snd_seq_t* seqHandle = port.client->get(); + bool success = true; while (numBytes > 0) { const long numSent = snd_midi_event_encode (midiParser, data, numBytes, &event); + if (numSent <= 0) + { + success = numSent == 0; break; + } numBytes -= numSent; data += numSent; @@ -449,11 +454,15 @@ public: snd_seq_ev_set_subs (&event); snd_seq_ev_set_direct (&event); - snd_seq_event_output (seqHandle, &event); + if (snd_seq_event_output_direct (seqHandle, &event) < 0) + { + success = false; + break; + } } - snd_seq_drain_output (seqHandle); snd_midi_event_reset_encode (midiParser); + return success; } private: diff --git a/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp b/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp index 9c43a1d..88a5960 100644 --- a/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp +++ b/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_DirectSound.cpp @@ -1255,7 +1255,7 @@ private: DSoundDeviceList deviceList; bool hasScanned; - void systemDeviceChanged() + void systemDeviceChanged() override { DSoundDeviceList newList; newList.scan(); diff --git a/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp b/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp index 320eca1..0ef7811 100644 --- a/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp +++ b/JuceLibraryCode/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp @@ -1418,7 +1418,7 @@ private: } //============================================================================== - void systemDeviceChanged() + void systemDeviceChanged() override { StringArray newOutNames, newInNames, newOutIds, newInIds; scan (newOutNames, newInNames, newOutIds, newInIds); diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/all.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/all.h index cc01e05..c7f3032 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/all.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/all.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/alloc.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/alloc.h index 83595ac..3aab81c 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/alloc.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/alloc.h @@ -1,6 +1,6 @@ /* alloc - Convenience routines for safely allocating memory * Copyright (C) 2007-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,7 +33,7 @@ #ifndef FLAC__SHARE__ALLOC_H #define FLAC__SHARE__ALLOC_H -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/assert.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/assert.h index fab30f7..f02aeac 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/assert.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/assert.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/callback.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/callback.h index 5f58552..9928843 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/callback.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/callback.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2004-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/compat.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/compat.h index 6c436cc..a3dc7c7 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/compat.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/compat.h @@ -1,5 +1,5 @@ /* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2012 Xiph.org Foundation + * Copyright (C) 2012-2014 Xiph.org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -73,23 +73,25 @@ #endif #if defined(_MSC_VER) -#if _MSC_VER < 1500 -/* Visual Studio 2008 has restrict. */ -#define restrict __restrict -#endif #define inline __inline #endif -/* adjust for compilers that can't understand using LLU suffix for uint64_t literals */ -#ifdef _MSC_VER -#define FLAC__U64L(x) x +#if defined __INTEL_COMPILER || (defined _MSC_VER && defined _WIN64) +/* MSVS generates VERY slow 32-bit code with __restrict */ +#define flac_restrict __restrict +#elif defined __GNUC__ +#define flac_restrict __restrict__ #else -#define FLAC__U64L(x) x##LLU +#define flac_restrict #endif +#define FLAC__U64L(x) x##ULL + #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ +#define FLAC__STRCASECMP stricmp #define FLAC__STRNCASECMP strnicmp #else +#define FLAC__STRCASECMP strcasecmp #define FLAC__STRNCASECMP strncasecmp #endif @@ -139,6 +141,7 @@ #ifdef _WIN32 /* All char* strings are in UTF-8 format. Added to support Unicode files on Windows */ +#include "win_utf8_io.h" #define flac_printf printf_utf8 #define flac_fprintf fprintf_utf8 @@ -160,12 +163,7 @@ #define flac_utime utime #define flac_unlink unlink #define flac_rename rename - -#ifdef _WIN32 -#define flac_stat _stat64 -#else #define flac_stat stat -#endif #endif @@ -177,8 +175,14 @@ #define flac_fstat fstat #endif +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 +#endif +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif -/* FLAC needs to compile and work correctly on systems with a norrmal ISO C99 +/* FLAC needs to compile and work correctly on systems with a normal ISO C99 * snprintf as well as Microsoft Visual Studio which has an non-standards * conformant snprint_s function. * @@ -188,6 +192,7 @@ extern "C" { #endif int flac_snprintf(char *str, size_t size, const char *fmt, ...); +int flac_vsnprintf(char *str, size_t size, const char *fmt, va_list va); #ifdef __cplusplus }; #endif diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/endswap.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/endswap.h index 2e09404..b2a7e85 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/endswap.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/endswap.h @@ -1,5 +1,5 @@ /* libFLAC - Free Lossless Audio Codec library - * Copyright (C) 2012 Xiph.org Foundation + * Copyright (C) 2012-2014 Xiph.org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,20 +33,46 @@ #if HAVE_BSWAP32 /* GCC and Clang */ +/* GCC prior to 4.8 didn't provide bswap16 on x86_64 */ +#if ! HAVE_BSWAP16 +static inline unsigned short __builtin_bswap16(unsigned short a) +{ + return (a<<8)|(a>>8); +} +#endif + +#define ENDSWAP_16(x) (__builtin_bswap16 (x)) #define ENDSWAP_32(x) (__builtin_bswap32 (x)) #elif defined _MSC_VER /* Windows. Apparently in . */ +#define ENDSWAP_16(x) (_byteswap_ushort (x)) #define ENDSWAP_32(x) (_byteswap_ulong (x)) #elif defined HAVE_BYTESWAP_H /* Linux */ #include +#define ENDSWAP_16(x) (bswap_16 (x)) #define ENDSWAP_32(x) (bswap_32 (x)) #else -#define ENDSWAP_32(x) ((((x) >> 24) & 0xFF) + (((x) >> 8) & 0xFF00) + (((x) & 0xFF00) << 8) + (((x) & 0xFF) << 24)) +#define ENDSWAP_16(x) ((((x) >> 8) & 0xFF) | (((x) & 0xFF) << 8)) +#define ENDSWAP_32(x) ((((x) >> 24) & 0xFF) | (((x) >> 8) & 0xFF00) | (((x) & 0xFF00) << 8) | (((x) & 0xFF) << 24)) + +#endif + + +/* Host to little-endian byte swapping. */ +#if CPU_IS_BIG_ENDIAN + +#define H2LE_16(x) ENDSWAP_16 (x) +#define H2LE_32(x) ENDSWAP_32 (x) + +#else + +#define H2LE_16(x) (x) +#define H2LE_32(x) (x) #endif diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/export.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/export.h index d7ca735..30f018b 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/export.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/export.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -61,9 +61,9 @@ #elif defined(_MSC_VER) #ifdef FLAC_API_EXPORTS -#define FLAC_API _declspec(dllexport) +#define FLAC_API __declspec(dllexport) #else -#define FLAC_API _declspec(dllimport) +#define FLAC_API __declspec(dllimport) #endif #elif defined(FLAC__USE_VISIBILITY_ATTR) diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/format.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/format.h index ecebe80..a151b67 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/format.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/format.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -509,9 +509,11 @@ typedef enum { FLAC__METADATA_TYPE_PICTURE = 6, /**< PICTURE block */ - FLAC__METADATA_TYPE_UNDEFINED = 7 + FLAC__METADATA_TYPE_UNDEFINED = 7, /**< marker to denote beginning of undefined type range; this number will increase as new metadata types are added */ + FLAC__MAX_METADATA_TYPE = FLAC__MAX_METADATA_TYPE_CODE, + /**< No type will ever be greater than this. There is not enough room in the protocol block. */ } FLAC__MetadataType; /** Maps a FLAC__MetadataType to a C string. diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c index 3ea040e..e011f84 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/bitmath.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,12 +30,11 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif #include "include/private/bitmath.h" -#include "../assert.h" /* An example of what FLAC__bitmath_silog2() computes: * diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c index 3fc7e1d..a4632e3 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/bitreader.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif @@ -73,7 +73,6 @@ */ static const unsigned FLAC__BITREADER_DEFAULT_CAPACITY = 65536u / FLAC__BITS_PER_WORD; /* in words */ -/* WATCHOUT: assembly routines rely on the order in which these fields are declared */ struct FLAC__BitReader { /* any partially-consumed word at the head will stay right-justified as bits are consumed from the left */ /* any incomplete word at the tail will be left-justified, and bytes from the read callback are added on the right */ @@ -87,7 +86,6 @@ struct FLAC__BitReader { unsigned crc16_align; /* the number of bits in the current consumed word that should not be CRC'd */ FLAC__BitReaderReadCallback read_callback; void *client_data; - FLAC__CPUInfo cpu_info; }; static inline void crc16_update_word_(FLAC__BitReader *br, uint32_t word) @@ -119,8 +117,7 @@ static inline void crc16_update_word_(FLAC__BitReader *br, uint32_t word) br->crc16_align = 0; } -/* would be static except it needs to be called by asm routines */ -FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br) +static FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br) { unsigned start, end; size_t bytes; @@ -231,7 +228,7 @@ void FLAC__bitreader_delete(FLAC__BitReader *br) * ***********************************************************************/ -FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__CPUInfo cpu, FLAC__BitReaderReadCallback rcb, void *cd) +FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd) { FLAC__ASSERT(0 != br); @@ -243,7 +240,6 @@ FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__CPUInfo cpu, FLAC__Bi return false; br->read_callback = rcb; br->client_data = cd; - br->cpu_info = cpu; return true; } @@ -1048,9 +1044,9 @@ FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *v return true; } -/* These functions a declared inline in this file but are also callable as +/* These functions are declared inline in this file but are also callable as * externs from elsewhere. - * According to the C99 sepc, section 6.7.4, simply providing a function + * According to the C99 spec, section 6.7.4, simply providing a function * prototype in a header file without 'inline' and making the function inline * in this file should be sufficient. * Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c index 9ac9ee5..565fbcd 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/bitwriter.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif @@ -47,8 +47,7 @@ /* WATCHOUT: if you change this you must also change the following #defines down to SWAP_BE_WORD_TO_HOST below to match */ /* WATCHOUT: there are a few places where the code will not work unless uint32_t is >= 32 bits wide */ #define FLAC__BYTES_PER_WORD 4 -#undef FLAC__BITS_PER_WORD -#define FLAC__BITS_PER_WORD 32 +#define FLAC__BITS_PER_WORD (8 * FLAC__BYTES_PER_WORD) #define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff) /* SWAP_BE_WORD_TO_HOST swaps bytes in a uint32_t (which is always big-endian) if necessary to match host byte order */ #if WORDS_BIGENDIAN @@ -524,28 +523,6 @@ FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FL msbits = uval >> parameter; -#if 0 /* OPT: can remove this special case if it doesn't make up for the extra compare (doesn't make a statistically significant difference with msvc or gcc/x86) */ - if(bw->bits && bw->bits + msbits + lsbits <= FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current uint32_t */ - /* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free uint32_t to work in */ - bw->bits = bw->bits + msbits + lsbits; - uval |= mask1; /* set stop bit */ - uval &= mask2; /* mask off unused top bits */ - /* NOT: bw->accum <<= msbits + lsbits because msbits+lsbits could be 32, then the shift would be a NOP */ - bw->accum <<= msbits; - bw->accum <<= lsbits; - bw->accum |= uval; - if(bw->bits == FLAC__BITS_PER_WORD) { - bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); - bw->bits = 0; - /* burying the capacity check down here means we have to grow the buffer a little if there are more vals to do */ - if(bw->capacity <= bw->words && nvals > 1 && !bitwriter_grow_(bw, 1)) { - FLAC__ASSERT(bw->capacity == bw->words); - return false; - } - } - } - else { -#elif 1 /*@@@@@@ OPT: try this version with MSVC6 to see if better, not much difference for gcc-4 */ if(bw->bits && bw->bits + msbits + lsbits < FLAC__BITS_PER_WORD) { /* i.e. if the whole thing fits in the current uint32_t */ /* ^^^ if bw->bits is 0 then we may have filled the buffer and have no free uint32_t to work in */ bw->bits = bw->bits + msbits + lsbits; @@ -555,7 +532,6 @@ FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FL bw->accum |= uval; } else { -#endif /* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+msbits+lsbits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */ /* OPT: pessimism may cause flurry of false calls to grow_ which eat up all savings before it */ if(bw->capacity <= bw->words + bw->bits + msbits + 1/*lsbits always fit in 1 uint32_t*/ && !bitwriter_grow_(bw, msbits+lsbits)) @@ -610,9 +586,7 @@ break1: bw->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum); bw->accum = uval; } -#if 1 } -#endif vals++; nvals--; } @@ -853,9 +827,9 @@ FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw) return true; } -/* These functions a declared inline in this file but are also callable as +/* These functions are declared inline in this file but are also callable as * externs from elsewhere. - * According to the C99 sepc, section 6.7.4, simply providing a function + * According to the C99 spec, section 6.7.4, simply providing a function * prototype in a header file without 'inline' and making the function inline * in this file should be sufficient. * Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/cpu.c b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/cpu.c index e352c95..46db9e3 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/cpu.c +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/cpu.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,47 +30,47 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif #include "include/private/cpu.h" -#include -#include + +#if 0 + #include + #include + #include +#endif #if defined FLAC__CPU_IA32 # include -#elif defined FLAC__CPU_PPC -# if !defined FLAC__NO_ASM -# if defined FLAC__SYS_DARWIN -# include -# include -# include -# include -# include -# ifndef CPU_SUBTYPE_POWERPC_970 -# define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100) -# endif -# else /* FLAC__SYS_DARWIN */ -# include -# include - -static sigjmp_buf jmpbuf; -static volatile sig_atomic_t canjump = 0; - -static void sigill_handler (int sig) +static void disable_sse(FLAC__CPUInfo *info) { - if (!canjump) { - signal (sig, SIG_DFL); - raise (sig); - } - canjump = 0; - siglongjmp (jmpbuf, 1); + info->ia32.sse = false; + info->ia32.sse2 = false; + info->ia32.sse3 = false; + info->ia32.ssse3 = false; + info->ia32.sse41 = false; + info->ia32.sse42 = false; } -# endif /* FLAC__SYS_DARWIN */ -# endif /* FLAC__NO_ASM */ -#endif /* FLAC__CPU_PPC */ + +static void disable_avx(FLAC__CPUInfo *info) +{ + info->ia32.avx = false; + info->ia32.avx2 = false; + info->ia32.fma = false; +} + +#elif defined FLAC__CPU_X86_64 + +static void disable_avx(FLAC__CPUInfo *info) +{ + info->x86.avx = false; + info->x86.avx2 = false; + info->x86.fma = false; +} +#endif #if defined (__NetBSD__) || defined(__OpenBSD__) #include @@ -87,25 +87,34 @@ static void sigill_handler (int sig) /* how to get sysctlbyname()? */ #endif +#ifdef FLAC__CPU_IA32 /* these are flags in EDX of CPUID AX=00000001 */ static const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV = 0x00008000; static const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000; static const unsigned FLAC__CPUINFO_IA32_CPUID_FXSR = 0x01000000; static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000; static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000; +#endif + /* these are flags in ECX of CPUID AX=00000001 */ static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE3 = 0x00000001; static const unsigned FLAC__CPUINFO_IA32_CPUID_SSSE3 = 0x00000200; -/* these are flags in EDX of CPUID AX=80000001 */ -static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW = 0x80000000; -static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW = 0x40000000; -static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX = 0x00400000; +static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE41 = 0x00080000; +static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE42 = 0x00100000; +#if defined FLAC__AVX_SUPPORTED +/* these are flags in ECX of CPUID AX=00000001 */ +static const unsigned FLAC__CPUINFO_IA32_CPUID_OSXSAVE = 0x08000000; +static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX = 0x10000000; +static const unsigned FLAC__CPUINFO_IA32_CPUID_FMA = 0x00001000; +/* these are flags in EBX of CPUID AX=00000007 */ +static const unsigned FLAC__CPUINFO_IA32_CPUID_AVX2 = 0x00000020; +#endif /* * Extra stuff needed for detection of OS support for SSE on IA-32 */ -#if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && defined FLAC__HAS_NASM && !defined FLAC__NO_SSE_OS && !defined FLAC__SSE_OS +#if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || defined FLAC__HAS_X86INTRIN) && !defined FLAC__NO_SSE_OS && !defined FLAC__SSE_OS # if defined(__linux__) /* * If the OS doesn't support SSE, we will get here with a SIGILL. We @@ -120,35 +129,14 @@ static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX = 0x00400000; * 6 bytes extra in case our estimate is wrong * 12 bytes puts us in the NOP "landing zone" */ -# undef USE_OBSOLETE_SIGCONTEXT_FLAVOR /* #define this to use the older signal handler method */ -# ifdef USE_OBSOLETE_SIGCONTEXT_FLAVOR - static void sigill_handler_sse_os(int signal, struct sigcontext sc) - { - (void)signal; - sc.eip += 3 + 3 + 6; - } -# else # include static void sigill_handler_sse_os(int signal, siginfo_t *si, void *uc) { (void)signal, (void)si; ((ucontext_t*)uc)->uc_mcontext.gregs[14/*REG_EIP*/] += 3 + 3 + 6; } -# endif # elif defined(_MSC_VER) # include -# define USE_TRY_CATCH_FLAVOR /* sigill_handler flavor resulted in several crash reports on win32 */ -# ifdef USE_TRY_CATCH_FLAVOR -# else - LONG CALLBACK sigill_handler_sse_os(EXCEPTION_POINTERS *ep) - { - if(ep->ExceptionRecord->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION) { - ep->ContextRecord->Eip += 3 + 3 + 6; - return EXCEPTION_CONTINUE_EXECUTION; - } - return EXCEPTION_CONTINUE_SEARCH; - } -# endif # endif #endif @@ -159,261 +147,344 @@ void FLAC__cpu_info(FLAC__CPUInfo *info) * IA32-specific */ #ifdef FLAC__CPU_IA32 + FLAC__bool ia32_fxsr = false; + FLAC__bool ia32_osxsave = false; + (void) ia32_fxsr; (void) ia32_osxsave; /* to avoid warnings about unused variables */ + memset(info, 0, sizeof(*info)); info->type = FLAC__CPUINFO_TYPE_IA32; -#if !defined FLAC__NO_ASM && defined FLAC__HAS_NASM +#if !defined FLAC__NO_ASM && (defined FLAC__HAS_NASM || defined FLAC__HAS_X86INTRIN) info->use_asm = true; /* we assume a minimum of 80386 with FLAC__CPU_IA32 */ - info->data.ia32.cpuid = FLAC__cpu_have_cpuid_asm_ia32()? true : false; - info->data.ia32.bswap = info->data.ia32.cpuid; /* CPUID => BSWAP since it came after */ - info->data.ia32.cmov = false; - info->data.ia32.mmx = false; - info->data.ia32.fxsr = false; - info->data.ia32.sse = false; - info->data.ia32.sse2 = false; - info->data.ia32.sse3 = false; - info->data.ia32.ssse3 = false; - info->data.ia32._3dnow = false; - info->data.ia32.ext3dnow = false; - info->data.ia32.extmmx = false; - if(info->data.ia32.cpuid) { - /* http://www.sandpile.org/ia32/cpuid.htm */ - FLAC__uint32 flags_edx, flags_ecx; - FLAC__cpu_info_asm_ia32(&flags_edx, &flags_ecx); - info->data.ia32.cmov = (flags_edx & FLAC__CPUINFO_IA32_CPUID_CMOV )? true : false; - info->data.ia32.mmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_MMX )? true : false; - info->data.ia32.fxsr = (flags_edx & FLAC__CPUINFO_IA32_CPUID_FXSR )? true : false; - info->data.ia32.sse = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE )? true : false; - info->data.ia32.sse2 = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE2 )? true : false; - info->data.ia32.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false; - info->data.ia32.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false; - -#ifdef FLAC__USE_3DNOW - flags_edx = FLAC__cpu_info_extended_amd_asm_ia32(); - info->data.ia32._3dnow = (flags_edx & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW )? true : false; - info->data.ia32.ext3dnow = (flags_edx & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW)? true : false; - info->data.ia32.extmmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX )? true : false; +#ifdef FLAC__HAS_X86INTRIN + if(!FLAC__cpu_have_cpuid_x86()) + return; #else - info->data.ia32._3dnow = info->data.ia32.ext3dnow = info->data.ia32.extmmx = false; + if(!FLAC__cpu_have_cpuid_asm_ia32()) + return; #endif + { + /* http://www.sandpile.org/x86/cpuid.htm */ +#ifdef FLAC__HAS_X86INTRIN + FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx; + FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); +#else + FLAC__uint32 flags_ecx, flags_edx; + FLAC__cpu_info_asm_ia32(&flags_edx, &flags_ecx); +#endif + info->ia32.cmov = (flags_edx & FLAC__CPUINFO_IA32_CPUID_CMOV )? true : false; + info->ia32.mmx = (flags_edx & FLAC__CPUINFO_IA32_CPUID_MMX )? true : false; + ia32_fxsr = (flags_edx & FLAC__CPUINFO_IA32_CPUID_FXSR )? true : false; + info->ia32.sse = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE )? true : false; + info->ia32.sse2 = (flags_edx & FLAC__CPUINFO_IA32_CPUID_SSE2 )? true : false; + info->ia32.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false; + info->ia32.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false; + info->ia32.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41)? true : false; + info->ia32.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42)? true : false; +#if defined FLAC__HAS_X86INTRIN && defined FLAC__AVX_SUPPORTED + ia32_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE)? true : false; + info->ia32.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX )? true : false; + info->ia32.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA )? true : false; + FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); + info->ia32.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 )? true : false; +#endif + } #ifdef DEBUG - fprintf(stderr, "CPU info (IA-32):\n"); - fprintf(stderr, " CPUID ...... %c\n", info->data.ia32.cpuid ? 'Y' : 'n'); - fprintf(stderr, " BSWAP ...... %c\n", info->data.ia32.bswap ? 'Y' : 'n'); - fprintf(stderr, " CMOV ....... %c\n", info->data.ia32.cmov ? 'Y' : 'n'); - fprintf(stderr, " MMX ........ %c\n", info->data.ia32.mmx ? 'Y' : 'n'); - fprintf(stderr, " FXSR ....... %c\n", info->data.ia32.fxsr ? 'Y' : 'n'); - fprintf(stderr, " SSE ........ %c\n", info->data.ia32.sse ? 'Y' : 'n'); - fprintf(stderr, " SSE2 ....... %c\n", info->data.ia32.sse2 ? 'Y' : 'n'); - fprintf(stderr, " SSE3 ....... %c\n", info->data.ia32.sse3 ? 'Y' : 'n'); - fprintf(stderr, " SSSE3 ...... %c\n", info->data.ia32.ssse3 ? 'Y' : 'n'); - fprintf(stderr, " 3DNow! ..... %c\n", info->data.ia32._3dnow ? 'Y' : 'n'); - fprintf(stderr, " 3DNow!-ext . %c\n", info->data.ia32.ext3dnow? 'Y' : 'n'); - fprintf(stderr, " 3DNow!-MMX . %c\n", info->data.ia32.extmmx ? 'Y' : 'n'); + fprintf(stderr, "CPU info (IA-32):\n"); + fprintf(stderr, " CMOV ....... %c\n", info->ia32.cmov ? 'Y' : 'n'); + fprintf(stderr, " MMX ........ %c\n", info->ia32.mmx ? 'Y' : 'n'); + fprintf(stderr, " SSE ........ %c\n", info->ia32.sse ? 'Y' : 'n'); + fprintf(stderr, " SSE2 ....... %c\n", info->ia32.sse2 ? 'Y' : 'n'); + fprintf(stderr, " SSE3 ....... %c\n", info->ia32.sse3 ? 'Y' : 'n'); + fprintf(stderr, " SSSE3 ...... %c\n", info->ia32.ssse3 ? 'Y' : 'n'); + fprintf(stderr, " SSE41 ...... %c\n", info->ia32.sse41 ? 'Y' : 'n'); + fprintf(stderr, " SSE42 ...... %c\n", info->ia32.sse42 ? 'Y' : 'n'); +# if defined FLAC__HAS_X86INTRIN && defined FLAC__AVX_SUPPORTED + fprintf(stderr, " AVX ........ %c\n", info->ia32.avx ? 'Y' : 'n'); + fprintf(stderr, " FMA ........ %c\n", info->ia32.fma ? 'Y' : 'n'); + fprintf(stderr, " AVX2 ....... %c\n", info->ia32.avx2 ? 'Y' : 'n'); +# endif #endif - /* - * now have to check for OS support of SSE/SSE2 - */ - if(info->data.ia32.fxsr || info->data.ia32.sse || info->data.ia32.sse2) { + /* + * now have to check for OS support of SSE instructions + */ + if(info->ia32.sse) { #if defined FLAC__NO_SSE_OS - /* assume user knows better than us; turn it off */ - info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; + /* assume user knows better than us; turn it off */ + disable_sse(info); #elif defined FLAC__SSE_OS - /* assume user knows better than us; leave as detected above */ + /* assume user knows better than us; leave as detected above */ #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__APPLE__) - int sse = 0; - size_t len; - /* at least one of these must work: */ - len = sizeof(sse); sse = sse || (sysctlbyname("hw.instruction_sse", &sse, &len, NULL, 0) == 0 && sse); - len = sizeof(sse); sse = sse || (sysctlbyname("hw.optional.sse" , &sse, &len, NULL, 0) == 0 && sse); /* __APPLE__ ? */ - if(!sse) - info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; + int sse = 0; + size_t len; + /* at least one of these must work: */ + len = sizeof(sse); sse = sse || (sysctlbyname("hw.instruction_sse", &sse, &len, NULL, 0) == 0 && sse); + len = sizeof(sse); sse = sse || (sysctlbyname("hw.optional.sse" , &sse, &len, NULL, 0) == 0 && sse); /* __APPLE__ ? */ + if(!sse) + disable_sse(info); #elif defined(__NetBSD__) || defined (__OpenBSD__) # if __NetBSD_Version__ >= 105250000 || (defined __OpenBSD__) - int val = 0, mib[2] = { CTL_MACHDEP, CPU_SSE }; - size_t len = sizeof(val); - if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) - info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; - else { /* double-check SSE2 */ - mib[1] = CPU_SSE2; - len = sizeof(val); - if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) - info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; + int val = 0, mib[2] = { CTL_MACHDEP, CPU_SSE }; + size_t len = sizeof(val); + if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) + disable_sse(info); + else { /* double-check SSE2 */ + mib[1] = CPU_SSE2; + len = sizeof(val); + if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) { + disable_sse(info); + info->ia32.sse = true; } + } # else - info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; + disable_sse(info); # endif #elif defined(__linux__) - int sse = 0; - struct sigaction sigill_save; -#ifdef USE_OBSOLETE_SIGCONTEXT_FLAVOR - if(0 == sigaction(SIGILL, NULL, &sigill_save) && signal(SIGILL, (void (*)(int))sigill_handler_sse_os) != SIG_ERR) -#else - struct sigaction sigill_sse; - sigill_sse.sa_sigaction = sigill_handler_sse_os; - __sigemptyset(&sigill_sse.sa_mask); - sigill_sse.sa_flags = SA_SIGINFO | SA_RESETHAND; /* SA_RESETHAND just in case our SIGILL return jump breaks, so we don't get stuck in a loop */ - if(0 == sigaction(SIGILL, &sigill_sse, &sigill_save)) -#endif - { - /* http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html */ - /* see sigill_handler_sse_os() for an explanation of the following: */ - asm volatile ( - "xorl %0,%0\n\t" /* for some reason, still need to do this to clear 'sse' var */ - "xorps %%xmm0,%%xmm0\n\t" /* will cause SIGILL if unsupported by OS */ - "incl %0\n\t" /* SIGILL handler will jump over this */ - /* landing zone */ - "nop\n\t" /* SIGILL jump lands here if "inc" is 9 bytes */ - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" /* SIGILL jump lands here if "inc" is 3 bytes (expected) */ - "nop\n\t" - "nop" /* SIGILL jump lands here if "inc" is 1 byte */ - : "=r"(sse) - : "r"(sse) - ); - - sigaction(SIGILL, &sigill_save, NULL); - } - - if(!sse) - info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; -#elif defined(_MSC_VER) -# ifdef USE_TRY_CATCH_FLAVOR - _try { - __asm { -# if _MSC_VER <= 1200 - /* VC6 assembler doesn't know SSE, have to emit bytecode instead */ - _emit 0x0F - _emit 0x57 - _emit 0xC0 -# else - xorps xmm0,xmm0 -# endif - } - } - _except(EXCEPTION_EXECUTE_HANDLER) { - if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION) - info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; - } -# else - int sse = 0; - LPTOP_LEVEL_EXCEPTION_FILTER save = SetUnhandledExceptionFilter(sigill_handler_sse_os); - /* see GCC version above for explanation */ - /* http://msdn2.microsoft.com/en-us/library/4ks26t93.aspx */ - /* http://www.codeproject.com/cpp/gccasm.asp */ - /* http://www.hick.org/~mmiller/msvc_inline_asm.html */ - __asm { -# if _MSC_VER <= 1200 - /* VC6 assembler doesn't know SSE, have to emit bytecode instead */ - _emit 0x0F - _emit 0x57 - _emit 0xC0 -# else - xorps xmm0,xmm0 -# endif - inc sse - nop - nop - nop - nop - nop - nop - nop - nop - nop - } - SetUnhandledExceptionFilter(save); - if(!sse) - info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; -# endif -#else - /* no way to test, disable to be safe */ - info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; -#endif -#ifdef DEBUG - fprintf(stderr, " SSE OS sup . %c\n", info->data.ia32.sse ? 'Y' : 'n'); -#endif - - } - } -#else - info->use_asm = false; -#endif - -/* - * PPC-specific - */ -#elif defined FLAC__CPU_PPC - info->type = FLAC__CPUINFO_TYPE_PPC; -# if !defined FLAC__NO_ASM - info->use_asm = true; -# ifdef FLAC__USE_ALTIVEC -# if defined FLAC__SYS_DARWIN - { - int val = 0, mib[2] = { CTL_HW, HW_VECTORUNIT }; - size_t len = sizeof(val); - info->data.ppc.altivec = !(sysctl(mib, 2, &val, &len, NULL, 0) || !val); - } - { - host_basic_info_data_t hostInfo; - mach_msg_type_number_t infoCount; - - infoCount = HOST_BASIC_INFO_COUNT; - host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount); - - info->data.ppc.ppc64 = (hostInfo.cpu_type == CPU_TYPE_POWERPC) && (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970); - } -# else /* FLAC__USE_ALTIVEC && !FLAC__SYS_DARWIN */ - { - /* no Darwin, do it the brute-force way */ - /* @@@@@@ this is not thread-safe; replace with SSE OS method above or remove */ - info->data.ppc.altivec = 0; - info->data.ppc.ppc64 = 0; - - signal (SIGILL, sigill_handler); - canjump = 0; - if (!sigsetjmp (jmpbuf, 1)) { - canjump = 1; - + int sse = 0; + struct sigaction sigill_save; + struct sigaction sigill_sse; + sigill_sse.sa_sigaction = sigill_handler_sse_os; + __sigemptyset(&sigill_sse.sa_mask); + sigill_sse.sa_flags = SA_SIGINFO | SA_RESETHAND; /* SA_RESETHAND just in case our SIGILL return jump breaks, so we don't get stuck in a loop */ + if(0 == sigaction(SIGILL, &sigill_sse, &sigill_save)) + { + /* http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html */ + /* see sigill_handler_sse_os() for an explanation of the following: */ asm volatile ( - "mtspr 256, %0\n\t" - "vand %%v0, %%v0, %%v0" - : - : "r" (-1) + "xorps %%xmm0,%%xmm0\n\t" /* will cause SIGILL if unsupported by OS */ + "incl %0\n\t" /* SIGILL handler will jump over this */ + /* landing zone */ + "nop\n\t" /* SIGILL jump lands here if "inc" is 9 bytes */ + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" /* SIGILL jump lands here if "inc" is 3 bytes (expected) */ + "nop\n\t" + "nop" /* SIGILL jump lands here if "inc" is 1 byte */ + : "=r"(sse) + : "0"(sse) ); - info->data.ppc.altivec = 1; + sigaction(SIGILL, &sigill_save, NULL); } - canjump = 0; - if (!sigsetjmp (jmpbuf, 1)) { - int x = 0; - canjump = 1; - /* PPC64 hardware implements the cntlzd instruction */ - asm volatile ("cntlzd %0, %1" : "=r" (x) : "r" (x) ); - - info->data.ppc.ppc64 = 1; + if(!sse) + disable_sse(info); +#elif defined(_MSC_VER) + __try { + __asm { + xorps xmm0,xmm0 + } } - signal (SIGILL, SIG_DFL); /*@@@@@@ should save and restore old signal */ + __except(EXCEPTION_EXECUTE_HANDLER) { + if (_exception_code() == STATUS_ILLEGAL_INSTRUCTION) + disable_sse(info); + } +#elif defined(__GNUC__) /* MinGW goes here */ + int sse = 0; + /* Based on the idea described in Agner Fog's manual "Optimizing subroutines in assembly language" */ + /* In theory, not guaranteed to detect lack of OS SSE support on some future Intel CPUs, but in practice works (see the aforementioned manual) */ + if (ia32_fxsr) { + struct { + FLAC__uint32 buff[128]; + } __attribute__((aligned(16))) fxsr; + FLAC__uint32 old_val, new_val; + + asm volatile ("fxsave %0" : "=m" (fxsr) : "m" (fxsr)); + old_val = fxsr.buff[50]; + fxsr.buff[50] ^= 0x0013c0de; /* change value in the buffer */ + asm volatile ("fxrstor %0" : "=m" (fxsr) : "m" (fxsr)); /* try to change SSE register */ + fxsr.buff[50] = old_val; /* restore old value in the buffer */ + asm volatile ("fxsave %0 " : "=m" (fxsr) : "m" (fxsr)); /* old value will be overwritten if SSE register was changed */ + new_val = fxsr.buff[50]; /* == old_val if FXRSTOR didn't change SSE register and (old_val ^ 0x0013c0de) otherwise */ + fxsr.buff[50] = old_val; /* again restore old value in the buffer */ + asm volatile ("fxrstor %0" : "=m" (fxsr) : "m" (fxsr)); /* restore old values of registers */ + + if ((old_val^new_val) == 0x0013c0de) + sse = 1; + } + if(!sse) + disable_sse(info); +#else + /* no way to test, disable to be safe */ + disable_sse(info); +#endif +#ifdef DEBUG + fprintf(stderr, " SSE OS sup . %c\n", info->ia32.sse ? 'Y' : 'n'); +#endif } -# endif -# else /* !FLAC__USE_ALTIVEC */ - info->data.ppc.altivec = 0; - info->data.ppc.ppc64 = 0; -# endif -# else + else /* info->ia32.sse == false */ + disable_sse(info); + + /* + * now have to check for OS support of AVX instructions + */ + if(info->ia32.avx && ia32_osxsave) { + FLAC__uint32 ecr = FLAC__cpu_xgetbv_x86(); + if ((ecr & 0x6) != 0x6) + disable_avx(info); +#ifdef DEBUG + fprintf(stderr, " AVX OS sup . %c\n", info->ia32.avx ? 'Y' : 'n'); +#endif + } + else /* no OS AVX support*/ + disable_avx(info); +#else info->use_asm = false; -# endif +#endif /* - * unknown CPI + * x86-64-specific + */ +#elif defined FLAC__CPU_X86_64 + FLAC__bool x86_osxsave = false; + (void) x86_osxsave; /* to avoid warnings about unused variables */ + memset(info, 0, sizeof(*info)); + info->type = FLAC__CPUINFO_TYPE_X86_64; +#if !defined FLAC__NO_ASM && defined FLAC__HAS_X86INTRIN + info->use_asm = true; + { + /* http://www.sandpile.org/x86/cpuid.htm */ + FLAC__uint32 flags_eax, flags_ebx, flags_ecx, flags_edx; + FLAC__cpu_info_x86(1, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); + info->x86.sse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE3 )? true : false; + info->x86.ssse3 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSSE3)? true : false; + info->x86.sse41 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE41)? true : false; + info->x86.sse42 = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_SSE42)? true : false; +#if defined FLAC__AVX_SUPPORTED + x86_osxsave = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_OSXSAVE)? true : false; + info->x86.avx = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_AVX )? true : false; + info->x86.fma = (flags_ecx & FLAC__CPUINFO_IA32_CPUID_FMA )? true : false; + FLAC__cpu_info_x86(7, &flags_eax, &flags_ebx, &flags_ecx, &flags_edx); + info->x86.avx2 = (flags_ebx & FLAC__CPUINFO_IA32_CPUID_AVX2 )? true : false; +#endif + } +#ifdef DEBUG + fprintf(stderr, "CPU info (x86-64):\n"); + fprintf(stderr, " SSE3 ....... %c\n", info->x86.sse3 ? 'Y' : 'n'); + fprintf(stderr, " SSSE3 ...... %c\n", info->x86.ssse3 ? 'Y' : 'n'); + fprintf(stderr, " SSE41 ...... %c\n", info->x86.sse41 ? 'Y' : 'n'); + fprintf(stderr, " SSE42 ...... %c\n", info->x86.sse42 ? 'Y' : 'n'); +# if defined FLAC__AVX_SUPPORTED + fprintf(stderr, " AVX ........ %c\n", info->x86.avx ? 'Y' : 'n'); + fprintf(stderr, " FMA ........ %c\n", info->x86.fma ? 'Y' : 'n'); + fprintf(stderr, " AVX2 ....... %c\n", info->x86.avx2 ? 'Y' : 'n'); +# endif +#endif + + /* + * now have to check for OS support of AVX instructions + */ + if(info->x86.avx && x86_osxsave) { + FLAC__uint32 ecr = FLAC__cpu_xgetbv_x86(); + if ((ecr & 0x6) != 0x6) + disable_avx(info); +#ifdef DEBUG + fprintf(stderr, " AVX OS sup . %c\n", info->x86.avx ? 'Y' : 'n'); +#endif + } + else /* no OS AVX support*/ + disable_avx(info); +#else + info->use_asm = false; +#endif + +/* + * unknown CPU */ #else info->type = FLAC__CPUINFO_TYPE_UNKNOWN; info->use_asm = false; #endif } + +#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN + +#if defined _MSC_VER +#include /* for __cpuid() and _xgetbv() */ +#elif defined __GNUC__ && defined HAVE_CPUID_H +#include /* for __get_cpuid() and __get_cpuid_max() */ +#endif + +FLAC__uint32 FLAC__cpu_have_cpuid_x86(void) +{ +#ifdef FLAC__CPU_X86_64 + return 1; +#else +# if defined _MSC_VER || defined __INTEL_COMPILER /* Do they support CPUs w/o CPUID support (or OSes that work on those CPUs)? */ + FLAC__uint32 flags1, flags2; + __asm { + pushfd + pushfd + pop eax + mov flags1, eax + xor eax, 0x200000 + push eax + popfd + pushfd + pop eax + mov flags2, eax + popfd + } + if (((flags1^flags2) & 0x200000) != 0) + return 1; + else + return 0; +# elif defined __GNUC__ && defined HAVE_CPUID_H + if (__get_cpuid_max(0, 0) != 0) + return 1; + else + return 0; +# else + return 0; +# endif +#endif +} + +void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx) +{ + (void) level; + +#if defined _MSC_VER || defined __INTEL_COMPILER + int cpuinfo[4]; + int ext = level & 0x80000000; + __cpuid(cpuinfo, ext); + if((unsigned)cpuinfo[0] < level) { + *eax = *ebx = *ecx = *edx = 0; + return; + } +#if defined FLAC__AVX_SUPPORTED + __cpuidex(cpuinfo, level, 0); /* for AVX2 detection */ +#else + __cpuid(cpuinfo, level); /* some old compilers don't support __cpuidex */ +#endif + *eax = cpuinfo[0]; *ebx = cpuinfo[1]; *ecx = cpuinfo[2]; *edx = cpuinfo[3]; +#elif defined __GNUC__ && defined HAVE_CPUID_H + FLAC__uint32 ext = level & 0x80000000; + __cpuid(ext, *eax, *ebx, *ecx, *edx); + if (*eax < level) { + *eax = *ebx = *ecx = *edx = 0; + return; + } + __cpuid_count(level, 0, *eax, *ebx, *ecx, *edx); +#else + *eax = *ebx = *ecx = *edx = 0; +#endif +} + +FLAC__uint32 FLAC__cpu_xgetbv_x86(void) +{ +#if (defined _MSC_VER || defined __INTEL_COMPILER) && defined FLAC__AVX_SUPPORTED + return (FLAC__uint32)_xgetbv(0); +#elif defined __GNUC__ + FLAC__uint32 lo, hi; + asm volatile (".byte 0x0f, 0x01, 0xd0" : "=a"(lo), "=d"(hi) : "c" (0)); + return lo; +#else + return 0; +#endif +} + +#endif /* (FLAC__CPU_IA32 || FLAC__CPU_X86_64) && FLAC__HAS_X86INTRIN */ diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/crc.c b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/crc.c index 225b26d..f58e7be 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/crc.c +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/crc.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/fixed.c b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/fixed.c index f8ebeda..78a9ec0 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/fixed.c +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/fixed.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,21 +30,17 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif #include #include +#include "../compat.h" #include "include/private/bitmath.h" #include "include/private/fixed.h" #include "../assert.h" -#ifndef M_LN2 -/* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */ -#define M_LN2 0.69314718055994530942 -#endif - #ifdef local_abs #undef local_abs #endif @@ -320,20 +316,11 @@ unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsig FLAC__ASSERT(data_len > 0 || total_error_3 == 0); FLAC__ASSERT(data_len > 0 || total_error_4 == 0); #ifndef FLAC__INTEGER_ONLY_LIBRARY -#if defined _MSC_VER || defined __MINGW32__ - /* with MSVC you have to spoon feed it the casting */ - residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0); - residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0); - residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0); - residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0); - residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)(FLAC__int64)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0); -#else residual_bits_per_sample[0] = (FLAC__float)((total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0); residual_bits_per_sample[1] = (FLAC__float)((total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0); residual_bits_per_sample[2] = (FLAC__float)((total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0); residual_bits_per_sample[3] = (FLAC__float)((total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0); residual_bits_per_sample[4] = (FLAC__float)((total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0); -#endif #else residual_bits_per_sample[0] = (total_error_0 > 0) ? local__compute_rbps_wide_integerized(total_error_0, data_len) : 0; residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_wide_integerized(total_error_1, data_len) : 0; diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/float.c b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/float.c index ae10407..1c16a2b 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/float.c +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/float.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2004-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/format.c b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/format.c index 1f37de9..eb8f56f 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/format.c +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/format.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif @@ -45,12 +45,7 @@ /* VERSION should come from configure */ FLAC_API const char *FLAC__VERSION_STRING = VERSION; -#if defined _MSC_VER || defined __BORLANDC__ || defined __MINW32__ -/* yet one more hack because of MSVC6: */ -FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC 1.3.0 20130526"; -#else -FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20130526"; -#endif +FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20141125"; FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143; diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h index 2925309..a526071 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/all.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h index 371bd48..9ca9ec3 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitmath.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,6 +34,7 @@ #define FLAC__PRIVATE__BITMATH_H #include "../../../ordinals.h" +#include "../../../assert.h" /* for CHAR_BIT */ #include @@ -74,16 +75,19 @@ static inline unsigned int FLAC__clz_soft_uint32(unsigned int word) static inline unsigned int FLAC__clz_uint32(FLAC__uint32 v) { /* Never used with input 0 */ + FLAC__ASSERT(v > 0); #if defined(__INTEL_COMPILER) return _bit_scan_reverse(v) ^ 31U; #elif defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) /* This will translate either to (bsr ^ 31U), clz , ctlz, cntlz, lzcnt depending on - * -march= setting or to a software rutine in exotic machines. */ + * -march= setting or to a software routine in exotic machines. */ return __builtin_clz(v); #elif defined(_MSC_VER) && (_MSC_VER >= 1400) - FLAC__uint32 idx; - _BitScanReverse((DWORD*) &idx, v); - return idx ^ 31U; + { + unsigned long idx; + _BitScanReverse(&idx, v); + return idx ^ 31U; + } #else return FLAC__clz_soft_uint32(v); #endif @@ -99,7 +103,7 @@ static inline unsigned int FLAC__clz2_uint32(FLAC__uint32 v) /* An example of what FLAC__bitmath_ilog2() computes: * - * ilog2( 0) = undefined + * ilog2( 0) = assertion failure * ilog2( 1) = 0 * ilog2( 2) = 1 * ilog2( 3) = 1 @@ -122,45 +126,56 @@ static inline unsigned int FLAC__clz2_uint32(FLAC__uint32 v) static inline unsigned FLAC__bitmath_ilog2(FLAC__uint32 v) { + FLAC__ASSERT(v > 0); +#if defined(__INTEL_COMPILER) + return _bit_scan_reverse(v); +#elif defined(_MSC_VER) && (_MSC_VER >= 1400) + { + unsigned long idx; + _BitScanReverse(&idx, v); + return idx; + } +#else return sizeof(FLAC__uint32) * CHAR_BIT - 1 - FLAC__clz_uint32(v); +#endif } -#ifdef FLAC__INTEGER_ONLY_LIBRARY /*Unused otherwise */ +#ifdef FLAC__INTEGER_ONLY_LIBRARY /* Unused otherwise */ static inline unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v) { - if (v == 0) - return 0; + FLAC__ASSERT(v > 0); #if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) return sizeof(FLAC__uint64) * CHAR_BIT - 1 - __builtin_clzll(v); -/* Sorry, only supported in win64/Itanium.. */ -#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && (defined(_M_IA64) || defined(_WIN64)) - FLAC__uint64 idx; - _BitScanReverse64(&idx, v); - return idx ^ 63U; +/* Sorry, only supported in x64/Itanium.. and both have fast FPU which makes integer-only encoder pointless */ +#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && (defined(_M_IA64) || defined(_M_X64)) + { + unsigned long idx; + _BitScanReverse64(&idx, v); + return idx; + } #else -/* Brain-damaged compilers will use the fastest possible way that is, +/* Brain-damaged compilers will use the fastest possible way that is, de Bruijn sequences (http://supertech.csail.mit.edu/papers/debruijn.pdf) - (C) Timothy B. Terriberry (tterribe@xiph.org) 2001-2009 LGPL (v2 or later). + (C) Timothy B. Terriberry (tterribe@xiph.org) 2001-2009 CC0 (Public domain). */ - static const unsigned char DEBRUIJN_IDX64[64]={ - 0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40, - 5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57, - 63, 6,12,18,24,27,33,39,16,37,45,47,30,53,49,56, - 62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58 - }; - int ret; - ret= v>0; - v|= v>>1; - v|= v>>2; - v|= v>>4; - v|= v>>8; - v|= v>>16; - v|= v>>32; - v= (v>>1)+1; - ret+=DEBRUIJN_IDX64[v*0x218A392CD3D5DBF>>58&0x3F]; - return ret; + { + static const unsigned char DEBRUIJN_IDX64[64]={ + 0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40, + 5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57, + 63, 6,12,18,24,27,33,39,16,37,45,47,30,53,49,56, + 62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58 + }; + v|= v>>1; + v|= v>>2; + v|= v>>4; + v|= v>>8; + v|= v>>16; + v|= v>>32; + v= (v>>1)+1; + return DEBRUIJN_IDX64[v*0x218A392CD3D5DBF>>58&0x3F]; + } #endif } #endif diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h index 4d9668f..83f8361 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitreader.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -50,7 +50,7 @@ typedef FLAC__bool (*FLAC__BitReaderReadCallback)(FLAC__byte buffer[], size_t *b */ FLAC__BitReader *FLAC__bitreader_new(void); void FLAC__bitreader_delete(FLAC__BitReader *br); -FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__CPUInfo cpu, FLAC__BitReaderReadCallback rcb, void *cd); +FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__BitReaderReadCallback rcb, void *cd); void FLAC__bitreader_free(FLAC__BitReader *br); /* does not 'free(br)' */ FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br); void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out); @@ -82,19 +82,10 @@ FLAC__bool FLAC__bitreader_read_byte_block_aligned_no_crc(FLAC__BitReader *br, F FLAC__bool FLAC__bitreader_read_unary_unsigned(FLAC__BitReader *br, unsigned *val); FLAC__bool FLAC__bitreader_read_rice_signed(FLAC__BitReader *br, int *val, unsigned parameter); FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter); -#ifndef FLAC__NO_ASM -# ifdef FLAC__CPU_IA32 -# ifdef FLAC__HAS_NASM -FLAC__bool FLAC__bitreader_read_rice_signed_block_asm_ia32_bswap(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter); -# endif -# endif -#endif #if 0 /* UNUSED */ FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, unsigned parameter); FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, unsigned *val, unsigned parameter); #endif FLAC__bool FLAC__bitreader_read_utf8_uint32(FLAC__BitReader *br, FLAC__uint32 *val, FLAC__byte *raw, unsigned *rawlen); FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *val, FLAC__byte *raw, unsigned *rawlen); - -FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br); #endif diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h index b1ff5e6..1e23efe 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/bitwriter.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/cpu.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/cpu.h index 930d678..655800e 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/cpu.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/cpu.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -41,49 +41,59 @@ typedef enum { FLAC__CPUINFO_TYPE_IA32, - FLAC__CPUINFO_TYPE_PPC, + FLAC__CPUINFO_TYPE_X86_64, FLAC__CPUINFO_TYPE_UNKNOWN } FLAC__CPUInfo_Type; +#if defined FLAC__CPU_IA32 typedef struct { - FLAC__bool cpuid; - FLAC__bool bswap; FLAC__bool cmov; FLAC__bool mmx; - FLAC__bool fxsr; FLAC__bool sse; FLAC__bool sse2; + FLAC__bool sse3; FLAC__bool ssse3; - FLAC__bool _3dnow; - FLAC__bool ext3dnow; - FLAC__bool extmmx; + FLAC__bool sse41; + FLAC__bool sse42; + FLAC__bool avx; + FLAC__bool avx2; + FLAC__bool fma; } FLAC__CPUInfo_IA32; - +#elif defined FLAC__CPU_X86_64 typedef struct { - FLAC__bool altivec; - FLAC__bool ppc64; -} FLAC__CPUInfo_PPC; + FLAC__bool sse3; + FLAC__bool ssse3; + FLAC__bool sse41; + FLAC__bool sse42; + FLAC__bool avx; + FLAC__bool avx2; + FLAC__bool fma; +} FLAC__CPUInfo_x86; +#endif typedef struct { FLAC__bool use_asm; FLAC__CPUInfo_Type type; - union { - FLAC__CPUInfo_IA32 ia32; - FLAC__CPUInfo_PPC ppc; - } data; +#if defined FLAC__CPU_IA32 + FLAC__CPUInfo_IA32 ia32; +#elif defined FLAC__CPU_X86_64 + FLAC__CPUInfo_x86 x86; +#endif } FLAC__CPUInfo; void FLAC__cpu_info(FLAC__CPUInfo *info); #ifndef FLAC__NO_ASM -#ifdef FLAC__CPU_IA32 -#ifdef FLAC__HAS_NASM +# if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32(void); void FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx); -FLAC__uint32 FLAC__cpu_info_extended_amd_asm_ia32(void); -#endif -#endif +# endif +# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN +FLAC__uint32 FLAC__cpu_have_cpuid_x86(void); +void FLAC__cpu_info_x86(FLAC__uint32 level, FLAC__uint32 *eax, FLAC__uint32 *ebx, FLAC__uint32 *ecx, FLAC__uint32 *edx); +FLAC__uint32 FLAC__cpu_xgetbv_x86(void); +# endif #endif #endif diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/crc.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/crc.h index 6284783..8ebe5c8 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/crc.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/crc.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -51,7 +51,7 @@ FLAC__uint8 FLAC__crc8(const FLAC__byte *data, unsigned len); */ extern unsigned const FLAC__crc16_table[256]; -#define FLAC__CRC16_UPDATE(data, crc) (((((crc)<<8) & 0xffff) ^ FLAC__crc16_table[((crc)>>8) ^ (data)])) +#define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) & 0xffff) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]) /* this alternate may be faster on some systems/compilers */ #if 0 #define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]) & 0xffff) diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/fixed.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/fixed.h index 0123bed..e4c044b 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/fixed.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/fixed.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -37,6 +37,7 @@ #include #endif +#include "cpu.h" #include "float.h" #include "../../../format.h" @@ -54,14 +55,22 @@ */ #ifndef FLAC__INTEGER_ONLY_LIBRARY unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); # ifndef FLAC__NO_ASM -# ifdef FLAC__CPU_IA32 -# ifdef FLAC__HAS_NASM -unsigned FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN +# ifdef FLAC__SSE2_SUPPORTED +unsigned FLAC__fixed_compute_best_predictor_intrin_sse2(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); +unsigned FLAC__fixed_compute_best_predictor_wide_intrin_sse2(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); +# endif +# ifdef FLAC__SSSE3_SUPPORTED +unsigned FLAC__fixed_compute_best_predictor_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +unsigned FLAC__fixed_compute_best_predictor_wide_intrin_ssse3(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER + 1]); # endif # endif +# if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM +unsigned FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); +# endif # endif -unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); #else unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); unsigned FLAC__fixed_compute_best_predictor_wide(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/float.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/float.h index 74d17ed..af09336 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/float.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/float.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2004-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/format.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/format.h index 996c7e9..87fb9e1 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/format.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/format.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h index d639e25..d97c26b 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/lpc.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -37,6 +37,7 @@ #include #endif +#include "cpu.h" #include "float.h" #include "../../../format.h" @@ -75,7 +76,15 @@ void FLAC__lpc_compute_autocorrelation_asm_ia32(const FLAC__real data[], unsigne void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); -void FLAC__lpc_compute_autocorrelation_asm_ia32_3dnow(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +# endif +# endif +# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN +# ifdef FLAC__SSE_SUPPORTED +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); +void FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); # endif # endif #endif @@ -145,6 +154,22 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da # ifdef FLAC__HAS_NASM void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); void FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +# endif +# endif +# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN +# ifdef FLAC__SSE2_SUPPORTED +void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +# endif +# ifdef FLAC__SSE4_1_SUPPORTED +void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_sse41(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +# endif +# ifdef FLAC__AVX2_SUPPORTED +void FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +void FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); +void FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]); # endif # endif #endif @@ -173,11 +198,17 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l # ifdef FLAC__HAS_NASM void FLAC__lpc_restore_signal_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); void FLAC__lpc_restore_signal_asm_ia32_mmx(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); +void FLAC__lpc_restore_signal_wide_asm_ia32(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); # endif /* FLAC__HAS_NASM */ -# elif defined FLAC__CPU_PPC -void FLAC__lpc_restore_signal_asm_ppc_altivec_16(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); -void FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); -# endif/* FLAC__CPU_IA32 || FLAC__CPU_PPC */ +# endif /* FLAC__CPU_IA32 */ +# if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN +# ifdef FLAC__SSE2_SUPPORTED +void FLAC__lpc_restore_signal_16_intrin_sse2(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); +# endif +# ifdef FLAC__SSE4_1_SUPPORTED +void FLAC__lpc_restore_signal_wide_intrin_sse41(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); +# endif +# endif #endif /* FLAC__NO_ASM */ #ifndef FLAC__INTEGER_ONLY_LIBRARY diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h index 2cf5c5d..b1324a9 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/md5.h @@ -28,11 +28,17 @@ #include "../../../ordinals.h" +typedef union { + FLAC__byte *p8; + FLAC__int16 *p16; + FLAC__int32 *p32; +} FLAC__multibyte; + typedef struct { FLAC__uint32 in[16]; FLAC__uint32 buf[4]; FLAC__uint32 bytes[2]; - FLAC__byte *internal_buf; + FLAC__multibyte internal_buf; size_t capacity; } FLAC__MD5Context; diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h index d6651c6..c387ea6 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/memory.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h index a29050e..29c73e0 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/metadata.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2002-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h index 51bf8c3..eaa9958 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/stream_encoder_framing.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h index 8acec39..8464d22 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/private/window.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2006-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -65,6 +65,8 @@ void FLAC__window_nuttall(FLAC__real *window, const FLAC__int32 L); void FLAC__window_rectangle(FLAC__real *window, const FLAC__int32 L); void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L); void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p); +void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end); +void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end); void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L); #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h index 057cd73..b852c2b 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/all.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h index 0d5813f..d8a3e61 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_decoder.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -40,6 +40,7 @@ typedef struct FLAC__StreamDecoderProtected { FLAC__StreamDecoderState state; + FLAC__StreamDecoderInitStatus initstate; unsigned channels; FLAC__ChannelAssignment channel_assignment; unsigned bits_per_sample; diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h index 2c632f9..bd0cf25 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/include/protected/stream_encoder.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -59,6 +59,8 @@ typedef enum { FLAC__APODIZATION_RECTANGLE, FLAC__APODIZATION_TRIANGLE, FLAC__APODIZATION_TUKEY, + FLAC__APODIZATION_PARTIAL_TUKEY, + FLAC__APODIZATION_PUNCHOUT_TUKEY, FLAC__APODIZATION_WELCH } FLAC__ApodizationFunction; @@ -71,6 +73,11 @@ typedef struct { struct { FLAC__real p; } tukey; + struct { + FLAC__real p; + FLAC__real start; + FLAC__real end; + } multiple_tukey; } parameters; } FLAC__ApodizationSpecification; diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c index 5741e7c..87e2321 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/lpc_flac.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif @@ -50,11 +50,6 @@ #ifndef FLAC__INTEGER_ONLY_LIBRARY -#ifndef M_LN2 -/* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */ -#define M_LN2 0.69314718055994530942 -#endif - #if !defined(HAVE_LROUND) #if defined(_MSC_VER) #include @@ -65,7 +60,7 @@ static inline long int lround(double x) { return (long)(x + copysign (0.5, x)); } -//If this fails, we are in the precence of a mid 90's compiler..move along... +/* If this fails, we are in the presence of a mid 90's compiler, move along... */ #endif void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len) @@ -160,7 +155,7 @@ void FLAC__lpc_compute_lp_coefficients(const FLAC__real autoc[], unsigned *max_o lp_coeff[i][j] = (FLAC__real)(-lpc[j]); /* negate FIR filter coeff to get predictor coeff */ error[i] = err; - /* see SF bug #1601812 http://sourceforge.net/tracker/index.php?func=detail&aid=1601812&group_id=13478&atid=113478 */ + /* see SF bug https://sourceforge.net/p/flac/bugs/234/ */ if(err == 0.0) { *max_order = i+1; return; @@ -264,7 +259,12 @@ int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order, return 0; } -void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]) +#if defined(_MSC_VER) +// silence MSVC warnings about __restrict modifier +#pragma warning ( disable : 4028 ) +#endif + +void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 * flac_restrict data, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict residual) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) { FLAC__int64 sumo; @@ -524,7 +524,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, u } #endif -void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[]) +void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 * flac_restrict data, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict residual) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) { unsigned i, j; @@ -780,7 +780,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ -void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]) +void FLAC__lpc_restore_signal(const FLAC__int32 * flac_restrict residual, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict data) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) { FLAC__int64 sumo; @@ -1041,7 +1041,7 @@ void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, c } #endif -void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]) +void FLAC__lpc_restore_signal_wide(const FLAC__int32 * flac_restrict residual, unsigned data_len, const FLAC__int32 * flac_restrict qlp_coeff, unsigned order, int lp_quantization, FLAC__int32 * flac_restrict data) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS) { unsigned i, j; @@ -1295,6 +1295,10 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l } #endif +#if defined(_MSC_VER) +#pragma warning ( default : 4028 ) +#endif + #ifndef FLAC__INTEGER_ONLY_LIBRARY FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples) diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/md5.c b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/md5.c index c448b87..d41f6a8 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/md5.c +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/md5.c @@ -1,4 +1,4 @@ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif @@ -7,6 +7,7 @@ #include "include/private/md5.h" #include "../alloc.h" +#include "../endswap.h" /* * This code implements the MD5 message-digest algorithm. @@ -223,7 +224,7 @@ void FLAC__MD5Init(FLAC__MD5Context *ctx) ctx->bytes[0] = 0; ctx->bytes[1] = 0; - ctx->internal_buf = 0; + ctx->internal_buf.p8= 0; ctx->capacity = 0; } @@ -259,9 +260,9 @@ void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx) byteSwap(ctx->buf, 4); memcpy(digest, ctx->buf, 16); - if(0 != ctx->internal_buf) { - free(ctx->internal_buf); - ctx->internal_buf = 0; + if (0 != ctx->internal_buf.p8) { + free(ctx->internal_buf.p8); + ctx->internal_buf.p8= 0; ctx->capacity = 0; } memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ @@ -270,58 +271,124 @@ void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx) /* * Convert the incoming audio signal to a byte stream */ -static void format_input_(FLAC__byte *buf, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample) +static void format_input_(FLAC__multibyte *mbuf, const FLAC__int32 * const signal[], unsigned channels, unsigned samples, unsigned bytes_per_sample) { + FLAC__byte *buf_ = mbuf->p8; + FLAC__int16 *buf16 = mbuf->p16; + FLAC__int32 *buf32 = mbuf->p32; + FLAC__int32 a_word; unsigned channel, sample; - register FLAC__int32 a_word; - register FLAC__byte *buf_ = buf; -#if WORDS_BIGENDIAN -#else - if(channels == 2 && bytes_per_sample == 2) { - FLAC__int16 *buf1_ = ((FLAC__int16*)buf_) + 1; - memcpy(buf_, signal[0], sizeof(FLAC__int32) * samples); - for(sample = 0; sample < samples; sample++, buf1_+=2) - *buf1_ = (FLAC__int16)signal[1][sample]; - } - else if(channels == 1 && bytes_per_sample == 2) { - FLAC__int16 *buf1_ = (FLAC__int16*)buf_; - for(sample = 0; sample < samples; sample++) - *buf1_++ = (FLAC__int16)signal[0][sample]; - } - else -#endif - if(bytes_per_sample == 2) { - if(channels == 2) { - for(sample = 0; sample < samples; sample++) { + /* Storage in the output buffer, buf, is little endian. */ + +#define BYTES_CHANNEL_SELECTOR(bytes, channels) (bytes * 100 + channels) + + /* First do the most commonly used combinations. */ + switch (BYTES_CHANNEL_SELECTOR (bytes_per_sample, channels)) { + /* One byte per sample. */ + case (BYTES_CHANNEL_SELECTOR (1, 1)): + for (sample = 0; sample < samples; sample++) + *buf_++ = signal[0][sample]; + return; + + case (BYTES_CHANNEL_SELECTOR (1, 2)): + for (sample = 0; sample < samples; sample++) { + *buf_++ = signal[0][sample]; + *buf_++ = signal[1][sample]; + } + return; + + case (BYTES_CHANNEL_SELECTOR (1, 4)): + for (sample = 0; sample < samples; sample++) { + *buf_++ = signal[0][sample]; + *buf_++ = signal[1][sample]; + *buf_++ = signal[2][sample]; + *buf_++ = signal[3][sample]; + } + return; + + case (BYTES_CHANNEL_SELECTOR (1, 6)): + for (sample = 0; sample < samples; sample++) { + *buf_++ = signal[0][sample]; + *buf_++ = signal[1][sample]; + *buf_++ = signal[2][sample]; + *buf_++ = signal[3][sample]; + *buf_++ = signal[4][sample]; + *buf_++ = signal[5][sample]; + } + return; + + case (BYTES_CHANNEL_SELECTOR (1, 8)): + for (sample = 0; sample < samples; sample++) { + *buf_++ = signal[0][sample]; + *buf_++ = signal[1][sample]; + *buf_++ = signal[2][sample]; + *buf_++ = signal[3][sample]; + *buf_++ = signal[4][sample]; + *buf_++ = signal[5][sample]; + *buf_++ = signal[6][sample]; + *buf_++ = signal[7][sample]; + } + return; + + /* Two bytes per sample. */ + case (BYTES_CHANNEL_SELECTOR (2, 1)): + for (sample = 0; sample < samples; sample++) + *buf16++ = H2LE_16(signal[0][sample]); + return; + + case (BYTES_CHANNEL_SELECTOR (2, 2)): + for (sample = 0; sample < samples; sample++) { + *buf16++ = H2LE_16(signal[0][sample]); + *buf16++ = H2LE_16(signal[1][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR (2, 4)): + for (sample = 0; sample < samples; sample++) { + *buf16++ = H2LE_16(signal[0][sample]); + *buf16++ = H2LE_16(signal[1][sample]); + *buf16++ = H2LE_16(signal[2][sample]); + *buf16++ = H2LE_16(signal[3][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR (2, 6)): + for (sample = 0; sample < samples; sample++) { + *buf16++ = H2LE_16(signal[0][sample]); + *buf16++ = H2LE_16(signal[1][sample]); + *buf16++ = H2LE_16(signal[2][sample]); + *buf16++ = H2LE_16(signal[3][sample]); + *buf16++ = H2LE_16(signal[4][sample]); + *buf16++ = H2LE_16(signal[5][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR (2, 8)): + for (sample = 0; sample < samples; sample++) { + *buf16++ = H2LE_16(signal[0][sample]); + *buf16++ = H2LE_16(signal[1][sample]); + *buf16++ = H2LE_16(signal[2][sample]); + *buf16++ = H2LE_16(signal[3][sample]); + *buf16++ = H2LE_16(signal[4][sample]); + *buf16++ = H2LE_16(signal[5][sample]); + *buf16++ = H2LE_16(signal[6][sample]); + *buf16++ = H2LE_16(signal[7][sample]); + } + return; + + /* Three bytes per sample. */ + case (BYTES_CHANNEL_SELECTOR (3, 1)): + for (sample = 0; sample < samples; sample++) { a_word = signal[0][sample]; *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; - a_word = signal[1][sample]; *buf_++ = (FLAC__byte)a_word; a_word >>= 8; *buf_++ = (FLAC__byte)a_word; } - } - else if(channels == 1) { - for(sample = 0; sample < samples; sample++) { - a_word = signal[0][sample]; - *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; - } - } - else { - for(sample = 0; sample < samples; sample++) { - for(channel = 0; channel < channels; channel++) { - a_word = signal[channel][sample]; - *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; - } - } - } - } - else if(bytes_per_sample == 3) { - if(channels == 2) { - for(sample = 0; sample < samples; sample++) { + return; + + case (BYTES_CHANNEL_SELECTOR (3, 2)): + for (sample = 0; sample < samples; sample++) { a_word = signal[0][sample]; *buf_++ = (FLAC__byte)a_word; a_word >>= 8; *buf_++ = (FLAC__byte)a_word; a_word >>= 8; @@ -331,60 +398,90 @@ static void format_input_(FLAC__byte *buf, const FLAC__int32 * const signal[], u *buf_++ = (FLAC__byte)a_word; a_word >>= 8; *buf_++ = (FLAC__byte)a_word; } - } - else if(channels == 1) { - for(sample = 0; sample < samples; sample++) { - a_word = signal[0][sample]; - *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; + return; + + /* Four bytes per sample. */ + case (BYTES_CHANNEL_SELECTOR (4, 1)): + for (sample = 0; sample < samples; sample++) + *buf32++ = H2LE_32(signal[0][sample]); + return; + + case (BYTES_CHANNEL_SELECTOR (4, 2)): + for (sample = 0; sample < samples; sample++) { + *buf32++ = H2LE_32(signal[0][sample]); + *buf32++ = H2LE_32(signal[1][sample]); } - } - else { - for(sample = 0; sample < samples; sample++) { - for(channel = 0; channel < channels; channel++) { + return; + + case (BYTES_CHANNEL_SELECTOR (4, 4)): + for (sample = 0; sample < samples; sample++) { + *buf32++ = H2LE_32(signal[0][sample]); + *buf32++ = H2LE_32(signal[1][sample]); + *buf32++ = H2LE_32(signal[2][sample]); + *buf32++ = H2LE_32(signal[3][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR (4, 6)): + for (sample = 0; sample < samples; sample++) { + *buf32++ = H2LE_32(signal[0][sample]); + *buf32++ = H2LE_32(signal[1][sample]); + *buf32++ = H2LE_32(signal[2][sample]); + *buf32++ = H2LE_32(signal[3][sample]); + *buf32++ = H2LE_32(signal[4][sample]); + *buf32++ = H2LE_32(signal[5][sample]); + } + return; + + case (BYTES_CHANNEL_SELECTOR (4, 8)): + for (sample = 0; sample < samples; sample++) { + *buf32++ = H2LE_32(signal[0][sample]); + *buf32++ = H2LE_32(signal[1][sample]); + *buf32++ = H2LE_32(signal[2][sample]); + *buf32++ = H2LE_32(signal[3][sample]); + *buf32++ = H2LE_32(signal[4][sample]); + *buf32++ = H2LE_32(signal[5][sample]); + *buf32++ = H2LE_32(signal[6][sample]); + *buf32++ = H2LE_32(signal[7][sample]); + } + return; + + default: + break; + } + + /* General version. */ + switch (bytes_per_sample) { + case 1: + for (sample = 0; sample < samples; sample++) + for (channel = 0; channel < channels; channel++) + *buf_++ = signal[channel][sample]; + return; + + case 2: + for (sample = 0; sample < samples; sample++) + for (channel = 0; channel < channels; channel++) + *buf16++ = H2LE_16(signal[channel][sample]); + return; + + case 3: + for (sample = 0; sample < samples; sample++) + for (channel = 0; channel < channels; channel++) { a_word = signal[channel][sample]; *buf_++ = (FLAC__byte)a_word; a_word >>= 8; *buf_++ = (FLAC__byte)a_word; a_word >>= 8; *buf_++ = (FLAC__byte)a_word; } - } - } - } - else if(bytes_per_sample == 1) { - if(channels == 2) { - for(sample = 0; sample < samples; sample++) { - a_word = signal[0][sample]; - *buf_++ = (FLAC__byte)a_word; - a_word = signal[1][sample]; - *buf_++ = (FLAC__byte)a_word; - } - } - else if(channels == 1) { - for(sample = 0; sample < samples; sample++) { - a_word = signal[0][sample]; - *buf_++ = (FLAC__byte)a_word; - } - } - else { - for(sample = 0; sample < samples; sample++) { - for(channel = 0; channel < channels; channel++) { - a_word = signal[channel][sample]; - *buf_++ = (FLAC__byte)a_word; - } - } - } - } - else { /* bytes_per_sample == 4, maybe optimize more later */ - for(sample = 0; sample < samples; sample++) { - for(channel = 0; channel < channels; channel++) { - a_word = signal[channel][sample]; - *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; a_word >>= 8; - *buf_++ = (FLAC__byte)a_word; - } - } + return; + + case 4: + for (sample = 0; sample < samples; sample++) + for (channel = 0; channel < channels; channel++) + *buf32++ = H2LE_32(signal[channel][sample]); + return; + + default: + break; } } @@ -396,26 +493,26 @@ FLAC__bool FLAC__MD5Accumulate(FLAC__MD5Context *ctx, const FLAC__int32 * const const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample; /* overflow check */ - if((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample) + if ((size_t)channels > SIZE_MAX / (size_t)bytes_per_sample) return false; - if((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples) + if ((size_t)channels * (size_t)bytes_per_sample > SIZE_MAX / (size_t)samples) return false; - if(ctx->capacity < bytes_needed) { - FLAC__byte *tmp = (FLAC__byte*) realloc(ctx->internal_buf, bytes_needed); - if(0 == tmp) { - free(ctx->internal_buf); - if(0 == (ctx->internal_buf = (FLAC__byte*) safe_malloc_(bytes_needed))) + if (ctx->capacity < bytes_needed) { + FLAC__byte *tmp = (FLAC__byte*) realloc(ctx->internal_buf.p8, bytes_needed); + if (0 == tmp) { + free(ctx->internal_buf.p8); + if (0 == (ctx->internal_buf.p8= (FLAC__byte*) safe_malloc_(bytes_needed))) return false; } else - ctx->internal_buf = tmp; + ctx->internal_buf.p8= tmp; ctx->capacity = bytes_needed; } - format_input_(ctx->internal_buf, signal, channels, samples, bytes_per_sample); + format_input_(&ctx->internal_buf, signal, channels, samples, bytes_per_sample); - FLAC__MD5Update(ctx, ctx->internal_buf, bytes_needed); + FLAC__MD5Update(ctx, ctx->internal_buf.p8, bytes_needed); return true; } diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/memory.c b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/memory.c index dd972e0..fb125f1 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/memory.c +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/memory.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,10 +30,14 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif +#ifdef HAVE_STDINT_H +#include +#endif + #include "include/private/memory.h" #include "../assert.h" #include "../alloc.h" @@ -46,25 +50,8 @@ void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address) #ifdef FLAC__ALIGN_MALLOC_DATA /* align on 32-byte (256-bit) boundary */ - x = safe_malloc_add_2op_(bytes, /*+*/31); -#ifdef SIZEOF_VOIDP -#if SIZEOF_VOIDP == 4 - /* could do *aligned_address = x + ((unsigned) (32 - (((unsigned)x) & 31))) & 31; */ - *aligned_address = (void*)(((unsigned)x + 31) & -32); -#elif SIZEOF_VOIDP == 8 - *aligned_address = (void*)(((FLAC__uint64)x + 31) & (FLAC__uint64)(-((FLAC__int64)32))); -#else -# error Unsupported sizeof(void*) -#endif -#else - /* there's got to be a better way to do this right for all archs */ - if(sizeof(void*) == sizeof(unsigned)) - *aligned_address = (void*)(((unsigned)x + 31) & -32); - else if(sizeof(void*) == sizeof(FLAC__uint64)) - *aligned_address = (void*)(((FLAC__uint64)x + 31) & (FLAC__uint64)(-((FLAC__int64)32))); - else - return 0; -#endif + x = safe_malloc_add_2op_(bytes, /*+*/31L); + *aligned_address = (void*)(((uintptr_t)x + 31L) & -32L); #else x = safe_malloc_(bytes); *aligned_address = x; diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c index 04e1766..d6a7973 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/stream_decoder.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif @@ -70,7 +70,7 @@ FLAC_API int FLAC_API_SUPPORTS_OGG_FLAC = * ***********************************************************************/ -static FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' }; +static const FLAC__byte ID3V2_TAG_[3] = { 'I', 'D', '3' }; /*********************************************************************** * @@ -86,7 +86,7 @@ static FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder); static FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder); static FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length); static FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length); -static FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj); +static FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, unsigned length); static FLAC__bool read_metadata_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj); static FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj); static FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder); @@ -141,9 +141,6 @@ typedef struct FLAC__StreamDecoderPrivate { void (*local_lpc_restore_signal_64bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit): */ void (*local_lpc_restore_signal_16bit)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); - /* for use when the signal is <= 16 bits-per-sample, or <= 15 bits-per-sample on a side channel (which requires 1 extra bit), AND order <= 8: */ - void (*local_lpc_restore_signal_16bit_order8)(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[]); - FLAC__bool (*local_bitreader_read_rice_signed_block)(FLAC__BitReader *br, int vals[], unsigned nvals, unsigned parameter); void *client_data; FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */ FLAC__BitReader *input; @@ -380,7 +377,7 @@ static FLAC__StreamDecoderInitStatus init_stream_internal_( #if FLAC__HAS_OGG decoder->private_->is_ogg = is_ogg; if(is_ogg && !FLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect)) - return decoder->protected_->state = FLAC__STREAM_DECODER_OGG_ERROR; + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE; #endif /* @@ -391,42 +388,44 @@ static FLAC__StreamDecoderInitStatus init_stream_internal_( decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal; decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide; decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal; - decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal; - decoder->private_->local_bitreader_read_rice_signed_block = FLAC__bitreader_read_rice_signed_block; /* now override with asm where appropriate */ #ifndef FLAC__NO_ASM if(decoder->private_->cpuinfo.use_asm) { #ifdef FLAC__CPU_IA32 FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); #ifdef FLAC__HAS_NASM -#if 1 /*@@@@@@ OPT: not clearly faster, needs more testing */ - if(decoder->private_->cpuinfo.data.ia32.bswap) - decoder->private_->local_bitreader_read_rice_signed_block = FLAC__bitreader_read_rice_signed_block_asm_ia32_bswap; -#endif - if(decoder->private_->cpuinfo.data.ia32.mmx) { + decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */ + if(decoder->private_->cpuinfo.ia32.mmx) { decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32_mmx; - decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32_mmx; } else { decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ia32; - decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32; } #endif -#elif defined FLAC__CPU_PPC - FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_PPC); - if(decoder->private_->cpuinfo.data.ppc.altivec) { - decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ppc_altivec_16; - decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8; +#ifdef FLAC__HAS_X86INTRIN +# if defined FLAC__SSE2_SUPPORTED && !defined FLAC__HAS_NASM /* OPT_SSE: not better than MMX asm */ + if(decoder->private_->cpuinfo.ia32.sse2) { + decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_16_intrin_sse2; } +# endif +# if defined FLAC__SSE4_1_SUPPORTED + if(decoder->private_->cpuinfo.ia32.sse41) { + decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide_intrin_sse41; + } +# endif +#endif +#elif defined FLAC__CPU_X86_64 + FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64); + /* No useful SSE optimizations yet */ #endif } #endif /* from here on, errors are fatal */ - if(!FLAC__bitreader_init(decoder->private_->input, decoder->private_->cpuinfo, read_callback_, decoder)) { + if(!FLAC__bitreader_init(decoder->private_->input, read_callback_, decoder)) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return FLAC__STREAM_DECODER_INIT_STATUS_MEMORY_ALLOCATION_ERROR; } @@ -528,10 +527,10 @@ static FLAC__StreamDecoderInitStatus init_FILE_internal_( FLAC__ASSERT(0 != file); if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) - return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED); + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED; if(0 == write_callback || 0 == error_callback) - return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS); + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; /* * To make sure that our file does not go unclosed after an error, we @@ -602,10 +601,10 @@ static FLAC__StreamDecoderInitStatus init_file_internal_( * in FLAC__stream_decoder_init_FILE() before the FILE* is assigned. */ if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) - return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED); + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_ALREADY_INITIALIZED; if(0 == write_callback || 0 == error_callback) - return (FLAC__StreamDecoderInitStatus) (decoder->protected_->state = (FLAC__StreamDecoderState) FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS); + return decoder->protected_->initstate = FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS; file = filename? flac_fopen(filename, "rb") : stdin; @@ -652,7 +651,7 @@ FLAC_API FLAC__bool FLAC__stream_decoder_finish(FLAC__StreamDecoder *decoder) if(decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED) return true; - /* see the comment in FLAC__seekable_stream_decoder_reset() as to why we + /* see the comment in FLAC__stream_decoder_reset() as to why we * always call FLAC__MD5Final() */ FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context); @@ -1316,9 +1315,6 @@ FLAC__bool allocate_output_(FLAC__StreamDecoder *decoder, unsigned size, unsigne memset(tmp, 0, sizeof(FLAC__int32)*4); decoder->private_->output[i] = tmp + 4; - /* WATCHOUT: - * minimum of quadword alignment for PPC vector optimizations is REQUIRED: - */ if(!FLAC__memory_alloc_aligned_int32_array(size, &decoder->private_->residual_unaligned[i], &decoder->private_->residual[i])) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; return false; @@ -1368,6 +1364,10 @@ FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder) id_ = 0; continue; } + + if(id_ >= 3) + return false; + if(x == ID3V2_TAG_[id_]) { id_++; i = 0; @@ -1446,6 +1446,7 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) unsigned real_length = length; FLAC__StreamMetadata block; + memset(&block, 0, sizeof(block)); block.is_last = is_last; block.type = (FLAC__MetadataType)type; block.length = length; @@ -1470,36 +1471,37 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) return false; /* read_callback_ sets the state for us */ } else { + FLAC__bool ok = true; switch(type) { case FLAC__METADATA_TYPE_PADDING: /* skip the padding bytes */ if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length)) - return false; /* read_callback_ sets the state for us */ + ok = false; /* read_callback_ sets the state for us */ break; case FLAC__METADATA_TYPE_APPLICATION: /* remember, we read the ID already */ if(real_length > 0) { if(0 == (block.data.application.data = (FLAC__byte*) malloc(real_length))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; + ok = false; } - if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.data, real_length)) - return false; /* read_callback_ sets the state for us */ + else if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.application.data, real_length)) + ok = false; /* read_callback_ sets the state for us */ } else block.data.application.data = 0; break; case FLAC__METADATA_TYPE_VORBIS_COMMENT: - if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment)) - return false; + if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment, real_length)) + ok = false; break; case FLAC__METADATA_TYPE_CUESHEET: if(!read_metadata_cuesheet_(decoder, &block.data.cue_sheet)) - return false; + ok = false; break; case FLAC__METADATA_TYPE_PICTURE: if(!read_metadata_picture_(decoder, &block.data.picture)) - return false; + ok = false; break; case FLAC__METADATA_TYPE_STREAMINFO: case FLAC__METADATA_TYPE_SEEKTABLE: @@ -1509,16 +1511,16 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) if(real_length > 0) { if(0 == (block.data.unknown.data = (FLAC__byte*) malloc(real_length))) { decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; + ok = false; } - if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.unknown.data, real_length)) - return false; /* read_callback_ sets the state for us */ + else if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, block.data.unknown.data, real_length)) + ok = false; /* read_callback_ sets the state for us */ } else block.data.unknown.data = 0; break; } - if(!decoder->private_->is_seeking && decoder->private_->metadata_callback) + if(ok && !decoder->private_->is_seeking && decoder->private_->metadata_callback) decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data); /* now we have to free any malloc()ed data in the block */ @@ -1563,6 +1565,9 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder) free(block.data.unknown.data); break; } + + if(!ok) /* anything that unsets "ok" should also make sure decoder->protected_->state is updated */ + return false; } } @@ -1689,58 +1694,88 @@ FLAC__bool read_metadata_seektable_(FLAC__StreamDecoder *decoder, FLAC__bool is_ return true; } -FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj) +FLAC__bool read_metadata_vorbiscomment_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_VorbisComment *obj, unsigned length) { FLAC__uint32 i; FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); /* read vendor string */ - FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); - if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length)) - return false; /* read_callback_ sets the state for us */ - if(obj->vendor_string.length > 0) { - if(0 == (obj->vendor_string.entry = (FLAC__byte*) safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length)) + if (length >= 8) { + length -= 8; /* vendor string length + num comments entries alone take 8 bytes */ + FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); + if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length)) return false; /* read_callback_ sets the state for us */ - obj->vendor_string.entry[obj->vendor_string.length] = '\0'; - } - else - obj->vendor_string.entry = 0; - - /* read num comments */ - FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32); - if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->num_comments)) - return false; /* read_callback_ sets the state for us */ - - /* read comments */ - if(obj->num_comments > 0) { - if(0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*) safe_malloc_mul_2op_p(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - for(i = 0; i < obj->num_comments; i++) { - FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); - if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length)) - return false; /* read_callback_ sets the state for us */ - if(obj->comments[i].length > 0) { - if(0 == (obj->comments[i].entry = (FLAC__byte*) safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) { - decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; - return false; - } - if(!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length)) - return false; /* read_callback_ sets the state for us */ - obj->comments[i].entry[obj->comments[i].length] = '\0'; + if (obj->vendor_string.length > 0) { + if (length < obj->vendor_string.length) { + obj->vendor_string.length = 0; + obj->vendor_string.entry = 0; + goto skip; } else - obj->comments[i].entry = 0; + length -= obj->vendor_string.length; + if (0 == (obj->vendor_string.entry = (FLAC__byte*) safe_malloc_add_2op_(obj->vendor_string.length, /*+*/1))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->vendor_string.entry, obj->vendor_string.length)) + return false; /* read_callback_ sets the state for us */ + obj->vendor_string.entry[obj->vendor_string.length] = '\0'; } + else + obj->vendor_string.entry = 0; + + /* read num comments */ + FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_NUM_COMMENTS_LEN == 32); + if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->num_comments)) + return false; /* read_callback_ sets the state for us */ + + /* read comments */ + if (obj->num_comments > 0) { + if (0 == (obj->comments = (FLAC__StreamMetadata_VorbisComment_Entry*) safe_malloc_mul_2op_p(obj->num_comments, /*times*/sizeof(FLAC__StreamMetadata_VorbisComment_Entry)))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + for (i = 0; i < obj->num_comments; i++) { + FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); + if (length < 4) { + obj->num_comments = i; + goto skip; + } + else + length -= 4; + if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->comments[i].length)) + return false; /* read_callback_ sets the state for us */ + if (obj->comments[i].length > 0) { + if (length < obj->comments[i].length) { + obj->comments[i].length = 0; + obj->comments[i].entry = 0; + obj->num_comments = i; + goto skip; + } + else + length -= obj->comments[i].length; + if (0 == (obj->comments[i].entry = (FLAC__byte*) safe_malloc_add_2op_(obj->comments[i].length, /*+*/1))) { + decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; + return false; + } + if (!FLAC__bitreader_read_byte_block_aligned_no_crc(decoder->private_->input, obj->comments[i].entry, obj->comments[i].length)) + return false; /* read_callback_ sets the state for us */ + obj->comments[i].entry[obj->comments[i].length] = '\0'; + } + else + obj->comments[i].entry = 0; + } + } + else + obj->comments = 0; } - else { - obj->comments = 0; + + skip: + if (length > 0) { + /* This will only happen on files with invalid data in comments */ + if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, length)) + return false; /* read_callback_ sets the state for us */ } return true; @@ -2655,12 +2690,8 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, un if( (FLAC__uint64)order * ((((FLAC__uint64)1)<qlp_coeff_precision)-1) < (((FLAC__uint64)-1) << 32) ) */ if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32) - if(bps <= 16 && subframe->qlp_coeff_precision <= 16) { - if(order <= 8) - decoder->private_->local_lpc_restore_signal_16bit_order8(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); - else - decoder->private_->local_lpc_restore_signal_16bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); - } + if(bps <= 16 && subframe->qlp_coeff_precision <= 16) + decoder->private_->local_lpc_restore_signal_16bit(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); else decoder->private_->local_lpc_restore_signal(decoder->private_->residual[channel], decoder->private_->frame.header.blocksize-order, subframe->qlp_coeff, order, subframe->quantization_level, decoder->private_->output[channel]+order); else @@ -2708,14 +2739,16 @@ FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigne if(decoder->private_->frame.header.blocksize < predictor_order) { send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; + /* We have received a potentially malicious bit stream. All we can do is error out to avoid a heap overflow. */ + return false; } } else { if(partition_samples < predictor_order) { send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; - return true; + /* We have received a potentially malicious bit stream. All we can do is error out to avoid a heap overflow. */ + return false; } } @@ -2732,7 +2765,7 @@ FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigne if(rice_parameter < pesc) { partitioned_rice_contents->raw_bits[partition] = 0; u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order; - if(!decoder->private_->local_bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter)) + if(!FLAC__bitreader_read_rice_signed_block(decoder->private_->input, residual + sample, u, rice_parameter)) return false; /* read_callback_ sets the state for us */ sample += u; } @@ -3074,12 +3107,7 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s return false; } #ifndef FLAC__INTEGER_ONLY_LIBRARY -#if defined _MSC_VER || defined __MINGW32__ - /* with VC++ you have to spoon feed it the casting */ - pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(FLAC__int64)(target_sample - lower_bound_sample) / (FLAC__double)(FLAC__int64)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(FLAC__int64)(upper_bound - lower_bound)) - approx_bytes_per_frame; -#else pos = (FLAC__int64)lower_bound + (FLAC__int64)((FLAC__double)(target_sample - lower_bound_sample) / (FLAC__double)(upper_bound_sample - lower_bound_sample) * (FLAC__double)(upper_bound - lower_bound)) - approx_bytes_per_frame; -#endif #else /* a little less accurate: */ if(upper_bound - lower_bound < 0xffffffff) @@ -3203,12 +3231,7 @@ FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint } else { #ifndef FLAC__INTEGER_ONLY_LIBRARY -#if defined _MSC_VER || defined __MINGW32__ - /* with MSVC you have to spoon feed it the casting */ - pos = (FLAC__uint64)((FLAC__double)(FLAC__int64)(target_sample - left_sample) / (FLAC__double)(FLAC__int64)(right_sample - left_sample) * (FLAC__double)(FLAC__int64)(right_pos - left_pos)); -#else pos = (FLAC__uint64)((FLAC__double)(target_sample - left_sample) / (FLAC__double)(right_sample - left_sample) * (FLAC__double)(right_pos - left_pos)); -#endif #else /* a little less accurate: */ if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff)) diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder.c b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder.c index 20e98da..f5eb90e 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder.c +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif @@ -55,10 +55,10 @@ #include "include/private/ogg_helper.h" #include "include/private/ogg_mapping.h" #endif +#include "include/private/stream_encoder.h" #include "include/private/stream_encoder_framing.h" #include "include/private/window.h" #include "../alloc.h" -#include "../compat.h" /* Exact Rice codeword length calculation is off by default. The simple @@ -103,16 +103,18 @@ static struct CompressionLevels { unsigned min_residual_partition_order; unsigned max_residual_partition_order; unsigned rice_parameter_search_dist; + const char *apodization; } compression_levels_[] = { - { false, false, 0, 0, false, false, false, 0, 3, 0 }, - { true , true , 0, 0, false, false, false, 0, 3, 0 }, - { true , false, 0, 0, false, false, false, 0, 3, 0 }, - { false, false, 6, 0, false, false, false, 0, 4, 0 }, - { true , true , 8, 0, false, false, false, 0, 4, 0 }, - { true , false, 8, 0, false, false, false, 0, 5, 0 }, - { true , false, 8, 0, false, false, false, 0, 6, 0 }, - { true , false, 8, 0, false, false, true , 0, 6, 0 }, - { true , false, 12, 0, false, false, true , 0, 6, 0 } + { false, false, 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" }, + { true , true , 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" }, + { true , false, 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" }, + { false, false, 6, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" }, + { true , true , 8, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" }, + { true , false, 8, 0, false, false, false, 0, 5, 0, "tukey(5e-1)" }, + { true , false, 8, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2)" }, + { true , false, 12, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2)" }, + { true , false, 12, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2);punchout_tukey(3)" } + /* here we use locale-independent 5e-1 instead of 0.5 or 0,5 */ }; @@ -342,10 +344,13 @@ typedef struct FLAC__StreamEncoderPrivate { unsigned current_frame_number; FLAC__MD5Context md5context; FLAC__CPUInfo cpuinfo; + void (*local_precompute_partition_info_sums)(const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], unsigned residual_samples, unsigned predictor_order, unsigned min_partition_order, unsigned max_partition_order, unsigned bps); #ifndef FLAC__INTEGER_ONLY_LIBRARY unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); + unsigned (*local_fixed_compute_best_predictor_wide)(const FLAC__int32 data[], unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); #else unsigned (*local_fixed_compute_best_predictor)(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); + unsigned (*local_fixed_compute_best_predictor_wide)(const FLAC__int32 data[], unsigned data_len, FLAC__fixedpoint residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1]); #endif #ifndef FLAC__INTEGER_ONLY_LIBRARY void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); @@ -873,7 +878,9 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( #ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; #endif + encoder->private_->local_precompute_partition_info_sums = precompute_partition_info_sums_; encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor; + encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide; #ifndef FLAC__INTEGER_ONLY_LIBRARY encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients; encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide; @@ -886,21 +893,23 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( # ifdef FLAC__CPU_IA32 FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); # ifdef FLAC__HAS_NASM - if(encoder->private_->cpuinfo.data.ia32.sse) { + if(encoder->private_->cpuinfo.ia32.sse) { if(encoder->protected_->max_lpc_order < 4) encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4; else if(encoder->protected_->max_lpc_order < 8) encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8; else if(encoder->protected_->max_lpc_order < 12) encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12; + else if(encoder->protected_->max_lpc_order < 16) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_16; else encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32; } - else if(encoder->private_->cpuinfo.data.ia32._3dnow) - encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_3dnow; else encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32; - if(encoder->private_->cpuinfo.data.ia32.mmx) { + + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_asm_ia32; /* OPT_IA32: was really necessary for GCC < 4.9 */ + if(encoder->private_->cpuinfo.ia32.mmx) { encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx; } @@ -908,16 +917,137 @@ static FLAC__StreamEncoderInitStatus init_stream_internal_( encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32; } - if(encoder->private_->cpuinfo.data.ia32.mmx && encoder->private_->cpuinfo.data.ia32.cmov) + + if(encoder->private_->cpuinfo.ia32.mmx && encoder->private_->cpuinfo.ia32.cmov) encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov; # endif /* FLAC__HAS_NASM */ -# endif /* FLAC__CPU_IA32 */ +# ifdef FLAC__HAS_X86INTRIN +# if defined FLAC__SSE_SUPPORTED + if(encoder->private_->cpuinfo.ia32.sse) { + if(encoder->protected_->max_lpc_order < 4) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4; + else if(encoder->protected_->max_lpc_order < 8) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8; + else if(encoder->protected_->max_lpc_order < 12) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12; + else if(encoder->protected_->max_lpc_order < 16) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16; + else + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; + } +# endif + +# ifdef FLAC__SSE2_SUPPORTED + if(encoder->private_->cpuinfo.ia32.sse2) { + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse2; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2; + } +# endif +# ifdef FLAC__SSE4_1_SUPPORTED + if(encoder->private_->cpuinfo.ia32.sse41) { + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_sse41; + } +# endif +# ifdef FLAC__AVX2_SUPPORTED + if(encoder->private_->cpuinfo.ia32.avx2) { + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2; + } +# endif + +# ifdef FLAC__SSE2_SUPPORTED + if (encoder->private_->cpuinfo.ia32.sse2) { + encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_sse2; + encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_sse2; + } +# endif +# ifdef FLAC__SSSE3_SUPPORTED + if (encoder->private_->cpuinfo.ia32.ssse3) { + encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_ssse3; + encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_ssse3; + } +# endif +# endif /* FLAC__HAS_X86INTRIN */ +# elif defined FLAC__CPU_X86_64 + FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_X86_64); +# ifdef FLAC__HAS_X86INTRIN +# ifdef FLAC__SSE_SUPPORTED + if(encoder->protected_->max_lpc_order < 4) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_4; + else if(encoder->protected_->max_lpc_order < 8) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_8; + else if(encoder->protected_->max_lpc_order < 12) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_12; + else if(encoder->protected_->max_lpc_order < 16) + encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_intrin_sse_lag_16; +# endif + +# ifdef FLAC__SSE2_SUPPORTED + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_sse2; +# endif +# ifdef FLAC__SSE4_1_SUPPORTED + if(encoder->private_->cpuinfo.x86.sse41) { + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_sse41; + } +# endif +# ifdef FLAC__AVX2_SUPPORTED + if(encoder->private_->cpuinfo.x86.avx2) { + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_16bit = FLAC__lpc_compute_residual_from_qlp_coefficients_16_intrin_avx2; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients = FLAC__lpc_compute_residual_from_qlp_coefficients_intrin_avx2; + encoder->private_->local_lpc_compute_residual_from_qlp_coefficients_64bit = FLAC__lpc_compute_residual_from_qlp_coefficients_wide_intrin_avx2; + } +# endif + +# ifdef FLAC__SSE2_SUPPORTED + encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_sse2; + encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_sse2; +# endif +# ifdef FLAC__SSSE3_SUPPORTED + if (encoder->private_->cpuinfo.x86.ssse3) { + encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_intrin_ssse3; + encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide_intrin_ssse3; + } +# endif +# endif /* FLAC__HAS_X86INTRIN */ +# endif /* FLAC__CPU_... */ } # endif /* !FLAC__NO_ASM */ #endif /* !FLAC__INTEGER_ONLY_LIBRARY */ +#if !defined FLAC__NO_ASM && defined FLAC__HAS_X86INTRIN + if(encoder->private_->cpuinfo.use_asm) { +# if defined FLAC__CPU_IA32 +# ifdef FLAC__SSE2_SUPPORTED + if(encoder->private_->cpuinfo.ia32.sse2) + encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_sse2; +# endif +# ifdef FLAC__SSSE3_SUPPORTED + if(encoder->private_->cpuinfo.ia32.ssse3) + encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_ssse3; +# endif +# ifdef FLAC__AVX2_SUPPORTED + if(encoder->private_->cpuinfo.ia32.avx2) + encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_avx2; +# endif +# elif defined FLAC__CPU_X86_64 +# ifdef FLAC__SSE2_SUPPORTED + encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_sse2; +# endif +# ifdef FLAC__SSSE3_SUPPORTED + if(encoder->private_->cpuinfo.x86.ssse3) + encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_ssse3; +# endif +# ifdef FLAC__AVX2_SUPPORTED + if(encoder->private_->cpuinfo.x86.avx2) + encoder->private_->local_precompute_partition_info_sums = FLAC__precompute_partition_info_sums_intrin_avx2; +# endif +# endif /* FLAC__CPU_... */ + } +#endif /* !FLAC__NO_ASM && FLAC__HAS_X86INTRIN */ /* finally override based on wide-ness if necessary */ if(encoder->private_->use_wide_by_block) { - encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_wide; + encoder->private_->local_fixed_compute_best_predictor = encoder->private_->local_fixed_compute_best_predictor_wide; } /* set state to OK; from here on, errors are fatal and we'll override the state then */ @@ -1152,7 +1282,7 @@ static FLAC__StreamEncoderInitStatus init_FILE_internal_( FLAC__StreamEncoder *encoder, FILE *file, FLAC__StreamEncoderProgressCallback progress_callback, - void * /*client_data*/, + void *client_data, FLAC__bool is_ogg ) { @@ -1178,6 +1308,13 @@ static FLAC__StreamEncoderInitStatus init_FILE_internal_( if(file == stdout) file = get_binary_stdout_(); /* just to be safe */ +#ifdef _WIN32 + /* + * Windows can suffer quite badly from disk fragmentation. This can be + * reduced significantly by setting the output buffer size to be 10MB. + */ + setvbuf(file, NULL, _IOFBF, 10*1024*1024); +#endif encoder->private_->file = file; encoder->private_->progress_callback = progress_callback; @@ -1447,11 +1584,10 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_compression_level(FLAC__StreamEncod ok &= FLAC__stream_encoder_set_do_mid_side_stereo (encoder, compression_levels_[value].do_mid_side_stereo); ok &= FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, compression_levels_[value].loose_mid_side_stereo); #ifndef FLAC__INTEGER_ONLY_LIBRARY -#if 0 - /* was: */ +#if 1 ok &= FLAC__stream_encoder_set_apodization (encoder, compression_levels_[value].apodization); - /* but it's too hard to specify the string in a locale-specific way */ #else + /* equivalent to -A tukey(0.5) */ encoder->protected_->num_apodizations = 1; encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY; encoder->protected_->apodizations[0].parameters.tukey.p = 0.5; @@ -1555,6 +1691,48 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_apodization(FLAC__StreamEncoder *en encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY; } } + else if(n>15 && 0 == strncmp("partial_tukey(" , specification, 14)) { + FLAC__int32 tukey_parts = (FLAC__int32)strtod(specification+14, 0); + const char *si_1 = strchr(specification, '/'); + FLAC__real overlap = si_1?flac_min((FLAC__real)strtod(si_1+1, 0),0.99f):0.1f; + FLAC__real overlap_units = 1.0f/(1.0f - overlap) - 1.0f; + const char *si_2 = strchr((si_1?(si_1+1):specification), '/'); + FLAC__real tukey_p = si_2?(FLAC__real)strtod(si_2+1, 0):0.2f; + + if (tukey_parts <= 1) { + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.tukey.p = tukey_p; + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY; + }else if (encoder->protected_->num_apodizations + tukey_parts < 32){ + FLAC__int32 m; + for(m = 0; m < tukey_parts; m++){ + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.p = tukey_p; + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.start = m/(tukey_parts+overlap_units); + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.end = (m+1+overlap_units)/(tukey_parts+overlap_units); + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_PARTIAL_TUKEY; + } + } + } + else if(n>16 && 0 == strncmp("punchout_tukey(" , specification, 15)) { + FLAC__int32 tukey_parts = (FLAC__int32)strtod(specification+15, 0); + const char *si_1 = strchr(specification, '/'); + FLAC__real overlap = si_1?flac_min((FLAC__real)strtod(si_1+1, 0),0.99f):0.2f; + FLAC__real overlap_units = 1.0f/(1.0f - overlap) - 1.0f; + const char *si_2 = strchr((si_1?(si_1+1):specification), '/'); + FLAC__real tukey_p = si_2?(FLAC__real)strtod(si_2+1, 0):0.2f; + + if (tukey_parts <= 1) { + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.tukey.p = tukey_p; + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_TUKEY; + }else if (encoder->protected_->num_apodizations + tukey_parts < 32){ + FLAC__int32 m; + for(m = 0; m < tukey_parts; m++){ + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.p = tukey_p; + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.start = m/(tukey_parts+overlap_units); + encoder->protected_->apodizations[encoder->protected_->num_apodizations].parameters.multiple_tukey.end = (m+1+overlap_units)/(tukey_parts+overlap_units); + encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_PUNCHOUT_TUKEY; + } + } + } else if(n==5 && 0 == strncmp("welch" , specification, n)) encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_WELCH; if (encoder->protected_->num_apodizations == 32) @@ -2236,8 +2414,8 @@ FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_blocksize) ok = true; - /* WATCHOUT: FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx() - * requires that the input arrays (in our case the integer signals) + /* WATCHOUT: FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx() and ..._intrin_sse2() + * require that the input arrays (in our case the integer signals) * have a buffer of up to 3 zeroes in front (at negative indices) for * alignment purposes; we use 4 in front to keep the data well-aligned. */ @@ -2334,6 +2512,12 @@ FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_blocksize) case FLAC__APODIZATION_TUKEY: FLAC__window_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.tukey.p); break; + case FLAC__APODIZATION_PARTIAL_TUKEY: + FLAC__window_partial_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.multiple_tukey.p, encoder->protected_->apodizations[i].parameters.multiple_tukey.start, encoder->protected_->apodizations[i].parameters.multiple_tukey.end); + break; + case FLAC__APODIZATION_PUNCHOUT_TUKEY: + FLAC__window_punchout_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.multiple_tukey.p, encoder->protected_->apodizations[i].parameters.multiple_tukey.start, encoder->protected_->apodizations[i].parameters.multiple_tukey.end); + break; case FLAC__APODIZATION_WELCH: FLAC__window_welch(encoder->private_->window[i], new_blocksize); break; @@ -3165,7 +3349,7 @@ FLAC__bool process_subframe_( #endif #ifndef FLAC__INTEGER_ONLY_LIBRARY FLAC__double lpc_residual_bits_per_sample; - FLAC__real autoc[FLAC__MAX_LPC_ORDER+1]; /* WATCHOUT: the size is important even though encoder->protected_->max_lpc_order might be less; some asm routines need all the space */ + FLAC__real autoc[FLAC__MAX_LPC_ORDER+1]; /* WATCHOUT: the size is important even though encoder->protected_->max_lpc_order might be less; some asm and x86 intrinsic routines need all the space */ FLAC__double lpc_error[FLAC__MAX_LPC_ORDER]; unsigned min_lpc_order, max_lpc_order, lpc_order; unsigned min_qlp_coeff_precision, max_qlp_coeff_precision, qlp_coeff_precision; @@ -3318,9 +3502,9 @@ FLAC__bool process_subframe_( } if(encoder->protected_->do_qlp_coeff_prec_search) { min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION; - /* try to ensure a 32-bit datapath throughout for 16bps(+1bps for side channel) or less */ - if(subframe_bps <= 17) { - max_qlp_coeff_precision = flac_min(32 - subframe_bps - lpc_order, FLAC__MAX_QLP_COEFF_PRECISION); + /* try to keep qlp coeff precision such that only 32-bit math is required for decode of <=16bps streams */ + if(subframe_bps <= 16) { + max_qlp_coeff_precision = flac_min(32 - subframe_bps - FLAC__bitmath_ilog2(lpc_order), FLAC__MAX_QLP_COEFF_PRECISION); max_qlp_coeff_precision = flac_max(max_qlp_coeff_precision, min_qlp_coeff_precision); } else @@ -3556,7 +3740,7 @@ unsigned evaluate_lpc_subframe_( FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents ) { - FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; + FLAC__int32 qlp_coeff[FLAC__MAX_LPC_ORDER]; /* WATCHOUT: the size is important; some x86 intrinsic routines need more than lpc order elements */ unsigned i, residual_bits, estimate; int quantization, ret; const unsigned residual_samples = blocksize - order; @@ -3671,7 +3855,7 @@ unsigned find_best_partition_order_( max_partition_order = FLAC__format_get_max_rice_partition_order_from_blocksize_limited_max_and_predictor_order(max_partition_order, blocksize, predictor_order); min_partition_order = flac_min(min_partition_order, max_partition_order); - precompute_partition_info_sums_(residual, abs_residual_partition_sums, residual_samples, predictor_order, min_partition_order, max_partition_order, bps); + private_->local_precompute_partition_info_sums(residual, abs_residual_partition_sums, residual_samples, predictor_order, min_partition_order, max_partition_order, bps); if(do_escape_coding) precompute_partition_info_escapes_(residual, raw_bits_per_partition, residual_samples, predictor_order, min_partition_order, max_partition_order); @@ -3743,17 +3927,6 @@ unsigned find_best_partition_order_( return best_residual_bits; } -#if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && defined FLAC__HAS_NASM -extern void precompute_partition_info_sums_32bit_asm_ia32_( - const FLAC__int32 residual[], - FLAC__uint64 abs_residual_partition_sums[], - unsigned blocksize, - unsigned predictor_order, - unsigned min_partition_order, - unsigned max_partition_order -); -#endif - void precompute_partition_info_sums_( const FLAC__int32 residual[], FLAC__uint64 abs_residual_partition_sums[], @@ -3769,21 +3942,12 @@ void precompute_partition_info_sums_( FLAC__ASSERT(default_partition_samples > predictor_order); -#if defined(FLAC__CPU_IA32) && !defined FLAC__NO_ASM && defined FLAC__HAS_NASM - /* slightly pessimistic but still catches all common cases */ - /* WATCHOUT: "+ bps" is an assumption that the average residual magnitude will not be more than "bps" bits */ - if(FLAC__bitmath_ilog2(default_partition_samples) + bps < 32) { - precompute_partition_info_sums_32bit_asm_ia32_(residual, abs_residual_partition_sums, residual_samples + predictor_order, predictor_order, min_partition_order, max_partition_order); - return; - } -#endif - /* first do max_partition_order */ { unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order); - /* slightly pessimistic but still catches all common cases */ - /* WATCHOUT: "+ bps" is an assumption that the average residual magnitude will not be more than "bps" bits */ - if(FLAC__bitmath_ilog2(default_partition_samples) + bps < 32) { + /* WATCHOUT: "+ bps + FLAC__MAX_EXTRA_RESIDUAL_BPS" is the maximum + * assumed size of the average residual magnitude */ + if(FLAC__bitmath_ilog2(default_partition_samples) + bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < 32) { FLAC__uint32 abs_residual_partition_sum; for(partition = residual_sample = 0; partition < partitions; partition++) { @@ -4027,8 +4191,35 @@ FLAC__bool set_partitioned_rice_( * in the partition, so the actual mean is * mean/partition_samples */ +#if 0 /* old simple code */ for(rice_parameter = 0, k = partition_samples; k < mean; rice_parameter++, k <<= 1) ; +#else +#if defined FLAC__CPU_X86_64 /* and other 64-bit arch, too */ + if(mean <= 0x80000000/512) { /* 512: more or less optimal for both 16- and 24-bit input */ +#else + if(mean <= 0x80000000/8) { /* 32-bit arch: use 32-bit math if possible */ +#endif + FLAC__uint32 k2, mean2 = (FLAC__uint32) mean; + rice_parameter = 0; k2 = partition_samples; + while(k2*8 < mean2) { /* requires: mean <= (2^31)/8 */ + rice_parameter += 4; k2 <<= 4; /* tuned for 16-bit input */ + } + while(k2 < mean2) { /* requires: mean <= 2^31 */ + rice_parameter++; k2 <<= 1; + } + } + else { + rice_parameter = 0; k = partition_samples; + if(mean <= FLAC__U64L(0x8000000000000000)/128) /* usually mean is _much_ smaller than this value */ + while(k*128 < mean) { /* requires: mean <= (2^63)/128 */ + rice_parameter += 8; k <<= 8; /* tuned for 24-bit input */ + } + while(k < mean) { /* requires: mean <= 2^63 */ + rice_parameter++; k <<= 1; + } + } +#endif if(rice_parameter >= rice_parameter_limit) { #ifdef DEBUG_VERBOSE fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1); diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder_framing.c b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder_framing.c index 41efca5..6d57006 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder_framing.c +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/stream_encoder_framing.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/window_flac.c b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/window_flac.c index c99d5b4..dc341a6 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/window_flac.c +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/libFLAC/window_flac.c @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2006-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -30,7 +30,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#if HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H # include #endif @@ -41,11 +41,6 @@ #ifndef FLAC__INTEGER_ONLY_LIBRARY -#ifndef M_PI -/* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */ -#define M_PI 3.14159265358979323846 -#endif - void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L) { @@ -62,7 +57,7 @@ void FLAC__window_bartlett(FLAC__real *window, const FLAC__int32 L) for (n = 0; n <= L/2-1; n++) window[n] = 2.0f * n / (float)N; for (; n <= N; n++) - window[n] = 2.0f - 2.0f * (N-n) / (float)N; + window[n] = 2.0f - 2.0f * n / (float)N; } } @@ -72,7 +67,7 @@ void FLAC__window_bartlett_hann(FLAC__real *window, const FLAC__int32 L) FLAC__int32 n; for (n = 0; n < L; n++) - window[n] = (FLAC__real)(0.62f - 0.48f * fabs((float)n/(float)N+0.5f) + 0.38f * cos(2.0f * M_PI * ((float)n/(float)N+0.5f))); + window[n] = (FLAC__real)(0.62f - 0.48f * fabs((float)n/(float)N-0.5f) - 0.38f * cos(2.0f * M_PI * ((float)n/(float)N))); } void FLAC__window_blackman(FLAC__real *window, const FLAC__int32 L) @@ -177,16 +172,16 @@ void FLAC__window_triangle(FLAC__real *window, const FLAC__int32 L) FLAC__int32 n; if (L & 1) { - for (n = 1; n <= L+1/2; n++) + for (n = 1; n <= (L+1)/2; n++) window[n-1] = 2.0f * n / ((float)L + 1.0f); for (; n <= L; n++) - window[n-1] = - (float)(2 * (L - n + 1)) / ((float)L + 1.0f); + window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f); } else { for (n = 1; n <= L/2; n++) - window[n-1] = 2.0f * n / (float)L; + window[n-1] = 2.0f * n / ((float)L + 1.0f); for (; n <= L; n++) - window[n-1] = ((float)(2 * (L - n)) + 1.0f) / (float)L; + window[n-1] = (float)(2 * (L - n + 1)) / ((float)L + 1.0f); } } @@ -211,6 +206,66 @@ void FLAC__window_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__rea } } +void FLAC__window_partial_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end) +{ + const FLAC__int32 start_n = (FLAC__int32)(start * L); + const FLAC__int32 end_n = (FLAC__int32)(end * L); + const FLAC__int32 N = end_n - start_n; + FLAC__int32 Np, n, i; + + if (p <= 0.0f) + FLAC__window_partial_tukey(window, L, 0.05f, start, end); + else if (p >= 1.0f) + FLAC__window_partial_tukey(window, L, 0.95f, start, end); + else { + + Np = (FLAC__int32)(p / 2.0f * N); + + for (n = 0; n < start_n && n < L; n++) + window[n] = 0.0f; + for (i = 1; n < (start_n+Np) && n < L; n++, i++) + window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np)); + for (; n < (end_n-Np) && n < L; n++) + window[n] = 1.0f; + for (i = Np; n < end_n && n < L; n++, i--) + window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Np)); + for (; n < L; n++) + window[n] = 0.0f; + } +} + +void FLAC__window_punchout_tukey(FLAC__real *window, const FLAC__int32 L, const FLAC__real p, const FLAC__real start, const FLAC__real end) +{ + const FLAC__int32 start_n = (FLAC__int32)(start * L); + const FLAC__int32 end_n = (FLAC__int32)(end * L); + FLAC__int32 Ns, Ne, n, i; + + if (p <= 0.0f) + FLAC__window_punchout_tukey(window, L, 0.05f, start, end); + else if (p >= 1.0f) + FLAC__window_punchout_tukey(window, L, 0.95f, start, end); + else { + + Ns = (FLAC__int32)(p / 2.0f * start_n); + Ne = (FLAC__int32)(p / 2.0f * (L - end_n)); + + for (n = 0, i = 1; n < Ns && n < L; n++, i++) + window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns)); + for (; n < start_n-Ns && n < L; n++) + window[n] = 1.0f; + for (i = Ns; n < start_n && n < L; n++, i--) + window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ns)); + for (; n < end_n && n < L; n++) + window[n] = 0.0f; + for (i = 1; n < end_n+Ne && n < L; n++, i++) + window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne)); + for (; n < L - (Ne) && n < L; n++) + window[n] = 1.0f; + for (i = Ne; n < L; n++, i--) + window[n] = (FLAC__real)(0.5f - 0.5f * cos(M_PI * i / Ne)); + } +} + void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L) { const FLAC__int32 N = L - 1; diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/metadata.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/metadata.h index 18bf6d1..02cfc32 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/metadata.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/metadata.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2001-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -500,7 +500,7 @@ FLAC_API FLAC__MetadataType FLAC__metadata_simple_iterator_get_block_type(const * \retval unsigned * The length of the metadata block at the current iterator position. * The is same length as that in the - * metadata block header, + * metadata block header, * i.e. the length of the metadata body that follows the header. */ FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator); diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/ordinals.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/ordinals.h index c9466c5..0bab9c2 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/ordinals.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/ordinals.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/stream_decoder.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/stream_decoder.h index be402c8..50cd754 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/stream_decoder.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/stream_decoder.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/stream_encoder.h b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/stream_encoder.h index f0fcab5..646efb7 100644 --- a/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/stream_encoder.h +++ b/JuceLibraryCode/modules/juce_audio_formats/codecs/flac/stream_encoder.h @@ -1,6 +1,6 @@ /* libFLAC - Free Lossless Audio Codec library * Copyright (C) 2000-2009 Josh Coalson - * Copyright (C) 2011-2013 Xiph.Org Foundation + * Copyright (C) 2011-2014 Xiph.Org Foundation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -830,28 +830,28 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_sample_rate(FLAC__StreamEncoder *en * The actual values set for each level are: * * - * + * + * + * + * + * + * + * + * + * + * + * * - * - * - * - * - * - * - * - * - * + * + * + * + * + * + * + * + * + * *
level - * do mid-side stereo - * loose mid-side stereo - * apodization - * max lpc order - * qlp coeff precision - * qlp coeff prec search - * escape coding - * exhaustive model search - * min residual partition order - * max residual partition order - * rice parameter search dist + * leveldo mid-side stereoloose mid-side stereoapodizationmax lpc orderqlp coeff precisionqlp coeff prec searchescape codingexhaustive model searchmin residual partition ordermax residual partition orderrice parameter search dist
0 false false tukey(0.5) 0 0 false false false 0 3 0
1 true true tukey(0.5) 0 0 false false false 0 3 0
2 true false tukey(0.5) 0 0 false false false 0 3 0
3 false false tukey(0.5) 6 0 false false false 0 4 0
4 true true tukey(0.5) 8 0 false false false 0 4 0
5 true false tukey(0.5) 8 0 false false false 0 5 0
6 true false tukey(0.5) 8 0 false false false 0 6 0
7 true false tukey(0.5) 8 0 false false true 0 6 0
8 true false tukey(0.5) 12 0 false false true 0 6 0
0 false false tukey(0.5) 0 0 false false false 0 3 0
1 true true tukey(0.5) 0 0 false false false 0 3 0
2 true false tukey(0.5) 0 0 false false false 0 3 0
3 false false tukey(0.5) 6 0 false false false 0 4 0
4 true true tukey(0.5) 8 0 false false false 0 4 0
5 true false tukey(0.5) 8 0 false false false 0 5 0
6 true false tukey(0.5);partial_tukey(2) 8 0 false false false 0 6 0
7 true false tukey(0.5);partial_tukey(2) 12 0 false false false 0 6 0
8 true false tukey(0.5);partial_tukey(2);punchout_tukey(3) 12 0 false false false 0 6 0
* * \default \c 5 @@ -920,7 +920,8 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamE * The available functions are \c bartlett, \c bartlett_hann, * \c blackman, \c blackman_harris_4term_92db, \c connes, \c flattop, * \c gauss(STDDEV), \c hamming, \c hann, \c kaiser_bessel, \c nuttall, - * \c rectangle, \c triangle, \c tukey(P), \c welch. + * \c rectangle, \c triangle, \c tukey(P), \c partial_tukey(n[/ov[/P]]), + * \c punchout_tukey(n[/ov[/P]]), \c welch. * * For \c gauss(STDDEV), STDDEV specifies the standard deviation * (0releaseSamples > 0) releaseDelta = (float) (-pitchRatio / sound->releaseSamples); else - releaseDelta = 0.0f; + releaseDelta = -1.0f; } else { diff --git a/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp b/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp index a741626..266a93e 100644 --- a/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp +++ b/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp @@ -364,7 +364,6 @@ class VST3HostContext : public Vst::IComponentHandler, // From VST V3.0.0 public Vst::IComponentHandler3, // From VST V3.5.0 (also very well named!) public Vst::IContextMenuTarget, public Vst::IHostApplication, - public Vst::IParamValueQueue, public Vst::IUnitHandler { public: @@ -684,31 +683,6 @@ public: return kNotImplemented; } - //============================================================================== - Vst::ParamID PLUGIN_API getParameterId() override - { - jassertfalse; - return 0; - } - - Steinberg::int32 PLUGIN_API getPointCount() override - { - jassertfalse; - return 0; - } - - tresult PLUGIN_API getPoint (Steinberg::int32, Steinberg::int32&, Vst::ParamValue&) override - { - jassertfalse; - return kResultFalse; - } - - tresult PLUGIN_API addPoint (Steinberg::int32, Vst::ParamValue, Steinberg::int32&) override - { - jassertfalse; - return kResultFalse; - } - //============================================================================== tresult PLUGIN_API notifyUnitSelection (Vst::UnitID) override { @@ -736,7 +710,6 @@ public: TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IComponentHandler3) TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IContextMenuTarget) TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IHostApplication) - TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IParamValueQueue) TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IUnitHandler) TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (iid, FUnknown, Vst::IComponentHandler) @@ -2052,6 +2025,100 @@ public: (void) sizeInBytes; } + //============================================================================== + // NB: this class and its subclasses must be public to avoid problems in + // DLL builds under MSVC. + class ParameterChangeList : public Vst::IParameterChanges + { + public: + ParameterChangeList() {} + virtual ~ParameterChangeList() {} + + JUCE_DECLARE_VST3_COM_REF_METHODS + JUCE_DECLARE_VST3_COM_QUERY_METHODS + + Steinberg::int32 PLUGIN_API getParameterCount() override { return (Steinberg::int32) queues.size(); } + Vst::IParamValueQueue* PLUGIN_API getParameterData (Steinberg::int32 index) override { return queues[(int) index]; } + + Vst::IParamValueQueue* PLUGIN_API addParameterData (const Vst::ParamID& id, Steinberg::int32& index) override + { + for (int i = queues.size(); --i >= 0;) + { + if (queues.getUnchecked (i)->getParameterId() == id) + { + index = (Steinberg::int32) i; + return queues.getUnchecked (i); + } + } + + ParamValueQueue* q = queues.add (new ParamValueQueue (id)); + index = getParameterCount() - 1; + return q; + } + + struct ParamValueQueue : public Vst::IParamValueQueue + { + ParamValueQueue (Vst::ParamID parameterID) : paramID (parameterID) + { + points.ensureStorageAllocated (1024); + } + + virtual ~ParamValueQueue() {} + + JUCE_DECLARE_VST3_COM_REF_METHODS + JUCE_DECLARE_VST3_COM_QUERY_METHODS + + Steinberg::Vst::ParamID PLUGIN_API getParameterId() override { return paramID; } + Steinberg::int32 PLUGIN_API getPointCount() override { return (Steinberg::int32) points.size(); } + + Steinberg::tresult PLUGIN_API getPoint (Steinberg::int32 index, + Steinberg::int32& sampleOffset, + Steinberg::Vst::ParamValue& value) override + { + if (isPositiveAndBelow ((int) index, points.size())) + { + ParamPoint e (points.getUnchecked ((int) index)); + sampleOffset = e.sampleOffset; + value = e.value; + return kResultTrue; + } + + sampleOffset = -1; + value = 0.0; + return kResultFalse; + } + + Steinberg::tresult PLUGIN_API addPoint (Steinberg::int32 sampleOffset, + Steinberg::Vst::ParamValue value, + Steinberg::int32& index) override + { + // XXX this may need to be made thread-safe.. + ParamPoint p = { sampleOffset, value }; + points.add (p); + index = (Steinberg::int32) points.size(); + return kResultTrue; + } + + private: + struct ParamPoint + { + Steinberg::int32 sampleOffset; + Steinberg::Vst::ParamValue value; + }; + + Atomic refCount; + const Vst::ParamID paramID; + Array points; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParamValueQueue) + }; + + Atomic refCount; + OwnedArray queues; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParameterChangeList) + }; + private: //============================================================================== VST3ModuleHandle::Ptr module; @@ -2122,35 +2189,6 @@ private: return stream; } - //============================================================================== - class ParameterChangeList : public Vst::IParameterChanges - { - public: - ParameterChangeList() {} - virtual ~ParameterChangeList() {} - - JUCE_DECLARE_VST3_COM_REF_METHODS - JUCE_DECLARE_VST3_COM_QUERY_METHODS - - Steinberg::int32 PLUGIN_API getParameterCount() override { return 0; } - - Vst::IParamValueQueue* PLUGIN_API getParameterData (Steinberg::int32) override - { - return nullptr; - } - - Vst::IParamValueQueue* PLUGIN_API addParameterData (const Vst::ParamID&, Steinberg::int32& index) override - { - index = 0; - return nullptr; - } - - private: - Atomic refCount; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParameterChangeList) - }; - ComSmartPtr inputParameterChanges, outputParameterChanges; ComSmartPtr midiInputs, midiOutputs; Vst::ProcessContext timingInfo; //< Only use this in processBlock()! diff --git a/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp b/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp index 5509e2c..3859061 100644 --- a/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp +++ b/JuceLibraryCode/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp @@ -135,7 +135,14 @@ namespace char chunk[8]; // variable }; - static VstInt32 fxbName (const char* name) noexcept { return (VstInt32) ByteOrder::bigEndianInt (name); } + // Compares a magic value in either endianness. + static bool compareMagic (VstInt32 magic, const char* name) noexcept + { + return magic == (VstInt32) ByteOrder::littleEndianInt (name) + || magic == (VstInt32) ByteOrder::bigEndianInt (name); + } + + static VstInt32 fxbName (const char* name) noexcept { return (VstInt32) ByteOrder::littleEndianInt (name); } static VstInt32 fxbSwap (const VstInt32 x) noexcept { return (VstInt32) ByteOrder::swapIfLittleEndian ((uint32) x); } static float fxbSwapFloat (const float x) noexcept @@ -1013,12 +1020,12 @@ public: if (position.isLooping) { vstHostTime.cycleStartPos = position.ppqLoopStart; - vstHostTime.cycleEndPos = position.ppqLoopEnd; - vstHostTime.flags |= kVstCyclePosValid; + vstHostTime.cycleEndPos = position.ppqLoopEnd; + vstHostTime.flags |= (kVstCyclePosValid | kVstTransportCycleActive); } else { - vstHostTime.flags &= ~kVstCyclePosValid; + vstHostTime.flags &= ~(kVstCyclePosValid | kVstTransportCycleActive); } } @@ -1432,11 +1439,10 @@ public: const fxSet* const set = (const fxSet*) data; - if ((set->chunkMagic != fxbName ("CcnK") && set->chunkMagic != fxbName ("KncC")) - || fxbSwap (set->version) > fxbVersionNum) + if ((! compareMagic (set->chunkMagic, "CcnK")) || fxbSwap (set->version) > fxbVersionNum) return false; - if (set->fxMagic == fxbName ("FxBk")) + if (compareMagic (set->fxMagic, "FxBk")) { // bank of programs if (fxbSwap (set->numPrograms) >= 0) @@ -1472,12 +1478,12 @@ public: return false; } } - else if (set->fxMagic == fxbName ("FxCk")) + else if (compareMagic (set->fxMagic, "FxCk")) { // single program const fxProgram* const prog = (const fxProgram*) data; - if (prog->chunkMagic != fxbName ("CcnK")) + if (! compareMagic (prog->chunkMagic, "CcnK")) return false; changeProgramName (getCurrentProgram(), prog->prgName); @@ -1485,7 +1491,7 @@ public: for (int i = 0; i < fxbSwap (prog->numParams); ++i) setParameter (i, fxbSwapFloat (prog->params[i])); } - else if (set->fxMagic == fxbName ("FBCh") || set->fxMagic == fxbName ("hCBF")) + else if (compareMagic (set->fxMagic, "FBCh")) { // non-preset chunk const fxChunkSet* const cset = (const fxChunkSet*) data; @@ -1495,7 +1501,7 @@ public: setChunkData (cset->chunk, fxbSwap (cset->chunkSize), false); } - else if (set->fxMagic == fxbName ("FPCh") || set->fxMagic == fxbName ("hCPF")) + else if (compareMagic (set->fxMagic, "FPCh")) { // preset chunk const fxProgramSet* const cset = (const fxProgramSet*) data; @@ -1671,7 +1677,8 @@ private: bool restoreProgramSettings (const fxProgram* const prog) { - if (prog->chunkMagic == fxbName ("CcnK") && prog->fxMagic == fxbName ("FxCk")) + if (compareMagic (prog->chunkMagic, "CcnK") + && compareMagic (prog->fxMagic, "FxCk")) { changeProgramName (getCurrentProgram(), prog->prgName); diff --git a/JuceLibraryCode/modules/juce_audio_processors/juce_module_info b/JuceLibraryCode/modules/juce_audio_processors/juce_module_info index 40a0d87..60d04ec 100644 --- a/JuceLibraryCode/modules/juce_audio_processors/juce_module_info +++ b/JuceLibraryCode/modules/juce_audio_processors/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_processors", "name": "JUCE audio plugin hosting classes", - "version": "3.0.8", + "version": "3.1.1", "description": "Classes for loading and playing VST, AU, or internally-generated audio processors.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/JuceLibraryCode/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp b/JuceLibraryCode/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp index c94411d..196e9ac 100644 --- a/JuceLibraryCode/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp +++ b/JuceLibraryCode/modules/juce_audio_processors/processors/juce_GenericAudioProcessorEditor.cpp @@ -67,7 +67,7 @@ public: if (paramHasChanged) { refresh(); - startTimer (1000 / 50); + startTimerHz (50); } else { diff --git a/JuceLibraryCode/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp b/JuceLibraryCode/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp index 589343f..c820f99 100644 --- a/JuceLibraryCode/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp +++ b/JuceLibraryCode/modules/juce_audio_utils/gui/juce_AudioThumbnail.cpp @@ -133,7 +133,7 @@ public: if (reader != nullptr) { if (levels.size() < (int) reader->numChannels) - levels.insertMultiple (0, Range(), (int) (reader->numChannels - levels.size())); + levels.insertMultiple (0, Range(), (int) reader->numChannels - levels.size()); reader->readMaxLevels (startSample, numSamples, levels.getRawDataPointer(), (int) reader->numChannels); @@ -240,7 +240,7 @@ private: for (int i = 0; i < numThumbSamps; ++i) { reader->readMaxLevels ((firstThumbIndex + i) * owner.samplesPerThumbSample, - owner.samplesPerThumbSample, levelsRead, numChannels); + owner.samplesPerThumbSample, levelsRead, (int) numChannels); for (int j = 0; j < (int) numChannels; ++j) levels[j][i].setFloat (levelsRead[j]); diff --git a/JuceLibraryCode/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp b/JuceLibraryCode/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp index fae07b7..9efad13 100644 --- a/JuceLibraryCode/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp +++ b/JuceLibraryCode/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp @@ -26,11 +26,8 @@ class MidiKeyboardUpDownButton : public Button { public: MidiKeyboardUpDownButton (MidiKeyboardComponent& comp, const int d) - : Button (String::empty), - owner (comp), - delta (d) + : Button (String::empty), owner (comp), delta (d) { - setOpaque (true); } void clicked() override @@ -60,8 +57,7 @@ private: }; //============================================================================== -MidiKeyboardComponent::MidiKeyboardComponent (MidiKeyboardState& s, - const Orientation o) +MidiKeyboardComponent::MidiKeyboardComponent (MidiKeyboardState& s, Orientation o) : state (s), xOffset (0), blackNoteLength (1), @@ -92,12 +88,12 @@ MidiKeyboardComponent::MidiKeyboardComponent (MidiKeyboardState& s, mouseOverNotes.insertMultiple (0, -1, 32); mouseDownNotes.insertMultiple (0, -1, 32); - setOpaque (true); + colourChanged(); setWantsKeyboardFocus (true); state.addListener (this); - startTimer (1000 / 20); + startTimerHz (20); } MidiKeyboardComponent::~MidiKeyboardComponent() @@ -169,6 +165,7 @@ void MidiKeyboardComponent::setScrollButtonsVisible (const bool newCanScroll) void MidiKeyboardComponent::colourChanged() { + setOpaque (findColour (whiteNoteColourId).isOpaque()); repaint(); } @@ -342,7 +339,7 @@ void MidiKeyboardComponent::repaintNote (const int noteNum) void MidiKeyboardComponent::paint (Graphics& g) { - g.fillAll (Colours::white.overlaidWith (findColour (whiteNoteColourId))); + g.fillAll (findColour (whiteNoteColourId)); const Colour lineColour (findColour (keySeparatorLineColourId)); const Colour textColour (findColour (textLabelColourId)); diff --git a/JuceLibraryCode/modules/juce_audio_utils/juce_audio_utils.cpp b/JuceLibraryCode/modules/juce_audio_utils/juce_audio_utils.cpp index f63682b..90c66cd 100644 --- a/JuceLibraryCode/modules/juce_audio_utils/juce_audio_utils.cpp +++ b/JuceLibraryCode/modules/juce_audio_utils/juce_audio_utils.cpp @@ -45,6 +45,7 @@ namespace juce #include "gui/juce_AudioThumbnail.cpp" #include "gui/juce_AudioThumbnailCache.cpp" #include "gui/juce_MidiKeyboardComponent.cpp" +#include "gui/juce_AudioAppComponent.cpp" #include "players/juce_AudioProcessorPlayer.cpp" } diff --git a/JuceLibraryCode/modules/juce_audio_utils/juce_audio_utils.h b/JuceLibraryCode/modules/juce_audio_utils/juce_audio_utils.h index b5f38f8..c9027d0 100644 --- a/JuceLibraryCode/modules/juce_audio_utils/juce_audio_utils.h +++ b/JuceLibraryCode/modules/juce_audio_utils/juce_audio_utils.h @@ -39,6 +39,7 @@ namespace juce #include "gui/juce_AudioThumbnail.h" #include "gui/juce_AudioThumbnailCache.h" #include "gui/juce_MidiKeyboardComponent.h" +#include "gui/juce_AudioAppComponent.h" #include "players/juce_AudioProcessorPlayer.h" } diff --git a/JuceLibraryCode/modules/juce_audio_utils/juce_module_info b/JuceLibraryCode/modules/juce_audio_utils/juce_module_info index 47dbf8b..3e92f42 100644 --- a/JuceLibraryCode/modules/juce_audio_utils/juce_module_info +++ b/JuceLibraryCode/modules/juce_audio_utils/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_audio_utils", "name": "JUCE extra audio utility classes", - "version": "3.0.8", + "version": "3.1.1", "description": "Classes for audio-related GUI and miscellaneous tasks.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/JuceLibraryCode/modules/juce_core/containers/juce_Array.h b/JuceLibraryCode/modules/juce_core/containers/juce_Array.h index 8e9cf3f..87a136e 100644 --- a/JuceLibraryCode/modules/juce_core/containers/juce_Array.h +++ b/JuceLibraryCode/modules/juce_core/containers/juce_Array.h @@ -474,7 +474,11 @@ public: numUsed += numberOfTimesToInsertIt; while (--numberOfTimesToInsertIt >= 0) - new (insertPos++) ElementType (newElement); + { + new (insertPos) ElementType (newElement); + ++insertPos; // NB: this increment is done separately from the + // new statement to avoid a compiler bug in VS2014 + } } } diff --git a/JuceLibraryCode/modules/juce_core/files/juce_DirectoryIterator.cpp b/JuceLibraryCode/modules/juce_core/files/juce_DirectoryIterator.cpp index 7d6dd4b..f2e09a6 100644 --- a/JuceLibraryCode/modules/juce_core/files/juce_DirectoryIterator.cpp +++ b/JuceLibraryCode/modules/juce_core/files/juce_DirectoryIterator.cpp @@ -73,64 +73,71 @@ bool DirectoryIterator::next() bool DirectoryIterator::next (bool* const isDirResult, bool* const isHiddenResult, int64* const fileSize, Time* const modTime, Time* const creationTime, bool* const isReadOnly) { - hasBeenAdvanced = true; - - if (subIterator != nullptr) + for (;;) { - if (subIterator->next (isDirResult, isHiddenResult, fileSize, modTime, creationTime, isReadOnly)) - return true; + hasBeenAdvanced = true; - subIterator = nullptr; - } - - String filename; - bool isDirectory, isHidden = false; - - while (fileFinder.next (filename, &isDirectory, - (isHiddenResult != nullptr || (whatToLookFor & File::ignoreHiddenFiles) != 0) ? &isHidden : nullptr, - fileSize, modTime, creationTime, isReadOnly)) - { - ++index; - - if (! filename.containsOnly (".")) + if (subIterator != nullptr) { - bool matches = false; - - if (isDirectory) - { - if (isRecursive && ((whatToLookFor & File::ignoreHiddenFiles) == 0 || ! isHidden)) - subIterator = new DirectoryIterator (File::createFileWithoutCheckingPath (path + filename), - true, wildCard, whatToLookFor); - - matches = (whatToLookFor & File::findDirectories) != 0; - } - else - { - matches = (whatToLookFor & File::findFiles) != 0; - } - - // if we're not relying on the OS iterator to do the wildcard match, do it now.. - if (matches && (isRecursive || wildCards.size() > 1)) - matches = fileMatches (wildCards, filename); - - if (matches && (whatToLookFor & File::ignoreHiddenFiles) != 0) - matches = ! isHidden; - - if (matches) - { - currentFile = File::createFileWithoutCheckingPath (path + filename); - if (isHiddenResult != nullptr) *isHiddenResult = isHidden; - if (isDirResult != nullptr) *isDirResult = isDirectory; - + if (subIterator->next (isDirResult, isHiddenResult, fileSize, modTime, creationTime, isReadOnly)) return true; - } - if (subIterator != nullptr) - return next (isDirResult, isHiddenResult, fileSize, modTime, creationTime, isReadOnly); + subIterator = nullptr; } - } - return false; + String filename; + bool isDirectory, isHidden = false, shouldContinue = false; + + while (fileFinder.next (filename, &isDirectory, + (isHiddenResult != nullptr || (whatToLookFor & File::ignoreHiddenFiles) != 0) ? &isHidden : nullptr, + fileSize, modTime, creationTime, isReadOnly)) + { + ++index; + + if (! filename.containsOnly (".")) + { + bool matches = false; + + if (isDirectory) + { + if (isRecursive && ((whatToLookFor & File::ignoreHiddenFiles) == 0 || ! isHidden)) + subIterator = new DirectoryIterator (File::createFileWithoutCheckingPath (path + filename), + true, wildCard, whatToLookFor); + + matches = (whatToLookFor & File::findDirectories) != 0; + } + else + { + matches = (whatToLookFor & File::findFiles) != 0; + } + + // if we're not relying on the OS iterator to do the wildcard match, do it now.. + if (matches && (isRecursive || wildCards.size() > 1)) + matches = fileMatches (wildCards, filename); + + if (matches && (whatToLookFor & File::ignoreHiddenFiles) != 0) + matches = ! isHidden; + + if (matches) + { + currentFile = File::createFileWithoutCheckingPath (path + filename); + if (isHiddenResult != nullptr) *isHiddenResult = isHidden; + if (isDirResult != nullptr) *isDirResult = isDirectory; + + return true; + } + + if (subIterator != nullptr) + { + shouldContinue = true; + break; + } + } + } + + if (! shouldContinue) + return false; + } } const File& DirectoryIterator::getFile() const diff --git a/JuceLibraryCode/modules/juce_core/files/juce_File.cpp b/JuceLibraryCode/modules/juce_core/files/juce_File.cpp index d5c520a..19d724b 100644 --- a/JuceLibraryCode/modules/juce_core/files/juce_File.cpp +++ b/JuceLibraryCode/modules/juce_core/files/juce_File.cpp @@ -219,6 +219,11 @@ bool File::setReadOnly (const bool shouldBeReadOnly, return setFileReadOnlyInternal (shouldBeReadOnly) && worked; } +bool File::setExecutePermission (bool shouldBeExecutable) const +{ + return setFileExecutableInternal (shouldBeExecutable); +} + bool File::deleteRecursively() const { bool worked = true; diff --git a/JuceLibraryCode/modules/juce_core/files/juce_File.h b/JuceLibraryCode/modules/juce_core/files/juce_File.h index 57d970f..522559a 100644 --- a/JuceLibraryCode/modules/juce_core/files/juce_File.h +++ b/JuceLibraryCode/modules/juce_core/files/juce_File.h @@ -348,6 +348,13 @@ public: bool setReadOnly (bool shouldBeReadOnly, bool applyRecursively = false) const; + /** Changes the execute-permissions of a file. + + @param shouldBeExecutable whether to add or remove execute-permission + @returns true if it manages to change the file's permissions. + */ + bool setExecutePermission (bool shouldBeExecutable) const; + /** Returns true if this file is a hidden or system file. The criteria for deciding whether a file is hidden are platform-dependent. */ @@ -968,6 +975,7 @@ private: bool setFileTimesInternal (int64 m, int64 a, int64 c) const; void getFileTimesInternal (int64& m, int64& a, int64& c) const; bool setFileReadOnlyInternal (bool) const; + bool setFileExecutableInternal (bool) const; }; #endif // JUCE_FILE_H_INCLUDED diff --git a/JuceLibraryCode/modules/juce_core/juce_module_info b/JuceLibraryCode/modules/juce_core/juce_module_info index 7fb2073..33eab6c 100644 --- a/JuceLibraryCode/modules/juce_core/juce_module_info +++ b/JuceLibraryCode/modules/juce_core/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_core", "name": "JUCE core classes", - "version": "3.0.8", + "version": "3.1.1", "description": "The essential set of basic JUCE classes, as required by all the other JUCE modules. Includes text, container, memory, threading and i/o functionality.", "website": "http://www.juce.com/juce", "license": "ISC Permissive", diff --git a/JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.cpp b/JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.cpp index 8cadfda..1b8f302 100644 --- a/JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.cpp +++ b/JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.cpp @@ -32,7 +32,7 @@ FileLogger::FileLogger (const File& file, : logFile (file) { if (maxInitialFileSizeBytes >= 0) - trimFileSize (maxInitialFileSizeBytes); + trimFileSize (logFile, maxInitialFileSizeBytes); if (! file.exists()) file.create(); // (to create the parent directories) @@ -57,23 +57,23 @@ void FileLogger::logMessage (const String& message) out << message << newLine; } -void FileLogger::trimFileSize (int64 maxFileSizeBytes) const +void FileLogger::trimFileSize (const File& file, int64 maxFileSizeBytes) { if (maxFileSizeBytes <= 0) { - logFile.deleteFile(); + file.deleteFile(); } else { - const int64 fileSize = logFile.getSize(); + const int64 fileSize = file.getSize(); if (fileSize > maxFileSizeBytes) { - TemporaryFile tempFile (logFile); + TemporaryFile tempFile (file); { FileOutputStream out (tempFile.getFile()); - FileInputStream in (logFile); + FileInputStream in (file); if (! (out.openedOk() && in.openedOk())) return; diff --git a/JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.h b/JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.h index 6be1668..09301b8 100644 --- a/JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.h +++ b/JuceLibraryCode/modules/juce_core/logging/juce_FileLogger.h @@ -121,13 +121,17 @@ public: // (implementation of the Logger virtual method) void logMessage (const String&); + //============================================================================== + /** This is a utility function which removes lines from the start of a text + file to make sure that its total size is below the given size. + */ + static void trimFileSize (const File& file, int64 maxFileSize); + private: //============================================================================== File logFile; CriticalSection logLock; - void trimFileSize (int64 maxFileSizeBytes) const; - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileLogger) }; diff --git a/JuceLibraryCode/modules/juce_core/maths/juce_Expression.cpp b/JuceLibraryCode/modules/juce_core/maths/juce_Expression.cpp index a18effa..632b90a 100644 --- a/JuceLibraryCode/modules/juce_core/maths/juce_Expression.cpp +++ b/JuceLibraryCode/modules/juce_core/maths/juce_Expression.cpp @@ -1162,9 +1162,9 @@ double Expression::Scope::evaluateFunction (const String& functionName, const do if (numParams == 1) { - if (functionName == "sin") return sin (parameters[0]); - if (functionName == "cos") return cos (parameters[0]); - if (functionName == "tan") return tan (parameters[0]); + if (functionName == "sin") return std::sin (parameters[0]); + if (functionName == "cos") return std::cos (parameters[0]); + if (functionName == "tan") return std::tan (parameters[0]); if (functionName == "abs") return std::abs (parameters[0]); } } diff --git a/JuceLibraryCode/modules/juce_core/maths/juce_NormalisableRange.h b/JuceLibraryCode/modules/juce_core/maths/juce_NormalisableRange.h index 800c616..56424a2 100644 --- a/JuceLibraryCode/modules/juce_core/maths/juce_NormalisableRange.h +++ b/JuceLibraryCode/modules/juce_core/maths/juce_NormalisableRange.h @@ -104,7 +104,7 @@ public: ValueType proportion = (v - start) / (end - start); if (skew != static_cast (1)) - proportion = pow (proportion, skew); + proportion = std::pow (proportion, skew); return proportion; } @@ -115,7 +115,7 @@ public: ValueType convertFrom0to1 (ValueType proportion) const noexcept { if (skew != static_cast (1) && proportion > ValueType()) - proportion = exp (log (proportion) / skew); + proportion = std::exp (std::log (proportion) / skew); return start + (end - start) * proportion; } diff --git a/JuceLibraryCode/modules/juce_core/native/juce_android_SystemStats.cpp b/JuceLibraryCode/modules/juce_core/native/juce_android_SystemStats.cpp index 8223b89..b012381 100644 --- a/JuceLibraryCode/modules/juce_core/native/juce_android_SystemStats.cpp +++ b/JuceLibraryCode/modules/juce_core/native/juce_android_SystemStats.cpp @@ -278,7 +278,7 @@ String SystemStats::getDisplayLanguage() { return getUserLanguage() + "-" + getU //============================================================================== void CPUInformation::initialise() noexcept { - numCpus = jmax (1, sysconf (_SC_NPROCESSORS_ONLN)); + numCpus = jmax (1, (int) sysconf (_SC_NPROCESSORS_ONLN)); } //============================================================================== diff --git a/JuceLibraryCode/modules/juce_core/native/juce_mac_Strings.mm b/JuceLibraryCode/modules/juce_core/native/juce_mac_Strings.mm index 862eb53..7a38b3d 100644 --- a/JuceLibraryCode/modules/juce_core/native/juce_mac_Strings.mm +++ b/JuceLibraryCode/modules/juce_core/native/juce_mac_Strings.mm @@ -32,17 +32,21 @@ String String::fromCFString (CFStringRef cfString) return String(); CFRange range = { 0, CFStringGetLength (cfString) }; - HeapBlock u ((size_t) range.length + 1); - CFStringGetCharacters (cfString, range, u); - u[range.length] = 0; + CFIndex bytesNeeded = 0; + CFStringGetBytes (cfString, range, kCFStringEncodingUTF8, 0, false, nullptr, 0, &bytesNeeded); - return String (CharPointer_UTF16 ((const CharPointer_UTF16::CharType*) u.getData())); + HeapBlock utf8 ((size_t) bytesNeeded + 1); + CFStringGetBytes (cfString, range, kCFStringEncodingUTF8, 0, false, utf8, bytesNeeded + 1, nullptr); + + return String (CharPointer_UTF8 ((const CharPointer_UTF8::CharType*) utf8.getData()), + CharPointer_UTF8 ((const CharPointer_UTF8::CharType*) utf8.getData() + bytesNeeded)); } CFStringRef String::toCFString() const { - CharPointer_UTF16 utf16 (toUTF16()); - return CFStringCreateWithCharacters (kCFAllocatorDefault, (const UniChar*) utf16.getAddress(), (CFIndex) utf16.length()); + const char* const utf8 = toRawUTF8(); + return CFStringCreateWithBytes (kCFAllocatorDefault, (const UInt8*) utf8, + (CFIndex) strlen (utf8), kCFStringEncodingUTF8, false); } String String::convertToPrecomposedUnicode() const @@ -72,7 +76,7 @@ String String::convertToPrecomposedUnicode() const { const size_t bytesNeeded = CharPointer_UTF16::getBytesRequiredFor (getCharPointer()); - HeapBlock tempOut; + HeapBlock tempOut; tempOut.calloc (bytesNeeded + 4); ByteCount bytesRead = 0; diff --git a/JuceLibraryCode/modules/juce_core/native/juce_posix_SharedCode.h b/JuceLibraryCode/modules/juce_core/native/juce_posix_SharedCode.h index 91785d6..c94d3a6 100644 --- a/JuceLibraryCode/modules/juce_core/native/juce_posix_SharedCode.h +++ b/JuceLibraryCode/modules/juce_core/native/juce_posix_SharedCode.h @@ -304,23 +304,33 @@ bool File::hasWriteAccess() const return false; } -bool File::setFileReadOnlyInternal (const bool shouldBeReadOnly) const +static bool setFileModeFlags (const String& fullPath, mode_t flags, bool shouldSet) noexcept { juce_statStruct info; if (! juce_stat (fullPath, info)) return false; - info.st_mode &= 0777; // Just permissions + info.st_mode &= 0777; - if (shouldBeReadOnly) - info.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); + if (shouldSet) + info.st_mode |= flags; else - // Give everybody write permission? - info.st_mode |= S_IWUSR | S_IWGRP | S_IWOTH; + info.st_mode &= ~flags; return chmod (fullPath.toUTF8(), info.st_mode) == 0; } +bool File::setFileReadOnlyInternal (bool shouldBeReadOnly) const +{ + // Hmm.. should we give global write permission or just the current user? + return setFileModeFlags (fullPath, S_IWUSR | S_IWGRP | S_IWOTH, ! shouldBeReadOnly); +} + +bool File::setFileExecutableInternal (bool shouldBeExecutable) const +{ + return setFileModeFlags (fullPath, S_IXUSR | S_IXGRP | S_IXOTH, shouldBeExecutable); +} + void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int64& creationTime) const { modificationTime = 0; @@ -328,11 +338,12 @@ void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int creationTime = 0; juce_statStruct info; + if (juce_stat (fullPath, info)) { - modificationTime = (int64) info.st_mtime * 1000; - accessTime = (int64) info.st_atime * 1000; - creationTime = (int64) info.st_ctime * 1000; + modificationTime = (int64) info.st_mtime * 1000; + accessTime = (int64) info.st_atime * 1000; + creationTime = (int64) info.st_ctime * 1000; } } diff --git a/JuceLibraryCode/modules/juce_core/native/juce_win32_Files.cpp b/JuceLibraryCode/modules/juce_core/native/juce_win32_Files.cpp index a77aa5a..b918cab 100644 --- a/JuceLibraryCode/modules/juce_core/native/juce_win32_Files.cpp +++ b/JuceLibraryCode/modules/juce_core/native/juce_win32_Files.cpp @@ -163,6 +163,12 @@ bool File::setFileReadOnlyInternal (const bool shouldBeReadOnly) const || SetFileAttributes (fullPath.toWideCharPointer(), newAtts) != FALSE; } +bool File::setFileExecutableInternal (bool /*shouldBeExecutable*/) const +{ + // XXX is this possible? + return false; +} + bool File::isHidden() const { return (WindowsFileHelpers::getAtts (fullPath) & FILE_ATTRIBUTE_HIDDEN) != 0; diff --git a/JuceLibraryCode/modules/juce_core/network/juce_Socket.cpp b/JuceLibraryCode/modules/juce_core/network/juce_Socket.cpp index 50da39c..291b580 100644 --- a/JuceLibraryCode/modules/juce_core/network/juce_Socket.cpp +++ b/JuceLibraryCode/modules/juce_core/network/juce_Socket.cpp @@ -389,7 +389,10 @@ void StreamingSocket::close() } if (handle != -1) + { + ::shutdown (handle, SHUT_RDWR); ::close (handle); + } #endif hostName.clear(); diff --git a/JuceLibraryCode/modules/juce_core/network/juce_URL.cpp b/JuceLibraryCode/modules/juce_core/network/juce_URL.cpp index 76d2b1e..a4cc02e 100644 --- a/JuceLibraryCode/modules/juce_core/network/juce_URL.cpp +++ b/JuceLibraryCode/modules/juce_core/network/juce_URL.cpp @@ -397,6 +397,17 @@ URL URL::withParameter (const String& parameterName, return u; } +URL URL::withParameters (const StringPairArray& parametersToAdd) const +{ + URL u (*this); + + for (int i = 0; i < parametersToAdd.size(); ++i) + u.addParameter (parametersToAdd.getAllKeys()[i], + parametersToAdd.getAllValues()[i]); + + return u; +} + URL URL::withPOSTData (const String& newPostData) const { URL u (*this); @@ -482,8 +493,8 @@ String URL::addEscapeChars (const String& s, const bool isParameter) || legalChars.indexOf ((juce_wchar) c) >= 0)) { utf8.set (i, '%'); - utf8.insert (++i, "0123456789abcdef" [((uint8) c) >> 4]); - utf8.insert (++i, "0123456789abcdef" [c & 15]); + utf8.insert (++i, "0123456789ABCDEF" [((uint8) c) >> 4]); + utf8.insert (++i, "0123456789ABCDEF" [c & 15]); } } diff --git a/JuceLibraryCode/modules/juce_core/network/juce_URL.h b/JuceLibraryCode/modules/juce_core/network/juce_URL.h index 06d8fb7..697ce0c 100644 --- a/JuceLibraryCode/modules/juce_core/network/juce_URL.h +++ b/JuceLibraryCode/modules/juce_core/network/juce_URL.h @@ -140,6 +140,12 @@ public: URL withParameter (const String& parameterName, const String& parameterValue) const; + /** Returns a copy of this URL, with a set of GET or POST parameters added. + This is a convenience method, equivalent to calling withParameter for each value. + @see withParameter + */ + URL withParameters (const StringPairArray& parametersToAdd) const; + /** Returns a copy of this URL, with a file-upload type parameter added to it. When performing a POST where one of your parameters is a binary file, this diff --git a/JuceLibraryCode/modules/juce_core/system/juce_StandardHeader.h b/JuceLibraryCode/modules/juce_core/system/juce_StandardHeader.h index 35d9b87..412ee53 100644 --- a/JuceLibraryCode/modules/juce_core/system/juce_StandardHeader.h +++ b/JuceLibraryCode/modules/juce_core/system/juce_StandardHeader.h @@ -35,8 +35,8 @@ See also SystemStats::getJUCEVersion() for a string version. */ #define JUCE_MAJOR_VERSION 3 -#define JUCE_MINOR_VERSION 0 -#define JUCE_BUILDNUMBER 8 +#define JUCE_MINOR_VERSION 1 +#define JUCE_BUILDNUMBER 1 /** Current Juce version number. diff --git a/JuceLibraryCode/modules/juce_core/system/juce_SystemStats.h b/JuceLibraryCode/modules/juce_core/system/juce_SystemStats.h index 835e6e6..023dcc0 100644 --- a/JuceLibraryCode/modules/juce_core/system/juce_SystemStats.h +++ b/JuceLibraryCode/modules/juce_core/system/juce_SystemStats.h @@ -47,28 +47,29 @@ public: /** The set of possible results of the getOperatingSystemType() method. */ enum OperatingSystemType { - UnknownOS = 0, + UnknownOS = 0, - Linux = 0x2000, - Android = 0x3000, - iOS = 0x8000, + Linux = 0x2000, + Android = 0x3000, + iOS = 0x8000, - MacOSX_10_4 = 0x1004, - MacOSX_10_5 = 0x1005, - MacOSX_10_6 = 0x1006, - MacOSX_10_7 = 0x1007, - MacOSX_10_8 = 0x1008, - MacOSX_10_9 = 0x1009, + MacOSX_10_4 = 0x1004, + MacOSX_10_5 = 0x1005, + MacOSX_10_6 = 0x1006, + MacOSX_10_7 = 0x1007, + MacOSX_10_8 = 0x1008, + MacOSX_10_9 = 0x1009, + MacOSX_10_10 = 0x100a, - Win2000 = 0x4105, - WinXP = 0x4106, - WinVista = 0x4107, - Windows7 = 0x4108, - Windows8_0 = 0x4109, - Windows8_1 = 0x410a, + Win2000 = 0x4105, + WinXP = 0x4106, + WinVista = 0x4107, + Windows7 = 0x4108, + Windows8_0 = 0x4109, + Windows8_1 = 0x410a, - Windows = 0x4000, /**< To test whether any version of Windows is running, - you can use the expression ((getOperatingSystemType() & Windows) != 0). */ + Windows = 0x4000, /**< To test whether any version of Windows is running, + you can use the expression ((getOperatingSystemType() & Windows) != 0). */ }; /** Returns the type of operating system we're running on. diff --git a/JuceLibraryCode/modules/juce_core/xml/juce_XmlDocument.h b/JuceLibraryCode/modules/juce_core/xml/juce_XmlDocument.h index d2a5b49..c032b85 100644 --- a/JuceLibraryCode/modules/juce_core/xml/juce_XmlDocument.h +++ b/JuceLibraryCode/modules/juce_core/xml/juce_XmlDocument.h @@ -41,7 +41,7 @@ @code XmlDocument myDocument (File ("myfile.xml")); - XmlElement* mainElement = myDocument.getDocumentElement(); + ScopedPointer mainElement (myDocument.getDocumentElement()); if (mainElement == nullptr) { @@ -57,7 +57,7 @@ Or you can use the static helper methods for quick parsing.. @code - XmlElement* xml = XmlDocument::parse (myXmlFile); + ScopedPointer xml (XmlDocument::parse (myXmlFile)); if (xml != nullptr && xml->hasTagName ("foobar")) { diff --git a/JuceLibraryCode/modules/juce_cryptography/juce_module_info b/JuceLibraryCode/modules/juce_cryptography/juce_module_info index 6960eef..42a588f 100644 --- a/JuceLibraryCode/modules/juce_cryptography/juce_module_info +++ b/JuceLibraryCode/modules/juce_cryptography/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_cryptography", "name": "JUCE cryptography classes", - "version": "3.0.8", + "version": "3.1.1", "description": "Classes for various basic cryptography functions, including RSA, Blowfish, MD5, SHA, etc.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/JuceLibraryCode/modules/juce_data_structures/juce_module_info b/JuceLibraryCode/modules/juce_data_structures/juce_module_info index 09b96f8..51d8fdb 100644 --- a/JuceLibraryCode/modules/juce_data_structures/juce_module_info +++ b/JuceLibraryCode/modules/juce_data_structures/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_data_structures", "name": "JUCE data model helper classes", - "version": "3.0.8", + "version": "3.1.1", "description": "Classes for undo/redo management, and smart data structures.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/JuceLibraryCode/modules/juce_data_structures/values/juce_Value.cpp b/JuceLibraryCode/modules/juce_data_structures/values/juce_Value.cpp index 55b37fe..b0bb405 100644 --- a/JuceLibraryCode/modules/juce_data_structures/values/juce_Value.cpp +++ b/JuceLibraryCode/modules/juce_data_structures/values/juce_Value.cpp @@ -111,12 +111,6 @@ Value::Value (const Value& other) : value (other.value) { } -Value& Value::operator= (const Value& other) -{ - value = other.value; - return *this; -} - #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS Value::Value (Value&& other) noexcept { diff --git a/JuceLibraryCode/modules/juce_data_structures/values/juce_Value.h b/JuceLibraryCode/modules/juce_data_structures/values/juce_Value.h index f8fc631..c25d35d 100644 --- a/JuceLibraryCode/modules/juce_data_structures/values/juce_Value.h +++ b/JuceLibraryCode/modules/juce_data_structures/values/juce_Value.h @@ -221,7 +221,11 @@ private: // This is disallowed to avoid confusion about whether it should // do a by-value or by-reference copy. - Value& operator= (const Value&); + Value& operator= (const Value&) JUCE_DELETED_FUNCTION; + + // This declaration prevents accidental construction from an integer of 0, + // which is possible in some compilers via an implicit cast to a pointer. + explicit Value (void*) JUCE_DELETED_FUNCTION; }; /** Writes a Value to an OutputStream as a UTF8 string. */ diff --git a/JuceLibraryCode/modules/juce_events/juce_events.h b/JuceLibraryCode/modules/juce_events/juce_events.h index 02f7c63..7af9c9c 100644 --- a/JuceLibraryCode/modules/juce_events/juce_events.h +++ b/JuceLibraryCode/modules/juce_events/juce_events.h @@ -39,6 +39,7 @@ namespace juce #include "messages/juce_NotificationType.h" #include "messages/juce_ApplicationBase.h" #include "messages/juce_Initialisation.h" +#include "messages/juce_MountedVolumeListChangeDetector.h" #include "broadcasters/juce_ListenerList.h" #include "broadcasters/juce_ActionBroadcaster.h" #include "broadcasters/juce_ActionListener.h" diff --git a/JuceLibraryCode/modules/juce_events/juce_module_info b/JuceLibraryCode/modules/juce_events/juce_module_info index 69e90c9..47c8ea8 100644 --- a/JuceLibraryCode/modules/juce_events/juce_module_info +++ b/JuceLibraryCode/modules/juce_events/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_events", "name": "JUCE message and event handling classes", - "version": "3.0.8", + "version": "3.1.1", "description": "Classes for running an application's main event loop and sending/receiving messages, timers, etc.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/JuceLibraryCode/modules/juce_events/native/juce_android_Messaging.cpp b/JuceLibraryCode/modules/juce_events/native/juce_android_Messaging.cpp index 733994a..144a326 100644 --- a/JuceLibraryCode/modules/juce_events/native/juce_android_Messaging.cpp +++ b/JuceLibraryCode/modules/juce_events/native/juce_android_Messaging.cpp @@ -42,7 +42,7 @@ bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* cons return true; } -JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, deliverMessage, void, (jobject activity, jlong value)) +JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, deliverMessage, void, (JNIEnv* env, jobject activity, jlong value)) { JUCE_TRY { diff --git a/JuceLibraryCode/modules/juce_events/native/juce_linux_Messaging.cpp b/JuceLibraryCode/modules/juce_events/native/juce_linux_Messaging.cpp index 48e28a7..046c462 100644 --- a/JuceLibraryCode/modules/juce_events/native/juce_linux_Messaging.cpp +++ b/JuceLibraryCode/modules/juce_events/native/juce_linux_Messaging.cpp @@ -131,7 +131,7 @@ public: } //============================================================================== - juce_DeclareSingleton_SingleThreaded_Minimal (InternalMessageQueue); + juce_DeclareSingleton_SingleThreaded_Minimal (InternalMessageQueue) private: CriticalSection lock; @@ -209,7 +209,7 @@ private: } }; -juce_ImplementSingleton_SingleThreaded (InternalMessageQueue); +juce_ImplementSingleton_SingleThreaded (InternalMessageQueue) //============================================================================== diff --git a/JuceLibraryCode/modules/juce_events/native/juce_mac_MessageManager.mm b/JuceLibraryCode/modules/juce_events/native/juce_mac_MessageManager.mm index 3aed8a2..7b2068e 100644 --- a/JuceLibraryCode/modules/juce_events/native/juce_mac_MessageManager.mm +++ b/JuceLibraryCode/modules/juce_events/native/juce_mac_MessageManager.mm @@ -365,3 +365,54 @@ void repostCurrentNSEvent() (new EventReposter())->post(); } + + +//============================================================================== +#if JUCE_MAC +struct MountedVolumeListChangeDetector::Pimpl +{ + Pimpl (MountedVolumeListChangeDetector& d) : owner (d) + { + static ObserverClass cls; + delegate = [cls.createInstance() init]; + ObserverClass::setOwner (delegate, this); + + NSNotificationCenter* nc = [[NSWorkspace sharedWorkspace] notificationCenter]; + + [nc addObserver: delegate selector: @selector (changed:) name: NSWorkspaceDidMountNotification object: nil]; + [nc addObserver: delegate selector: @selector (changed:) name: NSWorkspaceDidUnmountNotification object: nil]; + } + + ~Pimpl() + { + [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver: delegate]; + [delegate release]; + } + +private: + MountedVolumeListChangeDetector& owner; + id delegate; + + struct ObserverClass : public ObjCClass + { + ObserverClass() : ObjCClass ("JUCEDriveObserver_") + { + addIvar ("owner"); + addMethod (@selector (changed:), changed, "v@:@"); + addProtocol (@protocol (NSTextInput)); + registerClass(); + } + + static Pimpl* getOwner (id self) { return getIvar (self, "owner"); } + static void setOwner (id self, Pimpl* owner) { object_setInstanceVariable (self, "owner", owner); } + + static void changed (id self, SEL, NSNotification*) + { + getOwner (self)->owner.mountedVolumeListChanged(); + } + }; +}; + +MountedVolumeListChangeDetector::MountedVolumeListChangeDetector() { pimpl = new Pimpl (*this); } +MountedVolumeListChangeDetector::~MountedVolumeListChangeDetector() {} +#endif diff --git a/JuceLibraryCode/modules/juce_events/native/juce_win32_HiddenMessageWindow.h b/JuceLibraryCode/modules/juce_events/native/juce_win32_HiddenMessageWindow.h index c4747ec..e0df59a 100644 --- a/JuceLibraryCode/modules/juce_events/native/juce_win32_HiddenMessageWindow.h +++ b/JuceLibraryCode/modules/juce_events/native/juce_win32_HiddenMessageWindow.h @@ -100,7 +100,6 @@ public: virtual ~DeviceChangeDetector() {} -protected: virtual void systemDeviceChanged() = 0; void triggerAsyncDeviceChangeCallback() diff --git a/JuceLibraryCode/modules/juce_events/native/juce_win32_Messaging.cpp b/JuceLibraryCode/modules/juce_events/native/juce_win32_Messaging.cpp index 0bc0f78..853f54d 100644 --- a/JuceLibraryCode/modules/juce_events/native/juce_win32_Messaging.cpp +++ b/JuceLibraryCode/modules/juce_events/native/juce_win32_Messaging.cpp @@ -188,3 +188,30 @@ void MessageManager::doPlatformSpecificShutdown() OleUninitialize(); } + +//============================================================================== +struct MountedVolumeListChangeDetector::Pimpl : private DeviceChangeDetector +{ + Pimpl (MountedVolumeListChangeDetector& d) : DeviceChangeDetector (L"MountedVolumeList"), owner (d) + { + File::findFileSystemRoots (lastVolumeList); + } + + void systemDeviceChanged() override + { + Array newList; + File::findFileSystemRoots (newList); + + if (lastVolumeList != newList) + { + lastVolumeList = newList; + owner.mountedVolumeListChanged(); + } + } + + MountedVolumeListChangeDetector& owner; + Array lastVolumeList; +}; + +MountedVolumeListChangeDetector::MountedVolumeListChangeDetector() { pimpl = new Pimpl (*this); } +MountedVolumeListChangeDetector::~MountedVolumeListChangeDetector() {} diff --git a/JuceLibraryCode/modules/juce_events/timers/juce_Timer.cpp b/JuceLibraryCode/modules/juce_events/timers/juce_Timer.cpp index 6b7343a..f82abca 100644 --- a/JuceLibraryCode/modules/juce_events/timers/juce_Timer.cpp +++ b/JuceLibraryCode/modules/juce_events/timers/juce_Timer.cpp @@ -332,6 +332,14 @@ void Timer::startTimer (const int interval) noexcept } } +void Timer::startTimerHz (int timerFrequencyHz) noexcept +{ + if (timerFrequencyHz > 0) + startTimer (1000 / timerFrequencyHz); + else + stopTimer(); +} + void Timer::stopTimer() noexcept { const TimerThread::LockType::ScopedLockType sl (TimerThread::lock); diff --git a/JuceLibraryCode/modules/juce_events/timers/juce_Timer.h b/JuceLibraryCode/modules/juce_events/timers/juce_Timer.h index a2f823a..57b0ce8 100644 --- a/JuceLibraryCode/modules/juce_events/timers/juce_Timer.h +++ b/JuceLibraryCode/modules/juce_events/timers/juce_Timer.h @@ -91,6 +91,11 @@ public: */ void startTimer (int intervalInMilliseconds) noexcept; + /** Starts the timer with an interval specified in Hertz. + This is effectively the same as calling startTimer (1000 / timerFrequencyHz). + */ + void startTimerHz (int timerFrequencyHz) noexcept; + /** Stops the timer. No more callbacks will be made after this method returns. @@ -102,14 +107,10 @@ public: void stopTimer() noexcept; //============================================================================== - /** Checks if the timer has been started. - - @returns true if the timer is running. - */ + /** Returns true if the timer is currently running. */ bool isTimerRunning() const noexcept { return periodMs > 0; } /** Returns the timer's interval. - @returns the timer's interval in milliseconds if it's running, or 0 if it's not. */ int getTimerInterval() const noexcept { return periodMs; } diff --git a/JuceLibraryCode/modules/juce_graphics/fonts/juce_Font.cpp b/JuceLibraryCode/modules/juce_graphics/fonts/juce_Font.cpp index 1b4fc04..f0668d1 100644 --- a/JuceLibraryCode/modules/juce_graphics/fonts/juce_Font.cpp +++ b/JuceLibraryCode/modules/juce_graphics/fonts/juce_Font.cpp @@ -51,7 +51,7 @@ public: clearSingletonInstance(); } - juce_DeclareSingleton (TypefaceCache, false); + juce_DeclareSingleton (TypefaceCache, false) void setSize (const int numToCache) { diff --git a/JuceLibraryCode/modules/juce_graphics/geometry/juce_AffineTransform.cpp b/JuceLibraryCode/modules/juce_graphics/geometry/juce_AffineTransform.cpp index 59ebde3..85d6f4e 100644 --- a/JuceLibraryCode/modules/juce_graphics/geometry/juce_AffineTransform.cpp +++ b/JuceLibraryCode/modules/juce_graphics/geometry/juce_AffineTransform.cpp @@ -193,9 +193,9 @@ AffineTransform AffineTransform::sheared (const float shearX, const float shearY return AffineTransform (mat00 + shearX * mat10, mat01 + shearX * mat11, mat02 + shearX * mat12, - shearY * mat00 + mat10, - shearY * mat01 + mat11, - shearY * mat02 + mat12); + mat10 + shearY * mat00, + mat11 + shearY * mat01, + mat12 + shearY * mat02); } AffineTransform AffineTransform::verticalFlip (const float height) noexcept @@ -211,10 +211,10 @@ AffineTransform AffineTransform::inverted() const noexcept { determinant = 1.0 / determinant; - const float dst00 = (float) (mat11 * determinant); + const float dst00 = (float) ( mat11 * determinant); const float dst10 = (float) (-mat10 * determinant); const float dst01 = (float) (-mat01 * determinant); - const float dst11 = (float) (mat00 * determinant); + const float dst11 = (float) ( mat00 * determinant); return AffineTransform (dst00, dst01, -mat02 * dst00 - mat12 * dst01, dst10, dst11, -mat02 * dst10 - mat12 * dst11); @@ -258,5 +258,5 @@ bool AffineTransform::isOnlyTranslation() const noexcept float AffineTransform::getScaleFactor() const noexcept { - return (mat00 + mat11) / 2.0f; + return (std::abs (mat00) + std::abs (mat11)) / 2.0f; } diff --git a/JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.cpp b/JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.cpp index 5a6b2f8..65c211f 100644 --- a/JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.cpp +++ b/JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.cpp @@ -501,13 +501,20 @@ void Path::addRoundedRectangle (float x, float y, float w, float h, float cs) addRoundedRectangle (x, y, w, h, cs, cs); } -void Path::addTriangle (const float x1, const float y1, - const float x2, const float y2, - const float x3, const float y3) +void Path::addTriangle (float x1, float y1, + float x2, float y2, + float x3, float y3) { - startNewSubPath (x1, y1); - lineTo (x2, y2); - lineTo (x3, y3); + addTriangle (Point (x1, y1), + Point (x2, y2), + Point (x3, y3)); +} + +void Path::addTriangle (Point p1, Point p2, Point p3) +{ + startNewSubPath (p1); + lineTo (p2); + lineTo (p3); closeSubPath(); } diff --git a/JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.h b/JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.h index ac319f9..c680089 100644 --- a/JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.h +++ b/JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.h @@ -377,6 +377,18 @@ public: float x2, float y2, float x3, float y3); + /** Adds a triangle to the path. + + The triangle is added as a new closed sub-path. (Any currently open paths will be left open). + + Note that whether the vertices are specified in clockwise or anticlockwise + order will affect how the triangle is filled when it overlaps other + shapes (the winding order setting will affect this of course). + */ + void addTriangle (Point point1, + Point point2, + Point point3); + /** Adds a quadrilateral to the path. The quad is added as a new closed sub-path. (Any currently open paths will be left open). diff --git a/JuceLibraryCode/modules/juce_graphics/images/juce_ImageCache.cpp b/JuceLibraryCode/modules/juce_graphics/images/juce_ImageCache.cpp index 992ff32..a806e48 100644 --- a/JuceLibraryCode/modules/juce_graphics/images/juce_ImageCache.cpp +++ b/JuceLibraryCode/modules/juce_graphics/images/juce_ImageCache.cpp @@ -110,7 +110,7 @@ public: unsigned int cacheTimeout; - juce_DeclareSingleton_SingleThreaded_Minimal (ImageCache::Pimpl); + juce_DeclareSingleton_SingleThreaded_Minimal (ImageCache::Pimpl) private: OwnedArray images; @@ -119,7 +119,7 @@ private: JUCE_DECLARE_NON_COPYABLE (Pimpl) }; -juce_ImplementSingleton_SingleThreaded (ImageCache::Pimpl); +juce_ImplementSingleton_SingleThreaded (ImageCache::Pimpl) //============================================================================== diff --git a/JuceLibraryCode/modules/juce_graphics/juce_module_info b/JuceLibraryCode/modules/juce_graphics/juce_module_info index 75903c2..ab4d71b 100644 --- a/JuceLibraryCode/modules/juce_graphics/juce_module_info +++ b/JuceLibraryCode/modules/juce_graphics/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_graphics", "name": "JUCE graphics classes", - "version": "3.0.8", + "version": "3.1.1", "description": "Classes for 2D vector graphics, image loading/saving, font handling, etc.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/JuceLibraryCode/modules/juce_graphics/native/juce_freetype_Fonts.cpp b/JuceLibraryCode/modules/juce_graphics/native/juce_freetype_Fonts.cpp index 43a6436..d124eaf 100644 --- a/JuceLibraryCode/modules/juce_graphics/native/juce_freetype_Fonts.cpp +++ b/JuceLibraryCode/modules/juce_graphics/native/juce_freetype_Fonts.cpp @@ -224,7 +224,7 @@ public: sansSerif.addIfNotAlreadyThere (faces.getUnchecked(i)->family); } - juce_DeclareSingleton_SingleThreaded_Minimal (FTTypefaceList); + juce_DeclareSingleton_SingleThreaded_Minimal (FTTypefaceList) private: FTLibWrapper::Ptr library; diff --git a/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_TextButton.h b/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_TextButton.h index b9093b2..31c477b 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_TextButton.h +++ b/JuceLibraryCode/modules/juce_gui_basics/buttons/juce_TextButton.h @@ -102,7 +102,7 @@ public: private: #if JUCE_CATCH_DEPRECATED_CODE_MISUSE - // Note that this method has been removed - instead, see LookAndFeel::getTextButtonWidthToFitText() + // Note that this method has been removed - instead, see LookAndFeel::getTextButtonFont() virtual int getFont() { return 0; } #endif diff --git a/JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.cpp b/JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.cpp index 7cbe59f..00e8476 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.cpp +++ b/JuceLibraryCode/modules/juce_gui_basics/components/juce_Component.cpp @@ -784,6 +784,7 @@ public: validArea.clear(); } + if (! validArea.containsRectangle (compBounds)) { Graphics imG (image); LowLevelGraphicsContext& lg = imG.getInternalContext(); @@ -791,18 +792,15 @@ public: for (const Rectangle* i = validArea.begin(), * const e = validArea.end(); i != e; ++i) lg.excludeClipRectangle (*i); - if (! lg.isClipEmpty()) + if (! owner.isOpaque()) { - if (! owner.isOpaque()) - { - lg.setFill (Colours::transparentBlack); - lg.fillRect (imageBounds, true); - lg.setFill (Colours::black); - } - - lg.addTransform (AffineTransform::scale (scale)); - owner.paintEntireComponent (imG, true); + lg.setFill (Colours::transparentBlack); + lg.fillRect (imageBounds, true); + lg.setFill (Colours::black); } + + lg.addTransform (AffineTransform::scale (scale)); + owner.paintEntireComponent (imG, true); } validArea = imageBounds; diff --git a/JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp b/JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp index a6e7b07..12b81df 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp +++ b/JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.cpp @@ -89,7 +89,7 @@ ModalComponentManager::~ModalComponentManager() clearSingletonInstance(); } -juce_ImplementSingleton_SingleThreaded (ModalComponentManager); +juce_ImplementSingleton_SingleThreaded (ModalComponentManager) //============================================================================== diff --git a/JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.h b/JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.h index b21421e..1b927e1 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.h +++ b/JuceLibraryCode/modules/juce_gui_basics/components/juce_ModalComponentManager.h @@ -120,7 +120,7 @@ public: #endif //============================================================================== - juce_DeclareSingleton_SingleThreaded_Minimal (ModalComponentManager); + juce_DeclareSingleton_SingleThreaded_Minimal (ModalComponentManager) protected: /** Creates a ModalComponentManager. diff --git a/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp b/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp index 7c29dee..d609011 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp +++ b/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_DrawableImage.cpp @@ -37,6 +37,7 @@ DrawableImage::DrawableImage (const DrawableImage& other) overlayColour (other.overlayColour), bounds (other.bounds) { + setBounds (other.getBounds()); } DrawableImage::~DrawableImage() diff --git a/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_SVGParser.cpp b/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_SVGParser.cpp index cfb6b7b..35253a2 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_SVGParser.cpp +++ b/JuceLibraryCode/modules/juce_gui_basics/drawables/juce_SVGParser.cpp @@ -1157,9 +1157,9 @@ private: tokens.removeEmptyStrings (true); - float numbers [6]; + float numbers[6]; - for (int i = 0; i < 6; ++i) + for (int i = 0; i < numElementsInArray (numbers); ++i) numbers[i] = tokens[i].getFloatValue(); AffineTransform trans; @@ -1171,33 +1171,23 @@ private: } else if (t.startsWithIgnoreCase ("translate")) { - jassert (tokens.size() == 2); trans = AffineTransform::translation (numbers[0], numbers[1]); } else if (t.startsWithIgnoreCase ("scale")) { - if (tokens.size() == 1) - trans = AffineTransform::scale (numbers[0]); - else - trans = AffineTransform::scale (numbers[0], numbers[1]); + trans = AffineTransform::scale (numbers[0], numbers[tokens.size() > 1 ? 1 : 0]); } else if (t.startsWithIgnoreCase ("rotate")) { - if (tokens.size() != 3) - trans = AffineTransform::rotation (numbers[0] / (180.0f / float_Pi)); - else - trans = AffineTransform::rotation (numbers[0] / (180.0f / float_Pi), - numbers[1], numbers[2]); + trans = AffineTransform::rotation (numbers[0] / (180.0f / float_Pi), numbers[1], numbers[2]); } else if (t.startsWithIgnoreCase ("skewX")) { - trans = AffineTransform (1.0f, std::tan (numbers[0] * (float_Pi / 180.0f)), 0.0f, - 0.0f, 1.0f, 0.0f); + trans = AffineTransform::shear (std::tan (numbers[0] * (float_Pi / 180.0f)), 0.0f); } else if (t.startsWithIgnoreCase ("skewY")) { - trans = AffineTransform (1.0f, 0.0f, 0.0f, - std::tan (numbers[0] * (float_Pi / 180.0f)), 1.0f, 0.0f); + trans = AffineTransform::shear (0.0f, std::tan (numbers[0] * (float_Pi / 180.0f))); } result = trans.followedBy (result); @@ -1218,8 +1208,8 @@ private: const double midX = (x1 - x2) * 0.5; const double midY = (y1 - y2) * 0.5; - const double cosAngle = cos (angle); - const double sinAngle = sin (angle); + const double cosAngle = std::cos (angle); + const double sinAngle = std::sin (angle); const double xp = cosAngle * midX + sinAngle * midY; const double yp = cosAngle * midY - sinAngle * midX; const double xp2 = xp * xp; diff --git a/JuceLibraryCode/modules/juce_gui_basics/juce_module_info b/JuceLibraryCode/modules/juce_gui_basics/juce_module_info index d9d00fe..b17cfac 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/juce_module_info +++ b/JuceLibraryCode/modules/juce_gui_basics/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_gui_basics", "name": "JUCE GUI core classes", - "version": "3.0.8", + "version": "3.1.1", "description": "Basic user-interface components and related classes.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/JuceLibraryCode/modules/juce_gui_basics/layout/juce_AnimatedPosition.h b/JuceLibraryCode/modules/juce_gui_basics/layout/juce_AnimatedPosition.h index dac6ce1..2f82e03 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/layout/juce_AnimatedPosition.h +++ b/JuceLibraryCode/modules/juce_gui_basics/layout/juce_AnimatedPosition.h @@ -94,7 +94,7 @@ public: */ void endDrag() { - startTimer (1000 / 60); + startTimerHz (60); } /** Called outside of a drag operation to cause a nudge in the specified direction. @@ -102,7 +102,7 @@ public: */ void nudge (double deltaFromCurrentPosition) { - startTimer (100); + startTimerHz (10); moveTo (position + deltaFromCurrentPosition); } @@ -197,7 +197,7 @@ private: if (behaviour.isStopped (newPos)) stopTimer(); else - startTimer (1000 / 60); + startTimerHz (60); setPositionAndSendChange (newPos); } diff --git a/JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp b/JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp index 7c26c99..3507fc8 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp +++ b/JuceLibraryCode/modules/juce_gui_basics/layout/juce_ComponentAnimator.cpp @@ -25,9 +25,7 @@ class ComponentAnimator::AnimationTask { public: - AnimationTask (Component* const comp) noexcept : component (comp) - { - } + AnimationTask (Component* c) noexcept : component (c) {} void reset (const Rectangle& finalBounds, float finalAlpha, @@ -65,8 +63,8 @@ public: bool useTimeslice (const int elapsed) { - if (Component* const c = proxy != nullptr ? static_cast (proxy) - : static_cast (component)) + if (Component* const c = proxy != nullptr ? static_cast (proxy) + : static_cast (component)) { msElapsed += elapsed; double newProgress = msElapsed / (double) msTotal; @@ -149,7 +147,10 @@ public: else jassertfalse; // seem to be trying to animate a component that's not visible.. - image = c.createComponentSnapshot (c.getLocalBounds(), false, getDesktopScaleFactor()); + const float scale = (float) Desktop::getInstance().getDisplays() + .getDisplayContaining (getScreenBounds().getCentre()).scale; + + image = c.createComponentSnapshot (c.getLocalBounds(), false, scale); setVisible (true); toBehind (&c); @@ -189,14 +190,8 @@ private: }; //============================================================================== -ComponentAnimator::ComponentAnimator() - : lastTime (0) -{ -} - -ComponentAnimator::~ComponentAnimator() -{ -} +ComponentAnimator::ComponentAnimator() : lastTime (0) {} +ComponentAnimator::~ComponentAnimator() {} //============================================================================== ComponentAnimator::AnimationTask* ComponentAnimator::findTaskFor (Component* const component) const noexcept @@ -236,7 +231,7 @@ void ComponentAnimator::animateComponent (Component* const component, if (! isTimerRunning()) { lastTime = Time::getMillisecondCounter(); - startTimer (1000 / 50); + startTimerHz (50); } } } diff --git a/JuceLibraryCode/modules/juce_gui_basics/layout/juce_Viewport.cpp b/JuceLibraryCode/modules/juce_gui_basics/layout/juce_Viewport.cpp index 2824233..80266ce 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/layout/juce_Viewport.cpp +++ b/JuceLibraryCode/modules/juce_gui_basics/layout/juce_Viewport.cpp @@ -52,6 +52,7 @@ Viewport::Viewport (const String& name) Viewport::~Viewport() { deleteContentComp(); + mouseWheelTimer = nullptr; } //============================================================================== @@ -357,6 +358,30 @@ static int rescaleMouseWheelDistance (float distance, int singleStepSize) noexce : jmax (distance, 1.0f)); } +// This puts a temporary component overlay over the content component, to prevent +// wheel events from reaching components inside it, so that while spinning a wheel +// with momentum, it won't accidentally scroll any subcomponents of the viewport. +struct Viewport::MouseWheelTimer : public Timer +{ + MouseWheelTimer (Viewport& v) : viewport (v) + { + viewport.contentHolder.addAndMakeVisible (dummyOverlay); + dummyOverlay.setAlwaysOnTop (true); + dummyOverlay.setPaintingIsUnclipped (true); + dummyOverlay.setBounds (viewport.contentHolder.getLocalBounds()); + } + + void timerCallback() override + { + viewport.mouseWheelTimer = nullptr; + } + + Component dummyOverlay; + Viewport& viewport; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MouseWheelTimer) +}; + bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, const MouseWheelDetails& wheel) { if (! (e.mods.isAltDown() || e.mods.isCtrlDown() || e.mods.isCommandDown())) @@ -387,6 +412,11 @@ bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, const MouseWheelD if (pos != getViewPosition()) { + if (mouseWheelTimer == nullptr) + mouseWheelTimer = new MouseWheelTimer (*this); + + mouseWheelTimer->startTimer (300); + setViewPosition (pos); return true; } diff --git a/JuceLibraryCode/modules/juce_gui_basics/layout/juce_Viewport.h b/JuceLibraryCode/modules/juce_gui_basics/layout/juce_Viewport.h index baeb42a..c427515 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/layout/juce_Viewport.h +++ b/JuceLibraryCode/modules/juce_gui_basics/layout/juce_Viewport.h @@ -267,6 +267,9 @@ private: bool allowScrollingWithoutScrollbarV, allowScrollingWithoutScrollbarH; Component contentHolder; ScrollBar verticalScrollBar, horizontalScrollBar; + struct MouseWheelTimer; + ScopedPointer mouseWheelTimer; + Point viewportPosToCompPos (Point) const; void updateVisibleArea(); diff --git a/JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp b/JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp index 4135afe..31d2824 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp +++ b/JuceLibraryCode/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp @@ -1397,7 +1397,6 @@ void LookAndFeel_V2::drawRotarySlider (Graphics& g, int x, int y, int width, int g.fillPath (filledArc); } - if (thickness > 0) { const float innerRadius = radius * 0.2f; Path p; diff --git a/JuceLibraryCode/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h b/JuceLibraryCode/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h index 20f1f7b..2566c43 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h +++ b/JuceLibraryCode/modules/juce_gui_basics/mouse/juce_SelectedItemSet.h @@ -38,8 +38,6 @@ To be informed when items are selected/deselected, register a ChangeListener with this object. - - @see SelectableObject */ template class SelectedItemSet : public ChangeBroadcaster diff --git a/JuceLibraryCode/modules/juce_gui_basics/native/juce_android_Windowing.cpp b/JuceLibraryCode/modules/juce_gui_basics/native/juce_android_Windowing.cpp index 200615f..763403f 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/native/juce_android_Windowing.cpp +++ b/JuceLibraryCode/modules/juce_gui_basics/native/juce_android_Windowing.cpp @@ -111,7 +111,8 @@ public: // NB: must not put this in the initialiser list, as it invokes a callback, // which will fail if the peer is only half-constructed. view = GlobalRef (android.activity.callObjectMethod (JuceAppActivity.createNewView, - component.isOpaque(), (jlong) this)); + (jboolean) component.isOpaque(), + (jlong) this)); if (isFocused()) handleFocusGain(); @@ -584,7 +585,7 @@ ComponentPeer* Component::createNewPeer (int styleFlags, void*) jobject createOpenGLView (ComponentPeer* peer) { - jobject parentView = static_cast (peer->getNativeHandle()); + jobject parentView = static_cast (peer->getNativeHandle()); return getEnv()->CallObjectMethod (parentView, ComponentPeerView.createGLView); } diff --git a/JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_FileChooser.mm b/JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_FileChooser.mm index d5f36a6..f256067 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_FileChooser.mm +++ b/JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_FileChooser.mm @@ -172,10 +172,10 @@ void FileChooser::showPlatformDialog (Array& results, [panel setDirectoryURL: [NSURL fileURLWithPath: juceStringToNS (directory)]]; [panel setNameFieldStringValue: juceStringToNS (filename)]; - if ([panel runModal] == NSOKButton) + if ([panel runModal] == 1 /*NSModalResponseOK*/) #else if ([panel runModalForDirectory: juceStringToNS (directory) - file: juceStringToNS (filename)] == NSOKButton) + file: juceStringToNS (filename)] == 1 /*NSModalResponseOK*/) #endif { if (isSaveDialogue) diff --git a/JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm b/JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm index 45569b8..789fc88 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm +++ b/JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm @@ -411,9 +411,9 @@ public: if (NSWindow* const viewWindow = [view window]) { const NSRect windowFrame = [viewWindow frame]; - const NSPoint windowPoint = [view convertPoint: NSMakePoint (localPos.x, localPos.y) toView: nil]; + const NSPoint windowPoint = [view convertPoint: NSMakePoint (localPos.x, viewFrame.size.height - localPos.y) toView: nil]; const NSPoint screenPoint = NSMakePoint (windowFrame.origin.x + windowPoint.x, - windowFrame.origin.y + windowFrame.size.height - windowPoint.y); + windowFrame.origin.y + windowPoint.y); if (! isWindowAtPoint (viewWindow, screenPoint)) return false; @@ -574,7 +574,15 @@ public: { currentModifiers = currentModifiers.withoutMouseButtons(); - if (isWindowAtPoint ([ev window], [[ev window] convertBaseToScreen: [ev locationInWindow]])) + NSPoint windowPos = [ev locationInWindow]; + + #if defined (MAC_OS_X_VERSION_10_7) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7 + NSPoint screenPos = [[ev window] convertRectToScreen: NSMakeRect (windowPos.x, windowPos.y, 1.0f, 1.0f)].origin; + #else + NSPoint screenPos = [[ev window] convertBaseToScreen: windowPos]; + #endif + + if (isWindowAtPoint ([ev window], screenPos)) sendMouseEvent (ev); else // moved into another window which overlaps this one, so trigger an exit @@ -1786,7 +1794,9 @@ private: static void windowDidExitFullScreen (id, SEL, NSNotification*) { + #if defined (MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 [NSApp setPresentationOptions: NSApplicationPresentationDefault]; + #endif } static void zoom (id self, SEL, id sender) diff --git a/JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_Windowing.mm b/JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_Windowing.mm index 8f53304..392ca16 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_Windowing.mm +++ b/JuceLibraryCode/modules/juce_gui_basics/native/juce_mac_Windowing.mm @@ -164,37 +164,29 @@ bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& fi JUCE_AUTORELEASEPOOL { - NSView* view = (NSView*) sourceComp->getWindowHandle(); + if (NSView* view = (NSView*) sourceComp->getWindowHandle()) + { + if (NSEvent* event = [[view window] currentEvent]) + { + NSPoint eventPos = [event locationInWindow]; + NSRect dragRect = [view convertRect: NSMakeRect (eventPos.x - 16.0f, eventPos.y - 16.0f, 32.0f, 32.0f) + fromView: nil]; - if (view == nil) - return false; + for (int i = 0; i < files.size(); ++i) + { + if (! [view dragFile: juceStringToNS (files[i]) + fromRect: dragRect + slideBack: YES + event: event]) + return false; + } - NSPasteboard* pboard = [NSPasteboard pasteboardWithName: NSDragPboard]; - [pboard declareTypes: [NSArray arrayWithObject: NSFilenamesPboardType] - owner: nil]; - - NSMutableArray* filesArray = [NSMutableArray arrayWithCapacity: 4]; - for (int i = 0; i < files.size(); ++i) - [filesArray addObject: juceStringToNS (files[i])]; - - [pboard setPropertyList: filesArray - forType: NSFilenamesPboardType]; - - NSPoint dragPosition = [view convertPoint: [[[view window] currentEvent] locationInWindow] - fromView: nil]; - dragPosition.x -= 16; - dragPosition.y -= 16; - - [view dragImage: [[NSWorkspace sharedWorkspace] iconForFile: juceStringToNS (files[0])] - at: dragPosition - offset: NSMakeSize (0, 0) - event: [[view window] currentEvent] - pasteboard: pboard - source: view - slideBack: YES]; + return true; + } + } } - return true; + return false; } bool DragAndDropContainer::performExternalDragDropOfText (const String& /*text*/) @@ -340,13 +332,13 @@ public: const_cast (Desktop::getInstance().getDisplays()).refresh(); } - juce_DeclareSingleton_SingleThreaded_Minimal (DisplaySettingsChangeCallback); + juce_DeclareSingleton_SingleThreaded_Minimal (DisplaySettingsChangeCallback) private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DisplaySettingsChangeCallback) }; -juce_ImplementSingleton_SingleThreaded (DisplaySettingsChangeCallback); +juce_ImplementSingleton_SingleThreaded (DisplaySettingsChangeCallback) static Rectangle convertDisplayRect (NSRect r, CGFloat mainScreenBottom) { diff --git a/JuceLibraryCode/modules/juce_gui_basics/native/juce_win32_Windowing.cpp b/JuceLibraryCode/modules/juce_gui_basics/native/juce_win32_Windowing.cpp index 3ec007c..db23268 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/native/juce_win32_Windowing.cpp +++ b/JuceLibraryCode/modules/juce_gui_basics/native/juce_win32_Windowing.cpp @@ -1226,7 +1226,7 @@ private: LPCTSTR getWindowClassName() const noexcept { return (LPCTSTR) MAKELONG (atom, 0); } - juce_DeclareSingleton_SingleThreaded_Minimal (WindowClassHolder); + juce_DeclareSingleton_SingleThreaded_Minimal (WindowClassHolder) private: ATOM atom; @@ -1749,10 +1749,13 @@ private: doMouseMove (position); - updateModifiersFromWParam (wParam); - isDragging = true; + if (isValidPeer (this)) + { + updateModifiersFromWParam (wParam); + isDragging = true; - doMouseEvent (position); + doMouseEvent (position); + } } void doMouseUp (Point position, const WPARAM wParam) @@ -2936,7 +2939,7 @@ ComponentPeer* createNonRepaintingEmbeddedWindowsPeer (Component& component, voi } -juce_ImplementSingleton_SingleThreaded (HWNDComponentPeer::WindowClassHolder); +juce_ImplementSingleton_SingleThreaded (HWNDComponentPeer::WindowClassHolder) //============================================================================== diff --git a/JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp b/JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp index 27f3eb6..1c706e0 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp +++ b/JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeRectangle.cpp @@ -208,7 +208,7 @@ public: void applyToComponentBounds() { - for (int i = 4; --i >= 0;) + for (int i = 32; --i >= 0;) { ComponentScope scope (getComponent()); const Rectangle newBounds (rectangle.resolve (&scope).getSmallestIntegerContainer()); diff --git a/JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h b/JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h index fc5ad45..cd91c8d 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h +++ b/JuceLibraryCode/modules/juce_gui_basics/positioning/juce_RelativeRectangle.h @@ -28,7 +28,7 @@ //============================================================================== /** - An rectangle stored as a set of RelativeCoordinate values. + A rectangle stored as a set of RelativeCoordinate values. The rectangle's top, left, bottom and right edge positions are each stored as a RelativeCoordinate. diff --git a/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ComboBox.cpp b/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ComboBox.cpp index ffdcfd1..eed4111 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ComboBox.cpp +++ b/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ComboBox.cpp @@ -473,7 +473,7 @@ bool ComboBox::keyPressed (const KeyPress& key) if (key == KeyPress::returnKey) { - showPopup(); + showPopupIfNotActive(); return true; } @@ -512,42 +512,51 @@ void ComboBox::popupMenuFinishedCallback (int result, ComboBox* box) } } -void ComboBox::showPopup() +void ComboBox::showPopupIfNotActive() { if (! menuActive) { - const int selectedId = getSelectedId(); - - PopupMenu menu; - menu.setLookAndFeel (&getLookAndFeel()); - - for (int i = 0; i < items.size(); ++i) - { - const ItemInfo* const item = items.getUnchecked(i); - - if (item->isSeparator()) - menu.addSeparator(); - else if (item->isHeading) - menu.addSectionHeader (item->name); - else - menu.addItem (item->itemId, item->name, - item->isEnabled, item->itemId == selectedId); - } - - if (items.size() == 0) - menu.addItem (1, noChoicesMessage, false); - menuActive = true; - - menu.showMenuAsync (PopupMenu::Options().withTargetComponent (this) - .withItemThatMustBeVisible (selectedId) - .withMinimumWidth (getWidth()) - .withMaximumNumColumns (1) - .withStandardItemHeight (jlimit (12, 24, getHeight())), - ModalCallbackFunction::forComponent (popupMenuFinishedCallback, this)); + showPopup(); } } +void ComboBox::showPopup() +{ + PopupMenu menu; + menu.setLookAndFeel (&getLookAndFeel()); + addItemsToMenu (menu); + + menu.showMenuAsync (PopupMenu::Options().withTargetComponent (this) + .withItemThatMustBeVisible (getSelectedId()) + .withMinimumWidth (getWidth()) + .withMaximumNumColumns (1) + .withStandardItemHeight (label->getHeight()), + ModalCallbackFunction::forComponent (popupMenuFinishedCallback, this)); +} + +void ComboBox::addItemsToMenu (PopupMenu& menu) const +{ + const int selectedId = getSelectedId(); + + for (int i = 0; i < items.size(); ++i) + { + const ItemInfo* const item = items.getUnchecked(i); + jassert (item != nullptr); + + if (item->isSeparator()) + menu.addSeparator(); + else if (item->isHeading) + menu.addSectionHeader (item->name); + else + menu.addItem (item->itemId, item->name, + item->isEnabled, item->itemId == selectedId); + } + + if (items.size() == 0) + menu.addItem (1, noChoicesMessage, false); +} + //============================================================================== void ComboBox::mouseDown (const MouseEvent& e) { @@ -556,7 +565,7 @@ void ComboBox::mouseDown (const MouseEvent& e) isButtonDown = isEnabled() && ! e.mods.isPopupMenu(); if (isButtonDown && (e.eventComponent == this || ! label->isEditable())) - showPopup(); + showPopupIfNotActive(); } void ComboBox::mouseDrag (const MouseEvent& e) @@ -564,7 +573,7 @@ void ComboBox::mouseDrag (const MouseEvent& e) beginDragAutoRepeat (50); if (isButtonDown && ! e.mouseWasClicked()) - showPopup(); + showPopupIfNotActive(); } void ComboBox::mouseUp (const MouseEvent& e2) @@ -579,7 +588,7 @@ void ComboBox::mouseUp (const MouseEvent& e2) if (reallyContains (e.getPosition(), true) && (e2.eventComponent == this || ! label->isEditable())) { - showPopup(); + showPopupIfNotActive(); } } } diff --git a/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ComboBox.h b/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ComboBox.h index 11515ba..11f4dd4 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ComboBox.h +++ b/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ComboBox.h @@ -263,6 +263,9 @@ public: */ virtual void showPopup(); + /** Adds the items in this ComboBox to the given menu. */ + virtual void addItemsToMenu (PopupMenu&) const; + //============================================================================== /** A class for receiving events from a ComboBox. @@ -432,6 +435,7 @@ private: bool selectIfEnabled (int index); bool nudgeSelectedItem (int delta); void sendChange (NotificationType); + void showPopupIfNotActive(); static void popupMenuFinishedCallback (int, ComboBox*); JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ComboBox) diff --git a/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ListBox.cpp b/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ListBox.cpp index 47f7f4c..5364a0d 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ListBox.cpp +++ b/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ListBox.cpp @@ -174,7 +174,7 @@ public: int getRowNumberOfComponent (Component* const rowComponent) const noexcept { - const int index = getIndexOfChildComponent (rowComponent); + const int index = getViewedComponent()->getIndexOfChildComponent (rowComponent); const int num = rows.size(); for (int i = num; --i >= 0;) @@ -196,15 +196,16 @@ public: { hasUpdated = false; - const int newX = getViewedComponent()->getX(); - int newY = getViewedComponent()->getY(); + Component& content = *getViewedComponent(); + const int newX = content.getX(); + int newY = content.getY(); const int newW = jmax (owner.minimumRowWidth, getMaximumVisibleWidth()); const int newH = owner.totalItems * owner.getRowHeight(); if (newY + newH < getMaximumVisibleHeight() && newH > getMaximumVisibleHeight()) newY = getMaximumVisibleHeight() - newH; - getViewedComponent()->setBounds (newX, newY, newW, newH); + content.setBounds (newX, newY, newW, newH); if (makeSureItUpdatesContent && ! hasUpdated) updateContents(); @@ -214,11 +215,12 @@ public: { hasUpdated = true; const int rowH = owner.getRowHeight(); + Component& content = *getViewedComponent(); if (rowH > 0) { const int y = getViewPositionY(); - const int w = getViewedComponent()->getWidth(); + const int w = content.getWidth(); const int numNeeded = 2 + getMaximumVisibleHeight() / rowH; rows.removeRange (numNeeded, rows.size()); @@ -227,7 +229,7 @@ public: { RowComponent* newRow = new RowComponent (owner); rows.add (newRow); - getViewedComponent()->addAndMakeVisible (newRow); + content.addAndMakeVisible (newRow); } firstIndex = y / rowH; @@ -247,10 +249,10 @@ public: } if (owner.headerComponent != nullptr) - owner.headerComponent->setBounds (owner.outlineThickness + getViewedComponent()->getX(), + owner.headerComponent->setBounds (owner.outlineThickness + content.getX(), owner.outlineThickness, jmax (owner.getWidth() - owner.outlineThickness * 2, - getViewedComponent()->getWidth()), + content.getWidth()), owner.headerComponent->getHeight()); } diff --git a/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Slider.h b/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Slider.h index 92180ed..5f89b8b 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Slider.h +++ b/JuceLibraryCode/modules/juce_gui_basics/widgets/juce_Slider.h @@ -248,9 +248,7 @@ public: void setSkewFactorFromMidPoint (double sliderValueToShowAtMidPoint); /** Returns the current skew factor. - See setSkewFactor for more info. - @see setSkewFactor, setSkewFactorFromMidPoint */ double getSkewFactor() const noexcept; @@ -682,6 +680,13 @@ public: /** Returns the suffix that was set by setTextValueSuffix(). */ String getTextValueSuffix() const; + /** Returns the best number of decimal places to use when displaying this + slider's value. + It calculates the fewest decimal places needed to represent numbers with + the slider's interval setting. + */ + int getNumDecimalPlacesToDisplay() const noexcept; + //============================================================================== /** Allows a user-defined mapping of distance along the slider to its value. @@ -831,7 +836,6 @@ public: #endif }; -protected: //============================================================================== /** @internal */ void paint (Graphics&) override; @@ -858,11 +862,6 @@ protected: /** @internal */ void colourChanged() override; - /** Returns the best number of decimal places to use when displaying numbers. - This is calculated from the slider's interval setting. - */ - int getNumDecimalPlacesToDisplay() const noexcept; - private: //============================================================================== JUCE_PUBLIC_IN_DLL_BUILD (class Pimpl) diff --git a/JuceLibraryCode/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp b/JuceLibraryCode/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp index f30defc..0338cc4 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp +++ b/JuceLibraryCode/modules/juce_gui_basics/windows/juce_ResizableWindow.cpp @@ -558,6 +558,10 @@ bool ResizableWindow::restoreWindowStateFromString (const String& s) } updateLastPosIfNotFullScreen(); + + if (fs) + setBoundsConstrained (newPos); + setFullScreen (fs); if (! fs) diff --git a/JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp b/JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp index fbd0686..4de7f9f 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp +++ b/JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.cpp @@ -24,11 +24,11 @@ TooltipWindow::TooltipWindow (Component* const parentComp, const int delayMs) : Component ("tooltip"), + lastComponentUnderMouse (nullptr), millisecondsBeforeTipAppears (delayMs), - mouseClicks (0), - mouseWheelMoves (0), - lastHideTime (0), - lastComponentUnderMouse (nullptr) + mouseClicks (0), mouseWheelMoves (0), + lastCompChangeTime (0), lastHideTime (0), + reentrant (false) { if (Desktop::getInstance().getMainMouseSource().canHover()) startTimer (123); @@ -76,27 +76,34 @@ void TooltipWindow::updatePosition (const String& tip, Point pos, const Rec void TooltipWindow::displayTip (Point screenPos, const String& tip) { jassert (tip.isNotEmpty()); - if (tipShowing != tip) - repaint(); - tipShowing = tip; - - if (Component* const parent = getParentComponent()) + if (! reentrant) { - updatePosition (tip, parent->getLocalPoint (nullptr, screenPos), - parent->getLocalBounds()); - } - else - { - updatePosition (tip, screenPos, Desktop::getInstance().getDisplays() - .getDisplayContaining (screenPos).userArea); + ScopedValueSetter setter (reentrant, true, false); - addToDesktop (ComponentPeer::windowHasDropShadow - | ComponentPeer::windowIsTemporary - | ComponentPeer::windowIgnoresKeyPresses); - } + if (tipShowing != tip) + { + tipShowing = tip; + repaint(); + } - toFront (false); + if (Component* const parent = getParentComponent()) + { + updatePosition (tip, parent->getLocalPoint (nullptr, screenPos), + parent->getLocalBounds()); + } + else + { + updatePosition (tip, screenPos, Desktop::getInstance().getDisplays() + .getDisplayContaining (screenPos).userArea); + + addToDesktop (ComponentPeer::windowHasDropShadow + | ComponentPeer::windowIsTemporary + | ComponentPeer::windowIgnoresKeyPresses); + } + + toFront (false); + } } String TooltipWindow::getTipFor (Component* const c) @@ -110,14 +117,17 @@ String TooltipWindow::getTipFor (Component* const c) return ttc->getTooltip(); } - return String::empty; + return String(); } void TooltipWindow::hideTip() { - tipShowing.clear(); - removeFromDesktop(); - setVisible (false); + if (! reentrant) + { + tipShowing.clear(); + removeFromDesktop(); + setVisible (false); + } } void TooltipWindow::timerCallback() diff --git a/JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.h b/JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.h index d32d997..3688ae4 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.h +++ b/JuceLibraryCode/modules/juce_gui_basics/windows/juce_TooltipWindow.h @@ -110,12 +110,13 @@ public: private: //============================================================================== - int millisecondsBeforeTipAppears; Point lastMousePos; - int mouseClicks, mouseWheelMoves; - unsigned int lastCompChangeTime, lastHideTime; Component* lastComponentUnderMouse; String tipShowing, lastTipUnderMouse; + int millisecondsBeforeTipAppears; + int mouseClicks, mouseWheelMoves; + unsigned int lastCompChangeTime, lastHideTime; + bool reentrant; void paint (Graphics&) override; void mouseEnter (const MouseEvent&) override; diff --git a/JuceLibraryCode/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp b/JuceLibraryCode/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp index c7248dd..446b175 100644 --- a/JuceLibraryCode/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp +++ b/JuceLibraryCode/modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp @@ -36,7 +36,7 @@ public: clearSingletonInstance(); } - juce_DeclareSingleton_SingleThreaded_Minimal (TopLevelWindowManager); + juce_DeclareSingleton_SingleThreaded_Minimal (TopLevelWindowManager) void checkFocusAsync() { diff --git a/JuceLibraryCode/modules/juce_gui_extra/juce_gui_extra.cpp b/JuceLibraryCode/modules/juce_gui_extra/juce_gui_extra.cpp index 4b80cc2..bff407c 100644 --- a/JuceLibraryCode/modules/juce_gui_extra/juce_gui_extra.cpp +++ b/JuceLibraryCode/modules/juce_gui_extra/juce_gui_extra.cpp @@ -91,6 +91,7 @@ namespace juce #include "misc/juce_SplashScreen.cpp" #include "misc/juce_SystemTrayIconComponent.cpp" #include "misc/juce_LiveConstantEditor.cpp" +#include "misc/juce_AnimatedAppComponent.cpp" } @@ -146,5 +147,6 @@ namespace juce bool WebBrowserComponent::pageAboutToLoad (const String&) { return true; } void WebBrowserComponent::pageFinishedLoading (const String&) {} void WebBrowserComponent::windowCloseRequest() {} + void WebBrowserComponent::newWindowAttemptingToLoad (const String&) {} #endif } diff --git a/JuceLibraryCode/modules/juce_gui_extra/juce_gui_extra.h b/JuceLibraryCode/modules/juce_gui_extra/juce_gui_extra.h index 36532f1..da1f625 100644 --- a/JuceLibraryCode/modules/juce_gui_extra/juce_gui_extra.h +++ b/JuceLibraryCode/modules/juce_gui_extra/juce_gui_extra.h @@ -72,6 +72,7 @@ namespace juce #include "misc/juce_SystemTrayIconComponent.h" #include "misc/juce_WebBrowserComponent.h" #include "misc/juce_LiveConstantEditor.h" +#include "misc/juce_AnimatedAppComponent.h" } diff --git a/JuceLibraryCode/modules/juce_gui_extra/juce_module_info b/JuceLibraryCode/modules/juce_gui_extra/juce_module_info index 60a2754..ce0a4e9 100644 --- a/JuceLibraryCode/modules/juce_gui_extra/juce_module_info +++ b/JuceLibraryCode/modules/juce_gui_extra/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_gui_extra", "name": "JUCE extended GUI classes", - "version": "3.0.8", + "version": "3.1.1", "description": "Miscellaneous GUI classes for specialised tasks.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/JuceLibraryCode/modules/juce_gui_extra/misc/juce_WebBrowserComponent.h b/JuceLibraryCode/modules/juce_gui_extra/misc/juce_WebBrowserComponent.h index 6afad60..861dc9d 100644 --- a/JuceLibraryCode/modules/juce_gui_extra/misc/juce_WebBrowserComponent.h +++ b/JuceLibraryCode/modules/juce_gui_extra/misc/juce_WebBrowserComponent.h @@ -98,6 +98,12 @@ public: */ virtual void windowCloseRequest(); + /** This callback occurs when the browser attempts to load a URL in a new window. + This won't actually load the window but gives you a chance to either launch a + new window yourself or just load the URL into the current window with goToURL(). + */ + virtual void newWindowAttemptingToLoad (const String& newURL); + //============================================================================== /** @internal */ void paint (Graphics&) override; @@ -107,6 +113,8 @@ public: void parentHierarchyChanged() override; /** @internal */ void visibilityChanged() override; + /** @internal */ + void focusGained (FocusChangeType) override; private: //============================================================================== diff --git a/JuceLibraryCode/modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp b/JuceLibraryCode/modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp index d449bae..532b907 100644 --- a/JuceLibraryCode/modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp +++ b/JuceLibraryCode/modules/juce_gui_extra/native/juce_android_WebBrowserComponent.cpp @@ -107,3 +107,7 @@ void WebBrowserComponent::visibilityChanged() { checkWindowAssociation(); } + +void WebBrowserComponent::focusGained (FocusChangeType) +{ +} diff --git a/JuceLibraryCode/modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp b/JuceLibraryCode/modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp index 5aafe3a..43f5e79 100644 --- a/JuceLibraryCode/modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp +++ b/JuceLibraryCode/modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp @@ -112,3 +112,7 @@ void WebBrowserComponent::visibilityChanged() { checkWindowAssociation(); } + +void WebBrowserComponent::focusGained (FocusChangeType) +{ +} diff --git a/JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm b/JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm index 4fd30aa..655abb6 100644 --- a/JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm +++ b/JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_NSViewComponent.mm @@ -81,7 +81,7 @@ private: target->viewResized(); } - JUCE_DECLARE_NON_COPYABLE (ViewFrameChangeCallbackClass); + JUCE_DECLARE_NON_COPYABLE (ViewFrameChangeCallbackClass) }; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NSViewResizeWatcher) diff --git a/JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm b/JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm index a522809..89e17ef 100644 --- a/JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm +++ b/JuceLibraryCode/modules/juce_gui_extra/native/juce_mac_WebBrowserComponent.mm @@ -24,14 +24,16 @@ #if JUCE_MAC -struct DownloadClickDetectorClass : public ObjCClass +struct DownloadClickDetectorClass : public ObjCClass { - DownloadClickDetectorClass() : ObjCClass ("JUCEWebClickDetector_") + DownloadClickDetectorClass() : ObjCClass ("JUCEWebClickDetector_") { - addIvar ("owner"); + addIvar ("owner"); addMethod (@selector (webView:decidePolicyForNavigationAction:request:frame:decisionListener:), decidePolicyForNavigationAction, "v@:@@@@@"); + addMethod (@selector (webView:decidePolicyForNewWindowAction:request:newFrameName:decisionListener:), + decidePolicyForNewWindowAction, "v@:@@@@@"); addMethod (@selector (webView:didFinishLoadForFrame:), didFinishLoadForFrame, "v@:@@"); addMethod (@selector (webView:willCloseFrame:), willCloseFrame, "v@:@@"); addMethod (@selector (webView:runOpenPanelForFileButtonWithResultListener:allowMultipleFiles:), runOpenPanel, "v@:@@", @encode (BOOL)); @@ -43,17 +45,30 @@ struct DownloadClickDetectorClass : public ObjCClass static WebBrowserComponent* getOwner (id self) { return getIvar (self, "owner"); } private: - static void decidePolicyForNavigationAction (id self, SEL, WebView*, NSDictionary* actionInformation, - NSURLRequest*, WebFrame*, id listener) + static String getOriginalURL (NSDictionary* actionInformation) { - NSURL* url = [actionInformation valueForKey: nsStringLiteral ("WebActionOriginalURLKey")]; + if (NSURL* url = [actionInformation valueForKey: nsStringLiteral ("WebActionOriginalURLKey")]) + return nsStringToJuce ([url absoluteString]); - if (getOwner (self)->pageAboutToLoad (nsStringToJuce ([url absoluteString]))) + return String(); + } + + static void decidePolicyForNavigationAction (id self, SEL, WebView*, NSDictionary* actionInformation, + NSURLRequest*, WebFrame*, id listener) + { + if (getOwner (self)->pageAboutToLoad (getOriginalURL (actionInformation))) [listener use]; else [listener ignore]; } + static void decidePolicyForNewWindowAction (id self, SEL, WebView*, NSDictionary* actionInformation, + NSURLRequest*, NSString*, id listener) + { + getOwner (self)->newWindowAttemptingToLoad (getOriginalURL (actionInformation)); + [listener ignore]; + } + static void didFinishLoadForFrame (id self, SEL, WebView* sender, WebFrame* frame) { if ([frame isEqual: [sender mainFrame]]) @@ -94,7 +109,7 @@ private: } // (juce namespace) //============================================================================== -@interface WebViewTapDetector : NSObject +@interface WebViewTapDetector : NSObject { } @@ -115,30 +130,38 @@ private: @end //============================================================================== -@interface WebViewURLChangeDetector : NSObject +@interface WebViewURLChangeDetector : NSObject { juce::WebBrowserComponent* ownerComponent; } - (WebViewURLChangeDetector*) initWithWebBrowserOwner: (juce::WebBrowserComponent*) ownerComponent; -- (BOOL) webView: (UIWebView*) webView shouldStartLoadWithRequest: (NSURLRequest*) request navigationType: (UIWebViewNavigationType) navigationType; +- (BOOL) webView: (UIWebView*) webView shouldStartLoadWithRequest: (NSURLRequest*) request + navigationType: (UIWebViewNavigationType) navigationType; +- (void) webViewDidFinishLoad: (UIWebView*) webView; @end @implementation WebViewURLChangeDetector -- (WebViewURLChangeDetector*) initWithWebBrowserOwner: (juce::WebBrowserComponent*) ownerComponent_ +- (WebViewURLChangeDetector*) initWithWebBrowserOwner: (juce::WebBrowserComponent*) ownerComp { [super init]; - ownerComponent = ownerComponent_; + ownerComponent = ownerComp; return self; } -- (BOOL) webView: (UIWebView*) webView shouldStartLoadWithRequest: (NSURLRequest*) request navigationType: (UIWebViewNavigationType) navigationType +- (BOOL) webView: (UIWebView*) webView shouldStartLoadWithRequest: (NSURLRequest*) request + navigationType: (UIWebViewNavigationType) navigationType { (void) webView; (void) navigationType; return ownerComponent->pageAboutToLoad (nsStringToJuce (request.URL.absoluteString)); } + +- (void) webViewDidFinishLoad: (UIWebView*) webView +{ + ownerComponent->pageFinishedLoading (nsStringToJuce (webView.request.URL.absoluteString)); +} @end namespace juce { @@ -201,37 +224,45 @@ public: const StringArray* headers, const MemoryBlock* postData) { - NSMutableURLRequest* r - = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: juceStringToNS (url)] - cachePolicy: NSURLRequestUseProtocolCachePolicy - timeoutInterval: 30.0]; - - if (postData != nullptr && postData->getSize() > 0) - { - [r setHTTPMethod: nsStringLiteral ("POST")]; - [r setHTTPBody: [NSData dataWithBytes: postData->getData() - length: postData->getSize()]]; - } - - if (headers != nullptr) - { - for (int i = 0; i < headers->size(); ++i) - { - const String headerName ((*headers)[i].upToFirstOccurrenceOf (":", false, false).trim()); - const String headerValue ((*headers)[i].fromFirstOccurrenceOf (":", false, false).trim()); - - [r setValue: juceStringToNS (headerValue) - forHTTPHeaderField: juceStringToNS (headerName)]; - } - } - stop(); - #if JUCE_MAC - [[webView mainFrame] loadRequest: r]; - #else - [webView loadRequest: r]; - #endif + if (url.trimStart().startsWithIgnoreCase ("javascript:")) + { + [webView stringByEvaluatingJavaScriptFromString: + juceStringToNS (url.fromFirstOccurrenceOf (":", false, false))]; + } + else + { + NSMutableURLRequest* r + = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: juceStringToNS (url)] + cachePolicy: NSURLRequestUseProtocolCachePolicy + timeoutInterval: 30.0]; + + if (postData != nullptr && postData->getSize() > 0) + { + [r setHTTPMethod: nsStringLiteral ("POST")]; + [r setHTTPBody: [NSData dataWithBytes: postData->getData() + length: postData->getSize()]]; + } + + if (headers != nullptr) + { + for (int i = 0; i < headers->size(); ++i) + { + const String headerName ((*headers)[i].upToFirstOccurrenceOf (":", false, false).trim()); + const String headerValue ((*headers)[i].fromFirstOccurrenceOf (":", false, false).trim()); + + [r setValue: juceStringToNS (headerValue) + forHTTPHeaderField: juceStringToNS (headerName)]; + } + } + + #if JUCE_MAC + [[webView mainFrame] loadRequest: r]; + #else + [webView loadRequest: r]; + #endif + } } void goBack() { [webView goBack]; } @@ -377,3 +408,7 @@ void WebBrowserComponent::visibilityChanged() { checkWindowAssociation(); } + +void WebBrowserComponent::focusGained (FocusChangeType) +{ +} diff --git a/JuceLibraryCode/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp b/JuceLibraryCode/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp index 273d790..77a6f2e 100644 --- a/JuceLibraryCode/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp +++ b/JuceLibraryCode/modules/juce_gui_extra/native/juce_win32_WebBrowserComponent.cpp @@ -53,7 +53,7 @@ public: if (connectionPoint != nullptr) { - WebBrowserComponent* const owner = dynamic_cast (getParentComponent()); + WebBrowserComponent* const owner = dynamic_cast (getParentComponent()); jassert (owner != nullptr); EventHandler* handler = new EventHandler (*owner); @@ -129,13 +129,11 @@ private: DWORD adviseCookie; //============================================================================== - class EventHandler : public ComBaseClassHelper , + class EventHandler : public ComBaseClassHelper, public ComponentMovementWatcher { public: - EventHandler (WebBrowserComponent& owner_) - : ComponentMovementWatcher (&owner_), - owner (owner_) + EventHandler (WebBrowserComponent& w) : ComponentMovementWatcher (&w), owner (w) { } @@ -153,6 +151,13 @@ private: : VARIANT_TRUE; return S_OK; } + else if (dispIdMember == DISPID_NEWWINDOW3) + { + owner.newWindowAttemptingToLoad (pDispParams->rgvarg[0].bstrVal); + *pDispParams->rgvarg[3].pboolVal = VARIANT_TRUE; + + return S_OK; + } else if (dispIdMember == DISPID_DOCUMENTCOMPLETE) { owner.pageFinishedLoading (getStringFromVariant (pDispParams->rgvarg[0].pvarVal)); @@ -323,3 +328,26 @@ void WebBrowserComponent::visibilityChanged() { checkWindowAssociation(); } + +void WebBrowserComponent::focusGained (FocusChangeType) +{ + if (IOleObject* oleObject = (IOleObject*) browser->queryInterface (&IID_IOleObject)) + { + if (IOleWindow* oleWindow = (IOleWindow*) browser->queryInterface (&IID_IOleWindow)) + { + IOleClientSite* oleClientSite = nullptr; + + if (SUCCEEDED (oleObject->GetClientSite (&oleClientSite))) + { + HWND hwnd; + oleWindow->GetWindow (&hwnd); + oleObject->DoVerb (OLEIVERB_UIACTIVATE, nullptr, oleClientSite, 0, hwnd, nullptr); + oleClientSite->Release(); + } + + oleWindow->Release(); + } + + oleObject->Release(); + } +} diff --git a/JuceLibraryCode/modules/juce_opengl/juce_module_info b/JuceLibraryCode/modules/juce_opengl/juce_module_info index 092b308..b69a19a 100644 --- a/JuceLibraryCode/modules/juce_opengl/juce_module_info +++ b/JuceLibraryCode/modules/juce_opengl/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_opengl", "name": "JUCE OpenGL classes", - "version": "3.0.8", + "version": "3.1.1", "description": "Classes for rendering OpenGL in a JUCE window.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", @@ -14,6 +14,8 @@ { "file": "juce_opengl.mm", "target": "xcode" } ], "browse": [ "opengl/*", + "geometry/*", + "utils/*", "native/*" ], "OSXFrameworks": "OpenGL", diff --git a/JuceLibraryCode/modules/juce_opengl/juce_opengl.cpp b/JuceLibraryCode/modules/juce_opengl/juce_opengl.cpp index 77b2f3d..06bc5b0 100644 --- a/JuceLibraryCode/modules/juce_opengl/juce_opengl.cpp +++ b/JuceLibraryCode/modules/juce_opengl/juce_opengl.cpp @@ -207,5 +207,6 @@ private: #endif #include "opengl/juce_OpenGLContext.cpp" +#include "utils/juce_OpenGLAppComponent.cpp" } diff --git a/JuceLibraryCode/modules/juce_opengl/juce_opengl.h b/JuceLibraryCode/modules/juce_opengl/juce_opengl.h index bfeb599..9f61cc2 100644 --- a/JuceLibraryCode/modules/juce_opengl/juce_opengl.h +++ b/JuceLibraryCode/modules/juce_opengl/juce_opengl.h @@ -125,11 +125,12 @@ class OpenGLTexture; class OpenGLFrameBuffer; class OpenGLShaderProgram; +#include "geometry/juce_Quaternion.h" +#include "geometry/juce_Matrix3D.h" +#include "geometry/juce_Vector3D.h" +#include "geometry/juce_Draggable3DOrientation.h" #include "native/juce_MissingGLDefinitions.h" #include "opengl/juce_OpenGLHelpers.h" -#include "opengl/juce_Quaternion.h" -#include "opengl/juce_Matrix3D.h" -#include "opengl/juce_Draggable3DOrientation.h" #include "opengl/juce_OpenGLPixelFormat.h" #include "native/juce_OpenGLExtensions.h" #include "opengl/juce_OpenGLRenderer.h" @@ -141,7 +142,7 @@ class OpenGLShaderProgram; #include "opengl/juce_OpenGLRenderer.h" #include "opengl/juce_OpenGLShaderProgram.h" #include "opengl/juce_OpenGLTexture.h" -#include "opengl/juce_Vector3D.h" +#include "utils/juce_OpenGLAppComponent.h" } diff --git a/JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_osx.h b/JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_osx.h index baffcff..830b067 100644 --- a/JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_osx.h +++ b/JuceLibraryCode/modules/juce_opengl/native/juce_OpenGL_osx.h @@ -40,7 +40,6 @@ public: NSOpenGLPFAOpenGLProfile, version >= openGL3_2 ? NSOpenGLProfileVersion3_2Core : NSOpenGLProfileVersionLegacy, #endif NSOpenGLPFADoubleBuffer, - NSOpenGLPFAMPSafe, NSOpenGLPFAClosestPolicy, NSOpenGLPFANoRecovery, NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute) (pixFormat.redBits + pixFormat.greenBits + pixFormat.blueBits), diff --git a/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLContext.cpp b/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLContext.cpp index ee98359..60b25c1 100644 --- a/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLContext.cpp +++ b/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLContext.cpp @@ -262,7 +262,16 @@ public: glEnable (GL_TEXTURE_2D); clearGLError(); #endif - context.extensions.glActiveTexture (GL_TEXTURE0); + + #if JUCE_WINDOWS + // some stupidly old drivers are missing this function, so try to at least avoid a crash here, + // but if you hit this assertion you may want to have your own version check before using the + // component rendering stuff on such old drivers. + jassert (context.extensions.glActiveTexture != nullptr); + if (context.extensions.glActiveTexture != nullptr) + #endif + context.extensions.glActiveTexture (GL_TEXTURE0); + glBindTexture (GL_TEXTURE_2D, cachedImageFrameBuffer.getTextureID()); const Rectangle cacheBounds (cachedImageFrameBuffer.getWidth(), cachedImageFrameBuffer.getHeight()); diff --git a/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp b/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp index 8c8b4b6..659d6fe 100644 --- a/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp +++ b/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp @@ -38,18 +38,18 @@ struct TextureInfo struct CachedImageList : public ReferenceCountedObject, private ImagePixelData::Listener { - CachedImageList (size_t totalCacheSizeInPixels = 8 * 1024 * 1024) noexcept - : totalSize (0), maxCacheSize (totalCacheSizeInPixels) {} + CachedImageList (OpenGLContext& c, size_t totalCacheSizeInPixels = 8 * 1024 * 1024) noexcept + : context (c), totalSize (0), maxCacheSize (totalCacheSizeInPixels) {} - static CachedImageList* get (OpenGLContext& context) + static CachedImageList* get (OpenGLContext& c) { const char cacheValueID[] = "CachedImages"; - CachedImageList* list = static_cast (context.getAssociatedObject (cacheValueID)); + CachedImageList* list = static_cast (c.getAssociatedObject (cacheValueID)); if (list == nullptr) { - list = new CachedImageList(); - context.setAssociatedObject (cacheValueID, list); + list = new CachedImageList (c); + c.setAssociatedObject (cacheValueID, list); } return list; @@ -131,28 +131,45 @@ struct CachedImageList : public ReferenceCountedObject, typedef ReferenceCountedObjectPtr Ptr; private: + OpenGLContext& context; + OwnedArray images; + size_t totalSize, maxCacheSize; + + bool canUseContext() const noexcept + { + return OpenGLContext::getCurrentContext() == &context; + } + void imageDataChanged (ImagePixelData* im) override { if (CachedImage* c = findCachedImage (im)) - c->texture.release(); + if (canUseContext()) + c->texture.release(); } void imageDataBeingDeleted (ImagePixelData* im) override { for (int i = images.size(); --i >= 0;) { - if (images.getUnchecked(i)->pixelData == im) + CachedImage& ci = *images.getUnchecked(i); + + if (ci.pixelData == im) { - totalSize -= images.getUnchecked(i)->imageSize; - images.remove (i); + if (canUseContext()) + { + totalSize -= ci.imageSize; + images.remove (i); + } + else + { + ci.pixelData = nullptr; + } + break; } } } - OwnedArray images; - size_t totalSize, maxCacheSize; - CachedImage* findCachedImage (ImagePixelData* const pixelData) const { for (int i = 0; i < images.size(); ++i) diff --git a/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp b/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp index c7d709d..6f7edc4 100644 --- a/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp +++ b/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLShaderProgram.cpp @@ -135,13 +135,17 @@ void OpenGLShaderProgram::use() const noexcept OpenGLShaderProgram::Uniform::Uniform (const OpenGLShaderProgram& program, const char* const name) : uniformID (program.context.extensions.glGetUniformLocation (program.getProgramID(), name)), context (program.context) { + #if JUCE_DEBUG && ! JUCE_DONT_ASSERT_ON_GLSL_COMPILE_ERROR jassert (uniformID >= 0); + #endif } OpenGLShaderProgram::Attribute::Attribute (const OpenGLShaderProgram& program, const char* name) : attributeID (program.context.extensions.glGetAttribLocation (program.getProgramID(), name)) { + #if JUCE_DEBUG && ! JUCE_DONT_ASSERT_ON_GLSL_COMPILE_ERROR jassert (attributeID >= 0); + #endif } void OpenGLShaderProgram::Uniform::set (GLfloat n1) const noexcept { context.extensions.glUniform1f (uniformID, n1); } diff --git a/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp b/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp index aa44039..12dfee0 100644 --- a/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp +++ b/JuceLibraryCode/modules/juce_opengl/opengl/juce_OpenGLTexture.cpp @@ -164,14 +164,21 @@ void OpenGLTexture::loadARGBFlipped (const PixelARGB* pixels, int w, int h) void OpenGLTexture::release() { - if (textureID != 0 - && ownerContext == OpenGLContext::getCurrentContext()) + if (textureID != 0) { - glDeleteTextures (1, &textureID); + // If the texture is deleted while the owner context is not active, it's + // impossible to delete it, so this will be a leak until the context itself + // is deleted. + jassert (ownerContext == OpenGLContext::getCurrentContext()); - textureID = 0; - width = 0; - height = 0; + if (ownerContext == OpenGLContext::getCurrentContext()) + { + glDeleteTextures (1, &textureID); + + textureID = 0; + width = 0; + height = 0; + } } } diff --git a/JuceLibraryCode/modules/juce_video/juce_module_info b/JuceLibraryCode/modules/juce_video/juce_module_info index ce7a257..afce42b 100644 --- a/JuceLibraryCode/modules/juce_video/juce_module_info +++ b/JuceLibraryCode/modules/juce_video/juce_module_info @@ -1,7 +1,7 @@ { "id": "juce_video", "name": "JUCE video playback and capture classes", - "version": "3.0.8", + "version": "3.1.1", "description": "Classes for playing video and capturing camera input.", "website": "http://www.juce.com/juce", "license": "GPL/Commercial", diff --git a/JuceLibraryCode/modules/juce_video/native/juce_win32_DirectShowComponent.cpp b/JuceLibraryCode/modules/juce_video/native/juce_win32_DirectShowComponent.cpp index 5762459..e1489d8 100644 --- a/JuceLibraryCode/modules/juce_video/native/juce_win32_DirectShowComponent.cpp +++ b/JuceLibraryCode/modules/juce_video/native/juce_win32_DirectShowComponent.cpp @@ -530,7 +530,7 @@ private: bool isRegistered() const noexcept { return atom != 0; } LPCTSTR getWindowClassName() const noexcept { return (LPCTSTR) MAKELONG (atom, 0); } - juce_DeclareSingleton_SingleThreaded_Minimal (NativeWindowClass); + juce_DeclareSingleton_SingleThreaded_Minimal (NativeWindowClass) private: NativeWindowClass() @@ -724,7 +724,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DirectShowContext) }; -juce_ImplementSingleton_SingleThreaded (DirectShowComponent::DirectShowContext::NativeWindowClass); +juce_ImplementSingleton_SingleThreaded (DirectShowComponent::DirectShowContext::NativeWindowClass) //======================================================================