- updated

git-svn-id: http://moon:8086/svn/software/trunk/projects/mpsk_rx_gui@117 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
2015-01-05 13:35:46 +00:00
parent 3b38c6a587
commit 6e5aa7a991
156 changed files with 2332 additions and 1370 deletions
+3 -3
View File
@@ -49,15 +49,15 @@
#endif #endif
#ifndef JUCE_DIRECTSOUND #ifndef JUCE_DIRECTSOUND
//#define JUCE_DIRECTSOUND #define JUCE_DIRECTSOUND 1
#endif #endif
#ifndef JUCE_ALSA #ifndef JUCE_ALSA
#define JUCE_ALSA 0 //#define JUCE_ALSA
#endif #endif
#ifndef JUCE_JACK #ifndef JUCE_JACK
#define JUCE_JACK 1 //#define JUCE_JACK
#endif #endif
#ifndef JUCE_USE_ANDROID_OPENSLES #ifndef JUCE_USE_ANDROID_OPENSLES
-2
View File
@@ -35,13 +35,11 @@
using namespace juce; using namespace juce;
#endif #endif
#if ! JUCE_DONT_DECLARE_PROJECTINFO
namespace ProjectInfo namespace ProjectInfo
{ {
const char* const projectName = "M-QAM Transceiver"; const char* const projectName = "M-QAM Transceiver";
const char* const versionString = "1.0.0"; const char* const versionString = "1.0.0";
const int versionNumber = 0x10000; const int versionNumber = 0x10000;
} }
#endif
#endif // __APPHEADERFILE_GMZMR9__ #endif // __APPHEADERFILE_GMZMR9__
@@ -23,7 +23,7 @@
*/ */
#if JUCE_INTEL #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 #else
#define JUCE_SNAP_TO_ZERO(n) #define JUCE_SNAP_TO_ZERO(n)
#endif #endif
@@ -64,7 +64,7 @@ IIRCoefficients IIRCoefficients::makeLowPass (const double sampleRate,
{ {
jassert (sampleRate > 0); 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 nSquared = n * n;
const double c1 = 1.0 / (1.0 + std::sqrt (2.0) * n + nSquared); 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, IIRCoefficients IIRCoefficients::makeHighPass (const double sampleRate,
const double frequency) noexcept 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 nSquared = n * n;
const double c1 = 1.0 / (1.0 + std::sqrt (2.0) * n + nSquared); const double c1 = 1.0 / (1.0 + std::sqrt (2.0) * n + nSquared);
@@ -82,12 +82,13 @@ public:
const float dryScaleFactor = 2.0f; const float dryScaleFactor = 2.0f;
const float wet = newParams.wetLevel * wetScaleFactor; const float wet = newParams.wetLevel * wetScaleFactor;
wet1 = wet * (newParams.width * 0.5f + 0.5f); dryGain.setValue (newParams.dryLevel * dryScaleFactor);
wet2 = wet * (1.0f - newParams.width) * 0.5f; wetGain1.setValue (0.5f * wet * (1.0f + newParams.width));
dry = newParams.dryLevel * dryScaleFactor; wetGain2.setValue (0.5f * wet * (1.0f - newParams.width));
gain = isFrozen (newParams.freezeMode) ? 0.0f : 0.015f; gain = isFrozen (newParams.freezeMode) ? 0.0f : 0.015f;
parameters = newParams; parameters = newParams;
shouldUpdateDamping = true; updateDamping();
} }
//============================================================================== //==============================================================================
@@ -115,7 +116,12 @@ public:
allPass[1][i].setSize ((intSampleRate * (allPassTunings[i] + stereoSpread)) / 44100); 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. */ /** Clears the reverb's buffers. */
@@ -137,18 +143,18 @@ public:
{ {
jassert (left != nullptr && right != nullptr); jassert (left != nullptr && right != nullptr);
if (shouldUpdateDamping)
updateDamping();
for (int i = 0; i < numSamples; ++i) for (int i = 0; i < numSamples; ++i)
{ {
const float input = (left[i] + right[i]) * gain; const float input = (left[i] + right[i]) * gain;
float outL = 0, outR = 0; 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 for (int j = 0; j < numCombs; ++j) // accumulate the comb filters in parallel
{ {
outL += comb[0][j].process (input); outL += comb[0][j].process (input, damp, feedbck);
outR += comb[1][j].process (input); outR += comb[1][j].process (input, damp, feedbck);
} }
for (int j = 0; j < numAllPasses; ++j) // run the allpass filters in series for (int j = 0; j < numAllPasses; ++j) // run the allpass filters in series
@@ -157,6 +163,10 @@ public:
outR = allPass[1][j].process (outR); 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; left[i] = outL * wet1 + outR * wet2 + left[i] * dry;
right[i] = outR * wet1 + outL * wet2 + right[i] * dry; right[i] = outR * wet1 + outL * wet2 + right[i] * dry;
} }
@@ -167,32 +177,30 @@ public:
{ {
jassert (samples != nullptr); jassert (samples != nullptr);
if (shouldUpdateDamping)
updateDamping();
for (int i = 0; i < numSamples; ++i) for (int i = 0; i < numSamples; ++i)
{ {
const float input = samples[i] * gain; const float input = samples[i] * gain;
float output = 0; 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 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 for (int j = 0; j < numAllPasses; ++j) // run the allpass filters in series
output = allPass[0][j].process (output); output = allPass[0][j].process (output);
const float dry = dryGain.getNextValue();
const float wet1 = wetGain1.getNextValue();
samples[i] = output * wet1 + samples[i] * dry; samples[i] = output * wet1 + samples[i] * dry;
} }
} }
private: private:
//============================================================================== //==============================================================================
Parameters parameters; static bool isFrozen (const float freezeMode) noexcept { return freezeMode >= 0.5f; }
volatile bool shouldUpdateDamping;
float gain, wet1, wet2, dry;
inline static bool isFrozen (const float freezeMode) noexcept { return freezeMode >= 0.5f; }
void updateDamping() noexcept void updateDamping() noexcept
{ {
@@ -200,8 +208,6 @@ private:
const float roomOffset = 0.7f; const float roomOffset = 0.7f;
const float dampScaleFactor = 0.4f; const float dampScaleFactor = 0.4f;
shouldUpdateDamping = false;
if (isFrozen (parameters.freezeMode)) if (isFrozen (parameters.freezeMode))
setDamping (0.0f, 1.0f); setDamping (0.0f, 1.0f);
else else
@@ -211,19 +217,15 @@ private:
void setDamping (const float dampingToUse, const float roomSizeToUse) noexcept void setDamping (const float dampingToUse, const float roomSizeToUse) noexcept
{ {
for (int j = 0; j < numChannels; ++j) damping.setValue (dampingToUse);
for (int i = numCombs; --i >= 0;) feedback.setValue (roomSizeToUse);
comb[j][i].setFeedbackAndDamp (roomSizeToUse, dampingToUse);
} }
//============================================================================== //==============================================================================
class CombFilter class CombFilter
{ {
public: public:
CombFilter() noexcept CombFilter() noexcept : bufferSize (0), bufferIndex (0), last (0) {}
: bufferSize (0), bufferIndex (0),
feedback (0), last (0), damp1 (0), damp2 (0)
{}
void setSize (const int size) void setSize (const int size)
{ {
@@ -243,22 +245,15 @@ private:
buffer.clear ((size_t) bufferSize); 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; const float output = buffer[bufferIndex];
damp2 = 1.0f - d; last = (output * (1.0f - damp)) + (last * damp);
feedback = f;
}
inline float process (const float input) noexcept
{
const float output = buffer [bufferIndex];
last = (output * damp2) + (last * damp1);
JUCE_UNDENORMALISE (last); JUCE_UNDENORMALISE (last);
float temp = input + (last * feedback); float temp = input + (last * feedbackLevel);
JUCE_UNDENORMALISE (temp); JUCE_UNDENORMALISE (temp);
buffer [bufferIndex] = temp; buffer[bufferIndex] = temp;
bufferIndex = (bufferIndex + 1) % bufferSize; bufferIndex = (bufferIndex + 1) % bufferSize;
return output; return output;
} }
@@ -266,7 +261,7 @@ private:
private: private:
HeapBlock<float> buffer; HeapBlock<float> buffer;
int bufferSize, bufferIndex; int bufferSize, bufferIndex;
float feedback, last, damp1, damp2; float last;
JUCE_DECLARE_NON_COPYABLE (CombFilter) JUCE_DECLARE_NON_COPYABLE (CombFilter)
}; };
@@ -294,7 +289,7 @@ private:
buffer.clear ((size_t) bufferSize); buffer.clear ((size_t) bufferSize);
} }
inline float process (const float input) noexcept float process (const float input) noexcept
{ {
const float bufferedValue = buffer [bufferIndex]; const float bufferedValue = buffer [bufferIndex];
float temp = input + (bufferedValue * 0.5f); float temp = input + (bufferedValue * 0.5f);
@@ -311,11 +306,65 @@ private:
JUCE_DECLARE_NON_COPYABLE (AllPassFilter) 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 }; enum { numCombs = 8, numAllPasses = 4, numChannels = 2 };
Parameters parameters;
float gain;
CombFilter comb [numChannels][numCombs]; CombFilter comb [numChannels][numCombs];
AllPassFilter allPass [numChannels][numAllPasses]; AllPassFilter allPass [numChannels][numAllPasses];
LinearSmoothedValue damping, feedback, dryGain, wetGain1, wetGain2;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Reverb) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Reverb)
}; };
@@ -1,7 +1,7 @@
{ {
"id": "juce_audio_basics", "id": "juce_audio_basics",
"name": "JUCE audio and midi data classes", "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", "description": "Classes for audio buffer manipulation, midi message handling, synthesis, etc",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",
@@ -93,7 +93,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf
lastRatio = localRatio; lastRatio = localRatio;
} }
const int sampsNeeded = roundToInt (info.numSamples * localRatio) + 2; const int sampsNeeded = roundToInt (info.numSamples * localRatio) + 3;
int bufferSize = buffer.getNumSamples(); int bufferSize = buffer.getNumSamples();
@@ -138,8 +138,11 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf
} }
int nextPos = (bufferPos + 1) % bufferSize; int nextPos = (bufferPos + 1) % bufferSize;
for (int m = info.numSamples; --m >= 0;) for (int m = info.numSamples; --m >= 0;)
{ {
jassert (sampsInBuffer > 0 && nextPos != endOfBufferPos);
const float alpha = (float) subSampleOffset; const float alpha = (float) subSampleOffset;
for (int channel = 0; channel < channelsToProcess; ++channel) for (int channel = 0; channel < channelsToProcess; ++channel)
@@ -148,8 +151,6 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf
subSampleOffset += localRatio; subSampleOffset += localRatio;
jassert (sampsInBuffer > 0);
while (subSampleOffset >= 1.0) while (subSampleOffset >= 1.0)
{ {
if (++bufferPos >= bufferSize) if (++bufferPos >= bufferSize)
@@ -50,6 +50,11 @@ void SynthesiserVoice::setCurrentPlaybackSampleRate (const double newRate)
currentSampleRate = newRate; currentSampleRate = newRate;
} }
bool SynthesiserVoice::isVoiceActive() const
{
return getCurrentlyPlayingNote() >= 0;
}
void SynthesiserVoice::clearCurrentNote() void SynthesiserVoice::clearCurrentNote()
{ {
currentlyPlayingNote = -1; currentlyPlayingNote = -1;
@@ -426,7 +431,7 @@ SynthesiserVoice* Synthesiser::findFreeVoice (SynthesiserSound* soundToPlay,
{ {
SynthesiserVoice* const voice = voices.getUnchecked (i); SynthesiserVoice* const voice = voices.getUnchecked (i);
if (voice->getCurrentlyPlayingNote() < 0 && voice->canPlaySound (soundToPlay)) if ((! voice->isVoiceActive()) && voice->canPlaySound (soundToPlay))
return voice; return voice;
} }
@@ -140,6 +140,12 @@ public:
*/ */
virtual void stopNote (float velocity, bool allowTailOff) = 0; 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. /** 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. 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); 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 /** Returns true if the voice is currently playing a sound which is mapped to the given
midi channel. midi channel.
If it's not currently playing, this will return false. 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. /** 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 Note that the voice may still be playing after the key was released (e.g because the
@@ -1,7 +1,7 @@
{ {
"id": "juce_audio_devices", "id": "juce_audio_devices",
"name": "JUCE audio and midi I/O device classes", "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.", "description": "Classes to play and record from audio and midi i/o devices.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",
@@ -30,7 +30,7 @@ namespace
#endif #endif
#if JUCE_ALSA_LOGGING #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__)) #define JUCE_CHECKED_RESULT(x) (logErrorMessage (x, __LINE__))
static int logErrorMessage (int err, int lineNum) static int logErrorMessage (int err, int lineNum)
@@ -419,7 +419,7 @@ public:
port.deletePort(); port.deletePort();
} }
void sendMessageNow (const MidiMessage& message) bool sendMessageNow (const MidiMessage& message)
{ {
if (message.getRawDataSize() > maxEventSize) if (message.getRawDataSize() > maxEventSize)
{ {
@@ -435,12 +435,17 @@ public:
const uint8* data = message.getRawData(); const uint8* data = message.getRawData();
snd_seq_t* seqHandle = port.client->get(); snd_seq_t* seqHandle = port.client->get();
bool success = true;
while (numBytes > 0) while (numBytes > 0)
{ {
const long numSent = snd_midi_event_encode (midiParser, data, numBytes, &event); const long numSent = snd_midi_event_encode (midiParser, data, numBytes, &event);
if (numSent <= 0) if (numSent <= 0)
{
success = numSent == 0;
break; break;
}
numBytes -= numSent; numBytes -= numSent;
data += numSent; data += numSent;
@@ -449,11 +454,15 @@ public:
snd_seq_ev_set_subs (&event); snd_seq_ev_set_subs (&event);
snd_seq_ev_set_direct (&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); snd_midi_event_reset_encode (midiParser);
return success;
} }
private: private:
@@ -1255,7 +1255,7 @@ private:
DSoundDeviceList deviceList; DSoundDeviceList deviceList;
bool hasScanned; bool hasScanned;
void systemDeviceChanged() void systemDeviceChanged() override
{ {
DSoundDeviceList newList; DSoundDeviceList newList;
newList.scan(); newList.scan();
@@ -1418,7 +1418,7 @@ private:
} }
//============================================================================== //==============================================================================
void systemDeviceChanged() void systemDeviceChanged() override
{ {
StringArray newOutNames, newInNames, newOutIds, newInIds; StringArray newOutNames, newInNames, newOutIds, newInIds;
scan (newOutNames, newInNames, newOutIds, newInIds); scan (newOutNames, newInNames, newOutIds, newInIds);
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -1,6 +1,6 @@
/* alloc - Convenience routines for safely allocating memory /* alloc - Convenience routines for safely allocating memory
* Copyright (C) 2007-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -33,7 +33,7 @@
#ifndef FLAC__SHARE__ALLOC_H #ifndef FLAC__SHARE__ALLOC_H
#define FLAC__SHARE__ALLOC_H #define FLAC__SHARE__ALLOC_H
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2004-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -1,5 +1,5 @@
/* libFLAC - Free Lossless Audio Codec library /* 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -73,23 +73,25 @@
#endif #endif
#if defined(_MSC_VER) #if defined(_MSC_VER)
#if _MSC_VER < 1500
/* Visual Studio 2008 has restrict. */
#define restrict __restrict
#endif
#define inline __inline #define inline __inline
#endif #endif
/* adjust for compilers that can't understand using LLU suffix for uint64_t literals */ #if defined __INTEL_COMPILER || (defined _MSC_VER && defined _WIN64)
#ifdef _MSC_VER /* MSVS generates VERY slow 32-bit code with __restrict */
#define FLAC__U64L(x) x #define flac_restrict __restrict
#elif defined __GNUC__
#define flac_restrict __restrict__
#else #else
#define FLAC__U64L(x) x##LLU #define flac_restrict
#endif #endif
#define FLAC__U64L(x) x##ULL
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__ #if defined _MSC_VER || defined __BORLANDC__ || defined __MINGW32__
#define FLAC__STRCASECMP stricmp
#define FLAC__STRNCASECMP strnicmp #define FLAC__STRNCASECMP strnicmp
#else #else
#define FLAC__STRCASECMP strcasecmp
#define FLAC__STRNCASECMP strncasecmp #define FLAC__STRNCASECMP strncasecmp
#endif #endif
@@ -139,6 +141,7 @@
#ifdef _WIN32 #ifdef _WIN32
/* All char* strings are in UTF-8 format. Added to support Unicode files on Windows */ /* 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_printf printf_utf8
#define flac_fprintf fprintf_utf8 #define flac_fprintf fprintf_utf8
@@ -160,12 +163,7 @@
#define flac_utime utime #define flac_utime utime
#define flac_unlink unlink #define flac_unlink unlink
#define flac_rename rename #define flac_rename rename
#ifdef _WIN32
#define flac_stat _stat64
#else
#define flac_stat stat #define flac_stat stat
#endif
#endif #endif
@@ -177,8 +175,14 @@
#define flac_fstat fstat #define flac_fstat fstat
#endif #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 * snprintf as well as Microsoft Visual Studio which has an non-standards
* conformant snprint_s function. * conformant snprint_s function.
* *
@@ -188,6 +192,7 @@
extern "C" { extern "C" {
#endif #endif
int flac_snprintf(char *str, size_t size, const char *fmt, ...); 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 #ifdef __cplusplus
}; };
#endif #endif
@@ -1,5 +1,5 @@
/* libFLAC - Free Lossless Audio Codec library /* 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -33,20 +33,46 @@
#if HAVE_BSWAP32 /* GCC and Clang */ #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)) #define ENDSWAP_32(x) (__builtin_bswap32 (x))
#elif defined _MSC_VER /* Windows. Apparently in <stdlib.h>. */ #elif defined _MSC_VER /* Windows. Apparently in <stdlib.h>. */
#define ENDSWAP_16(x) (_byteswap_ushort (x))
#define ENDSWAP_32(x) (_byteswap_ulong (x)) #define ENDSWAP_32(x) (_byteswap_ulong (x))
#elif defined HAVE_BYTESWAP_H /* Linux */ #elif defined HAVE_BYTESWAP_H /* Linux */
#include <byteswap.h> #include <byteswap.h>
#define ENDSWAP_16(x) (bswap_16 (x))
#define ENDSWAP_32(x) (bswap_32 (x)) #define ENDSWAP_32(x) (bswap_32 (x))
#else #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 #endif
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -61,9 +61,9 @@
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
#ifdef FLAC_API_EXPORTS #ifdef FLAC_API_EXPORTS
#define FLAC_API _declspec(dllexport) #define FLAC_API __declspec(dllexport)
#else #else
#define FLAC_API _declspec(dllimport) #define FLAC_API __declspec(dllimport)
#endif #endif
#elif defined(FLAC__USE_VISIBILITY_ATTR) #elif defined(FLAC__USE_VISIBILITY_ATTR)
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -509,9 +509,11 @@ typedef enum {
FLAC__METADATA_TYPE_PICTURE = 6, FLAC__METADATA_TYPE_PICTURE = 6,
/**< <A HREF="../format.html#metadata_block_picture">PICTURE</A> block */ /**< <A HREF="../format.html#metadata_block_picture">PICTURE</A> 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 */ /**< 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; } FLAC__MetadataType;
/** Maps a FLAC__MetadataType to a C string. /** Maps a FLAC__MetadataType to a C string.
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -30,12 +30,11 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
#include "include/private/bitmath.h" #include "include/private/bitmath.h"
#include "../assert.h"
/* An example of what FLAC__bitmath_silog2() computes: /* An example of what FLAC__bitmath_silog2() computes:
* *
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@@ -73,7 +73,6 @@
*/ */
static const unsigned FLAC__BITREADER_DEFAULT_CAPACITY = 65536u / FLAC__BITS_PER_WORD; /* in words */ 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 { struct FLAC__BitReader {
/* any partially-consumed word at the head will stay right-justified as bits are consumed from the left */ /* 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 */ /* 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 */ unsigned crc16_align; /* the number of bits in the current consumed word that should not be CRC'd */
FLAC__BitReaderReadCallback read_callback; FLAC__BitReaderReadCallback read_callback;
void *client_data; void *client_data;
FLAC__CPUInfo cpu_info;
}; };
static inline void crc16_update_word_(FLAC__BitReader *br, uint32_t word) 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; br->crc16_align = 0;
} }
/* would be static except it needs to be called by asm routines */ static FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br)
FLAC__bool bitreader_read_from_client_(FLAC__BitReader *br)
{ {
unsigned start, end; unsigned start, end;
size_t bytes; 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); FLAC__ASSERT(0 != br);
@@ -243,7 +240,6 @@ FLAC__bool FLAC__bitreader_init(FLAC__BitReader *br, FLAC__CPUInfo cpu, FLAC__Bi
return false; return false;
br->read_callback = rcb; br->read_callback = rcb;
br->client_data = cd; br->client_data = cd;
br->cpu_info = cpu;
return true; return true;
} }
@@ -1048,9 +1044,9 @@ FLAC__bool FLAC__bitreader_read_utf8_uint64(FLAC__BitReader *br, FLAC__uint64 *v
return true; 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. * 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 * prototype in a header file without 'inline' and making the function inline
* in this file should be sufficient. * in this file should be sufficient.
* Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To * Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #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: 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 */ /* 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 #define FLAC__BYTES_PER_WORD 4
#undef FLAC__BITS_PER_WORD #define FLAC__BITS_PER_WORD (8 * FLAC__BYTES_PER_WORD)
#define FLAC__BITS_PER_WORD 32
#define FLAC__WORD_ALL_ONES ((FLAC__uint32)0xffffffff) #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 */ /* 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 #if WORDS_BIGENDIAN
@@ -524,28 +523,6 @@ FLAC__bool FLAC__bitwriter_write_rice_signed_block(FLAC__BitWriter *bw, const FL
msbits = uval >> parameter; 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 && 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 */ /* ^^^ 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; 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; bw->accum |= uval;
} }
else { else {
#endif
/* slightly pessimistic size check but faster than "<= bw->words + (bw->bits+msbits+lsbits+FLAC__BITS_PER_WORD-1)/FLAC__BITS_PER_WORD" */ /* 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 */ /* 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)) 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->buffer[bw->words++] = SWAP_BE_WORD_TO_HOST(bw->accum);
bw->accum = uval; bw->accum = uval;
} }
#if 1
} }
#endif
vals++; vals++;
nvals--; nvals--;
} }
@@ -853,9 +827,9 @@ FLAC__bool FLAC__bitwriter_zero_pad_to_byte_boundary(FLAC__BitWriter *bw)
return true; 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. * 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 * prototype in a header file without 'inline' and making the function inline
* in this file should be sufficient. * in this file should be sufficient.
* Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To * Unfortunately, the Microsoft VS compiler doesn't pick them up externally. To
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -30,47 +30,47 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
#include "include/private/cpu.h" #include "include/private/cpu.h"
#include <stdlib.h>
#include <stdio.h> #if 0
#include <stdlib.h>
#include <memory.h>
#include <stdio.h>
#endif
#if defined FLAC__CPU_IA32 #if defined FLAC__CPU_IA32
# include <signal.h> # include <signal.h>
#elif defined FLAC__CPU_PPC
# if !defined FLAC__NO_ASM
# if defined FLAC__SYS_DARWIN
# include <sys/sysctl.h>
# include <mach/mach.h>
# include <mach/mach_host.h>
# include <mach/host_info.h>
# include <mach/machine.h>
# ifndef CPU_SUBTYPE_POWERPC_970
# define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100)
# endif
# else /* FLAC__SYS_DARWIN */
# include <signal.h> static void disable_sse(FLAC__CPUInfo *info)
# include <setjmp.h>
static sigjmp_buf jmpbuf;
static volatile sig_atomic_t canjump = 0;
static void sigill_handler (int sig)
{ {
if (!canjump) { info->ia32.sse = false;
signal (sig, SIG_DFL); info->ia32.sse2 = false;
raise (sig); info->ia32.sse3 = false;
} info->ia32.ssse3 = false;
canjump = 0; info->ia32.sse41 = false;
siglongjmp (jmpbuf, 1); info->ia32.sse42 = false;
} }
# endif /* FLAC__SYS_DARWIN */
# endif /* FLAC__NO_ASM */ static void disable_avx(FLAC__CPUInfo *info)
#endif /* FLAC__CPU_PPC */ {
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__) #if defined (__NetBSD__) || defined(__OpenBSD__)
#include <sys/param.h> #include <sys/param.h>
@@ -87,25 +87,34 @@ static void sigill_handler (int sig)
/* how to get sysctlbyname()? */ /* how to get sysctlbyname()? */
#endif #endif
#ifdef FLAC__CPU_IA32
/* these are flags in EDX of CPUID AX=00000001 */ /* 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_CMOV = 0x00008000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_MMX = 0x00800000; 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_FXSR = 0x01000000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000; static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE = 0x02000000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000; static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE2 = 0x04000000;
#endif
/* these are flags in ECX of CPUID AX=00000001 */ /* 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_SSE3 = 0x00000001;
static const unsigned FLAC__CPUINFO_IA32_CPUID_SSSE3 = 0x00000200; 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_SSE41 = 0x00080000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_3DNOW = 0x80000000; static const unsigned FLAC__CPUINFO_IA32_CPUID_SSE42 = 0x00100000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXT3DNOW = 0x40000000;
static const unsigned FLAC__CPUINFO_IA32_CPUID_EXTENDED_AMD_EXTMMX = 0x00400000;
#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 * 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 defined(__linux__)
/* /*
* If the OS doesn't support SSE, we will get here with a SIGILL. We * 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 * 6 bytes extra in case our estimate is wrong
* 12 bytes puts us in the NOP "landing zone" * 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 <sys/ucontext.h> # include <sys/ucontext.h>
static void sigill_handler_sse_os(int signal, siginfo_t *si, void *uc) static void sigill_handler_sse_os(int signal, siginfo_t *si, void *uc)
{ {
(void)signal, (void)si; (void)signal, (void)si;
((ucontext_t*)uc)->uc_mcontext.gregs[14/*REG_EIP*/] += 3 + 3 + 6; ((ucontext_t*)uc)->uc_mcontext.gregs[14/*REG_EIP*/] += 3 + 3 + 6;
} }
# endif
# elif defined(_MSC_VER) # elif defined(_MSC_VER)
# include <windows.h> # include <windows.h>
# 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
#endif #endif
@@ -159,261 +147,344 @@ void FLAC__cpu_info(FLAC__CPUInfo *info)
* IA32-specific * IA32-specific
*/ */
#ifdef FLAC__CPU_IA32 #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; 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->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; #ifdef FLAC__HAS_X86INTRIN
info->data.ia32.bswap = info->data.ia32.cpuid; /* CPUID => BSWAP since it came after */ if(!FLAC__cpu_have_cpuid_x86())
info->data.ia32.cmov = false; return;
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;
#else #else
info->data.ia32._3dnow = info->data.ia32.ext3dnow = info->data.ia32.extmmx = false; if(!FLAC__cpu_have_cpuid_asm_ia32())
return;
#endif #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 #ifdef DEBUG
fprintf(stderr, "CPU info (IA-32):\n"); fprintf(stderr, "CPU info (IA-32):\n");
fprintf(stderr, " CPUID ...... %c\n", info->data.ia32.cpuid ? 'Y' : 'n'); fprintf(stderr, " CMOV ....... %c\n", info->ia32.cmov ? 'Y' : 'n');
fprintf(stderr, " BSWAP ...... %c\n", info->data.ia32.bswap ? 'Y' : 'n'); fprintf(stderr, " MMX ........ %c\n", info->ia32.mmx ? 'Y' : 'n');
fprintf(stderr, " CMOV ....... %c\n", info->data.ia32.cmov ? 'Y' : 'n'); fprintf(stderr, " SSE ........ %c\n", info->ia32.sse ? 'Y' : 'n');
fprintf(stderr, " MMX ........ %c\n", info->data.ia32.mmx ? 'Y' : 'n'); fprintf(stderr, " SSE2 ....... %c\n", info->ia32.sse2 ? 'Y' : 'n');
fprintf(stderr, " FXSR ....... %c\n", info->data.ia32.fxsr ? 'Y' : 'n'); fprintf(stderr, " SSE3 ....... %c\n", info->ia32.sse3 ? 'Y' : 'n');
fprintf(stderr, " SSE ........ %c\n", info->data.ia32.sse ? 'Y' : 'n'); fprintf(stderr, " SSSE3 ...... %c\n", info->ia32.ssse3 ? 'Y' : 'n');
fprintf(stderr, " SSE2 ....... %c\n", info->data.ia32.sse2 ? 'Y' : 'n'); fprintf(stderr, " SSE41 ...... %c\n", info->ia32.sse41 ? 'Y' : 'n');
fprintf(stderr, " SSE3 ....... %c\n", info->data.ia32.sse3 ? 'Y' : 'n'); fprintf(stderr, " SSE42 ...... %c\n", info->ia32.sse42 ? 'Y' : 'n');
fprintf(stderr, " SSSE3 ...... %c\n", info->data.ia32.ssse3 ? 'Y' : 'n'); # if defined FLAC__HAS_X86INTRIN && defined FLAC__AVX_SUPPORTED
fprintf(stderr, " 3DNow! ..... %c\n", info->data.ia32._3dnow ? 'Y' : 'n'); fprintf(stderr, " AVX ........ %c\n", info->ia32.avx ? 'Y' : 'n');
fprintf(stderr, " 3DNow!-ext . %c\n", info->data.ia32.ext3dnow? 'Y' : 'n'); fprintf(stderr, " FMA ........ %c\n", info->ia32.fma ? 'Y' : 'n');
fprintf(stderr, " 3DNow!-MMX . %c\n", info->data.ia32.extmmx ? 'Y' : 'n'); fprintf(stderr, " AVX2 ....... %c\n", info->ia32.avx2 ? 'Y' : 'n');
# endif
#endif #endif
/* /*
* now have to check for OS support of SSE/SSE2 * now have to check for OS support of SSE instructions
*/ */
if(info->data.ia32.fxsr || info->data.ia32.sse || info->data.ia32.sse2) { if(info->ia32.sse) {
#if defined FLAC__NO_SSE_OS #if defined FLAC__NO_SSE_OS
/* assume user knows better than us; turn it off */ /* 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; disable_sse(info);
#elif defined FLAC__SSE_OS #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__) #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__APPLE__)
int sse = 0; int sse = 0;
size_t len; size_t len;
/* at least one of these must work: */ /* 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.instruction_sse", &sse, &len, NULL, 0) == 0 && sse);
len = sizeof(sse); sse = sse || (sysctlbyname("hw.optional.sse" , &sse, &len, NULL, 0) == 0 && sse); /* __APPLE__ ? */ len = sizeof(sse); sse = sse || (sysctlbyname("hw.optional.sse" , &sse, &len, NULL, 0) == 0 && sse); /* __APPLE__ ? */
if(!sse) if(!sse)
info->data.ia32.fxsr = info->data.ia32.sse = info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; disable_sse(info);
#elif defined(__NetBSD__) || defined (__OpenBSD__) #elif defined(__NetBSD__) || defined (__OpenBSD__)
# if __NetBSD_Version__ >= 105250000 || (defined __OpenBSD__) # if __NetBSD_Version__ >= 105250000 || (defined __OpenBSD__)
int val = 0, mib[2] = { CTL_MACHDEP, CPU_SSE }; int val = 0, mib[2] = { CTL_MACHDEP, CPU_SSE };
size_t len = sizeof(val); size_t len = sizeof(val);
if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !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; disable_sse(info);
else { /* double-check SSE2 */ else { /* double-check SSE2 */
mib[1] = CPU_SSE2; mib[1] = CPU_SSE2;
len = sizeof(val); len = sizeof(val);
if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) if(sysctl(mib, 2, &val, &len, NULL, 0) < 0 || !val) {
info->data.ia32.sse2 = info->data.ia32.sse3 = info->data.ia32.ssse3 = false; disable_sse(info);
info->ia32.sse = true;
} }
}
# else # 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 # endif
#elif defined(__linux__) #elif defined(__linux__)
int sse = 0; int sse = 0;
struct sigaction sigill_save; struct sigaction sigill_save;
#ifdef USE_OBSOLETE_SIGCONTEXT_FLAVOR struct sigaction sigill_sse;
if(0 == sigaction(SIGILL, NULL, &sigill_save) && signal(SIGILL, (void (*)(int))sigill_handler_sse_os) != SIG_ERR) sigill_sse.sa_sigaction = sigill_handler_sse_os;
#else __sigemptyset(&sigill_sse.sa_mask);
struct sigaction sigill_sse; 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 */
sigill_sse.sa_sigaction = sigill_handler_sse_os; if(0 == sigaction(SIGILL, &sigill_sse, &sigill_save))
__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 */ /* http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html */
if(0 == sigaction(SIGILL, &sigill_sse, &sigill_save)) /* see sigill_handler_sse_os() for an explanation of the following: */
#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;
asm volatile ( asm volatile (
"mtspr 256, %0\n\t" "xorps %%xmm0,%%xmm0\n\t" /* will cause SIGILL if unsupported by OS */
"vand %%v0, %%v0, %%v0" "incl %0\n\t" /* SIGILL handler will jump over this */
: /* landing zone */
: "r" (-1) "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 */ if(!sse)
asm volatile ("cntlzd %0, %1" : "=r" (x) : "r" (x) ); disable_sse(info);
#elif defined(_MSC_VER)
info->data.ppc.ppc64 = 1; __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 /* info->ia32.sse == false */
# else /* !FLAC__USE_ALTIVEC */ disable_sse(info);
info->data.ppc.altivec = 0;
info->data.ppc.ppc64 = 0; /*
# endif * now have to check for OS support of AVX instructions
# else */
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; 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 #else
info->type = FLAC__CPUINFO_TYPE_UNKNOWN; info->type = FLAC__CPUINFO_TYPE_UNKNOWN;
info->use_asm = false; info->use_asm = false;
#endif #endif
} }
#if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
#if defined _MSC_VER
#include <intrin.h> /* for __cpuid() and _xgetbv() */
#elif defined __GNUC__ && defined HAVE_CPUID_H
#include <cpuid.h> /* 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 */
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -30,21 +30,17 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include "../compat.h"
#include "include/private/bitmath.h" #include "include/private/bitmath.h"
#include "include/private/fixed.h" #include "include/private/fixed.h"
#include "../assert.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 #ifdef local_abs
#undef local_abs #undef local_abs
#endif #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_3 == 0);
FLAC__ASSERT(data_len > 0 || total_error_4 == 0); FLAC__ASSERT(data_len > 0 || total_error_4 == 0);
#ifndef FLAC__INTEGER_ONLY_LIBRARY #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[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[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[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[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); 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 #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[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; residual_bits_per_sample[1] = (total_error_1 > 0) ? local__compute_rbps_wide_integerized(total_error_1, data_len) : 0;
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2004-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@@ -45,12 +45,7 @@
/* VERSION should come from configure */ /* VERSION should come from configure */
FLAC_API const char *FLAC__VERSION_STRING = VERSION; FLAC_API const char *FLAC__VERSION_STRING = VERSION;
#if defined _MSC_VER || defined __BORLANDC__ || defined __MINW32__ FLAC_API const char *FLAC__VENDOR_STRING = "reference libFLAC " VERSION " 20141125";
/* 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 FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' }; FLAC_API const FLAC__byte FLAC__STREAM_SYNC_STRING[4] = { 'f','L','a','C' };
FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143; FLAC_API const unsigned FLAC__STREAM_SYNC = 0x664C6143;
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -34,6 +34,7 @@
#define FLAC__PRIVATE__BITMATH_H #define FLAC__PRIVATE__BITMATH_H
#include "../../../ordinals.h" #include "../../../ordinals.h"
#include "../../../assert.h"
/* for CHAR_BIT */ /* for CHAR_BIT */
#include <limits.h> #include <limits.h>
@@ -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) static inline unsigned int FLAC__clz_uint32(FLAC__uint32 v)
{ {
/* Never used with input 0 */ /* Never used with input 0 */
FLAC__ASSERT(v > 0);
#if defined(__INTEL_COMPILER) #if defined(__INTEL_COMPILER)
return _bit_scan_reverse(v) ^ 31U; return _bit_scan_reverse(v) ^ 31U;
#elif defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) #elif defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
/* This will translate either to (bsr ^ 31U), clz , ctlz, cntlz, lzcnt depending on /* 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); return __builtin_clz(v);
#elif defined(_MSC_VER) && (_MSC_VER >= 1400) #elif defined(_MSC_VER) && (_MSC_VER >= 1400)
FLAC__uint32 idx; {
_BitScanReverse((DWORD*) &idx, v); unsigned long idx;
return idx ^ 31U; _BitScanReverse(&idx, v);
return idx ^ 31U;
}
#else #else
return FLAC__clz_soft_uint32(v); return FLAC__clz_soft_uint32(v);
#endif #endif
@@ -99,7 +103,7 @@ static inline unsigned int FLAC__clz2_uint32(FLAC__uint32 v)
/* An example of what FLAC__bitmath_ilog2() computes: /* An example of what FLAC__bitmath_ilog2() computes:
* *
* ilog2( 0) = undefined * ilog2( 0) = assertion failure
* ilog2( 1) = 0 * ilog2( 1) = 0
* ilog2( 2) = 1 * ilog2( 2) = 1
* ilog2( 3) = 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) 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); 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) static inline unsigned FLAC__bitmath_ilog2_wide(FLAC__uint64 v)
{ {
if (v == 0) FLAC__ASSERT(v > 0);
return 0;
#if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) #if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
return sizeof(FLAC__uint64) * CHAR_BIT - 1 - __builtin_clzll(v); return sizeof(FLAC__uint64) * CHAR_BIT - 1 - __builtin_clzll(v);
/* Sorry, only supported in win64/Itanium.. */ /* 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(_WIN64)) #elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && (defined(_M_IA64) || defined(_M_X64))
FLAC__uint64 idx; {
_BitScanReverse64(&idx, v); unsigned long idx;
return idx ^ 63U; _BitScanReverse64(&idx, v);
return idx;
}
#else #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) 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, static const unsigned char DEBRUIJN_IDX64[64]={
5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57, 0, 1, 2, 7, 3,13, 8,19, 4,25,14,28, 9,34,20,40,
63, 6,12,18,24,27,33,39,16,37,45,47,30,53,49,56, 5,17,26,38,15,46,29,48,10,31,35,54,21,50,41,57,
62,11,23,32,36,44,52,55,61,22,43,51,60,42,59,58 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>>1; v|= v>>2;
v|= v>>2; v|= v>>4;
v|= v>>4; v|= v>>8;
v|= v>>8; v|= v>>16;
v|= v>>16; v|= v>>32;
v|= v>>32; v= (v>>1)+1;
v= (v>>1)+1; return DEBRUIJN_IDX64[v*0x218A392CD3D5DBF>>58&0x3F];
ret+=DEBRUIJN_IDX64[v*0x218A392CD3D5DBF>>58&0x3F]; }
return ret;
#endif #endif
} }
#endif #endif
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * 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); FLAC__BitReader *FLAC__bitreader_new(void);
void FLAC__bitreader_delete(FLAC__BitReader *br); 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)' */ void FLAC__bitreader_free(FLAC__BitReader *br); /* does not 'free(br)' */
FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br); FLAC__bool FLAC__bitreader_clear(FLAC__BitReader *br);
void FLAC__bitreader_dump(const FLAC__BitReader *br, FILE *out); 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_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(FLAC__BitReader *br, int *val, unsigned parameter);
FLAC__bool FLAC__bitreader_read_rice_signed_block(FLAC__BitReader *br, int vals[], unsigned nvals, 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 */ #if 0 /* UNUSED */
FLAC__bool FLAC__bitreader_read_golomb_signed(FLAC__BitReader *br, int *val, unsigned parameter); 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); FLAC__bool FLAC__bitreader_read_golomb_unsigned(FLAC__BitReader *br, unsigned *val, unsigned parameter);
#endif #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_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 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 #endif
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -41,49 +41,59 @@
typedef enum { typedef enum {
FLAC__CPUINFO_TYPE_IA32, FLAC__CPUINFO_TYPE_IA32,
FLAC__CPUINFO_TYPE_PPC, FLAC__CPUINFO_TYPE_X86_64,
FLAC__CPUINFO_TYPE_UNKNOWN FLAC__CPUINFO_TYPE_UNKNOWN
} FLAC__CPUInfo_Type; } FLAC__CPUInfo_Type;
#if defined FLAC__CPU_IA32
typedef struct { typedef struct {
FLAC__bool cpuid;
FLAC__bool bswap;
FLAC__bool cmov; FLAC__bool cmov;
FLAC__bool mmx; FLAC__bool mmx;
FLAC__bool fxsr;
FLAC__bool sse; FLAC__bool sse;
FLAC__bool sse2; FLAC__bool sse2;
FLAC__bool sse3; FLAC__bool sse3;
FLAC__bool ssse3; FLAC__bool ssse3;
FLAC__bool _3dnow; FLAC__bool sse41;
FLAC__bool ext3dnow; FLAC__bool sse42;
FLAC__bool extmmx; FLAC__bool avx;
FLAC__bool avx2;
FLAC__bool fma;
} FLAC__CPUInfo_IA32; } FLAC__CPUInfo_IA32;
#elif defined FLAC__CPU_X86_64
typedef struct { typedef struct {
FLAC__bool altivec; FLAC__bool sse3;
FLAC__bool ppc64; FLAC__bool ssse3;
} FLAC__CPUInfo_PPC; FLAC__bool sse41;
FLAC__bool sse42;
FLAC__bool avx;
FLAC__bool avx2;
FLAC__bool fma;
} FLAC__CPUInfo_x86;
#endif
typedef struct { typedef struct {
FLAC__bool use_asm; FLAC__bool use_asm;
FLAC__CPUInfo_Type type; FLAC__CPUInfo_Type type;
union { #if defined FLAC__CPU_IA32
FLAC__CPUInfo_IA32 ia32; FLAC__CPUInfo_IA32 ia32;
FLAC__CPUInfo_PPC ppc; #elif defined FLAC__CPU_X86_64
} data; FLAC__CPUInfo_x86 x86;
#endif
} FLAC__CPUInfo; } FLAC__CPUInfo;
void FLAC__cpu_info(FLAC__CPUInfo *info); void FLAC__cpu_info(FLAC__CPUInfo *info);
#ifndef FLAC__NO_ASM #ifndef FLAC__NO_ASM
#ifdef FLAC__CPU_IA32 # if defined FLAC__CPU_IA32 && defined FLAC__HAS_NASM
#ifdef FLAC__HAS_NASM
FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32(void); FLAC__uint32 FLAC__cpu_have_cpuid_asm_ia32(void);
void FLAC__cpu_info_asm_ia32(FLAC__uint32 *flags_edx, FLAC__uint32 *flags_ecx); 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 # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
#endif 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
#endif #endif
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * 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]; 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 */ /* this alternate may be faster on some systems/compilers */
#if 0 #if 0
#define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]) & 0xffff) #define FLAC__CRC16_UPDATE(data, crc) ((((crc)<<8) ^ FLAC__crc16_table[((crc)>>8) ^ (data)]) & 0xffff)
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -37,6 +37,7 @@
#include <config.h> #include <config.h>
#endif #endif
#include "cpu.h"
#include "float.h" #include "float.h"
#include "../../../format.h" #include "../../../format.h"
@@ -54,14 +55,22 @@
*/ */
#ifndef FLAC__INTEGER_ONLY_LIBRARY #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(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 # ifndef FLAC__NO_ASM
# ifdef FLAC__CPU_IA32 # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
# ifdef FLAC__HAS_NASM # ifdef FLAC__SSE2_SUPPORTED
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]); 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
# 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 # 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 #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(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]); 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]);
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2004-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -37,6 +37,7 @@
#include <config.h> #include <config.h>
#endif #endif
#include "cpu.h"
#include "float.h" #include "float.h"
#include "../../../format.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_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_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_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 # endif
#endif #endif
@@ -145,6 +154,22 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients_wide(const FLAC__int32 *da
# ifdef FLAC__HAS_NASM # 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(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_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 # endif
#endif #endif
@@ -173,11 +198,17 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
# ifdef FLAC__HAS_NASM # 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(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_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 */ # endif /* FLAC__HAS_NASM */
# elif defined FLAC__CPU_PPC # endif /* FLAC__CPU_IA32 */
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[]); # if (defined FLAC__CPU_IA32 || defined FLAC__CPU_X86_64) && defined FLAC__HAS_X86INTRIN
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[]); # ifdef FLAC__SSE2_SUPPORTED
# endif/* FLAC__CPU_IA32 || FLAC__CPU_PPC */ 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 */ #endif /* FLAC__NO_ASM */
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
@@ -28,11 +28,17 @@
#include "../../../ordinals.h" #include "../../../ordinals.h"
typedef union {
FLAC__byte *p8;
FLAC__int16 *p16;
FLAC__int32 *p32;
} FLAC__multibyte;
typedef struct { typedef struct {
FLAC__uint32 in[16]; FLAC__uint32 in[16];
FLAC__uint32 buf[4]; FLAC__uint32 buf[4];
FLAC__uint32 bytes[2]; FLAC__uint32 bytes[2];
FLAC__byte *internal_buf; FLAC__multibyte internal_buf;
size_t capacity; size_t capacity;
} FLAC__MD5Context; } FLAC__MD5Context;
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2002-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2006-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * 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_rectangle(FLAC__real *window, const FLAC__int32 L);
void FLAC__window_triangle(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_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); void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L);
#endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */ #endif /* !defined FLAC__INTEGER_ONLY_LIBRARY */
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -40,6 +40,7 @@
typedef struct FLAC__StreamDecoderProtected { typedef struct FLAC__StreamDecoderProtected {
FLAC__StreamDecoderState state; FLAC__StreamDecoderState state;
FLAC__StreamDecoderInitStatus initstate;
unsigned channels; unsigned channels;
FLAC__ChannelAssignment channel_assignment; FLAC__ChannelAssignment channel_assignment;
unsigned bits_per_sample; unsigned bits_per_sample;
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -59,6 +59,8 @@ typedef enum {
FLAC__APODIZATION_RECTANGLE, FLAC__APODIZATION_RECTANGLE,
FLAC__APODIZATION_TRIANGLE, FLAC__APODIZATION_TRIANGLE,
FLAC__APODIZATION_TUKEY, FLAC__APODIZATION_TUKEY,
FLAC__APODIZATION_PARTIAL_TUKEY,
FLAC__APODIZATION_PUNCHOUT_TUKEY,
FLAC__APODIZATION_WELCH FLAC__APODIZATION_WELCH
} FLAC__ApodizationFunction; } FLAC__ApodizationFunction;
@@ -71,6 +73,11 @@ typedef struct {
struct { struct {
FLAC__real p; FLAC__real p;
} tukey; } tukey;
struct {
FLAC__real p;
FLAC__real start;
FLAC__real end;
} multiple_tukey;
} parameters; } parameters;
} FLAC__ApodizationSpecification; } FLAC__ApodizationSpecification;
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@@ -50,11 +50,6 @@
#ifndef FLAC__INTEGER_ONLY_LIBRARY #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(HAVE_LROUND)
#if defined(_MSC_VER) #if defined(_MSC_VER)
#include <float.h> #include <float.h>
@@ -65,7 +60,7 @@
static inline long int lround(double x) { static inline long int lround(double x) {
return (long)(x + copysign (0.5, 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 #endif
void FLAC__lpc_window_data(const FLAC__int32 in[], const FLAC__real window[], FLAC__real out[], unsigned data_len) 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 */ lp_coeff[i][j] = (FLAC__real)(-lpc[j]); /* negate FIR filter coeff to get predictor coeff */
error[i] = err; 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) { if(err == 0.0) {
*max_order = i+1; *max_order = i+1;
return; return;
@@ -264,7 +259,12 @@ int FLAC__lpc_quantize_coefficients(const FLAC__real lp_coeff[], unsigned order,
return 0; 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) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{ {
FLAC__int64 sumo; FLAC__int64 sumo;
@@ -524,7 +524,7 @@ void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, u
} }
#endif #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) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{ {
unsigned i, j; 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 */ #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) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{ {
FLAC__int64 sumo; FLAC__int64 sumo;
@@ -1041,7 +1041,7 @@ void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, c
} }
#endif #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) #if defined(FLAC__OVERFLOW_DETECT) || !defined(FLAC__LPC_UNROLLED_FILTER_LOOPS)
{ {
unsigned i, j; unsigned i, j;
@@ -1295,6 +1295,10 @@ void FLAC__lpc_restore_signal_wide(const FLAC__int32 residual[], unsigned data_l
} }
#endif #endif
#if defined(_MSC_VER)
#pragma warning ( default : 4028 )
#endif
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples) FLAC__double FLAC__lpc_compute_expected_bits_per_residual_sample(FLAC__double lpc_error, unsigned total_samples)
@@ -1,4 +1,4 @@
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@@ -7,6 +7,7 @@
#include "include/private/md5.h" #include "include/private/md5.h"
#include "../alloc.h" #include "../alloc.h"
#include "../endswap.h"
/* /*
* This code implements the MD5 message-digest algorithm. * This code implements the MD5 message-digest algorithm.
@@ -223,7 +224,7 @@ void FLAC__MD5Init(FLAC__MD5Context *ctx)
ctx->bytes[0] = 0; ctx->bytes[0] = 0;
ctx->bytes[1] = 0; ctx->bytes[1] = 0;
ctx->internal_buf = 0; ctx->internal_buf.p8= 0;
ctx->capacity = 0; ctx->capacity = 0;
} }
@@ -259,9 +260,9 @@ void FLAC__MD5Final(FLAC__byte digest[16], FLAC__MD5Context *ctx)
byteSwap(ctx->buf, 4); byteSwap(ctx->buf, 4);
memcpy(digest, ctx->buf, 16); memcpy(digest, ctx->buf, 16);
if(0 != ctx->internal_buf) { if (0 != ctx->internal_buf.p8) {
free(ctx->internal_buf); free(ctx->internal_buf.p8);
ctx->internal_buf = 0; ctx->internal_buf.p8= 0;
ctx->capacity = 0; ctx->capacity = 0;
} }
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ 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 * 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; unsigned channel, sample;
register FLAC__int32 a_word;
register FLAC__byte *buf_ = buf;
#if WORDS_BIGENDIAN /* Storage in the output buffer, buf, is little endian. */
#else
if(channels == 2 && bytes_per_sample == 2) { #define BYTES_CHANNEL_SELECTOR(bytes, channels) (bytes * 100 + channels)
FLAC__int16 *buf1_ = ((FLAC__int16*)buf_) + 1;
memcpy(buf_, signal[0], sizeof(FLAC__int32) * samples); /* First do the most commonly used combinations. */
for(sample = 0; sample < samples; sample++, buf1_+=2) switch (BYTES_CHANNEL_SELECTOR (bytes_per_sample, channels)) {
*buf1_ = (FLAC__int16)signal[1][sample]; /* One byte per sample. */
} case (BYTES_CHANNEL_SELECTOR (1, 1)):
else if(channels == 1 && bytes_per_sample == 2) { for (sample = 0; sample < samples; sample++)
FLAC__int16 *buf1_ = (FLAC__int16*)buf_; *buf_++ = signal[0][sample];
for(sample = 0; sample < samples; sample++) return;
*buf1_++ = (FLAC__int16)signal[0][sample];
} case (BYTES_CHANNEL_SELECTOR (1, 2)):
else for (sample = 0; sample < samples; sample++) {
#endif *buf_++ = signal[0][sample];
if(bytes_per_sample == 2) { *buf_++ = signal[1][sample];
if(channels == 2) { }
for(sample = 0; sample < samples; 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]; 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;
a_word = signal[1][sample];
*buf_++ = (FLAC__byte)a_word; a_word >>= 8; *buf_++ = (FLAC__byte)a_word; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; *buf_++ = (FLAC__byte)a_word;
} }
} return;
else if(channels == 1) {
for(sample = 0; sample < samples; sample++) { case (BYTES_CHANNEL_SELECTOR (3, 2)):
a_word = signal[0][sample]; for (sample = 0; sample < samples; 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++) {
a_word = signal[0][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; 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; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; *buf_++ = (FLAC__byte)a_word;
} }
} return;
else if(channels == 1) {
for(sample = 0; sample < samples; sample++) { /* Four bytes per sample. */
a_word = signal[0][sample]; case (BYTES_CHANNEL_SELECTOR (4, 1)):
*buf_++ = (FLAC__byte)a_word; a_word >>= 8; for (sample = 0; sample < samples; sample++)
*buf_++ = (FLAC__byte)a_word; a_word >>= 8; *buf32++ = H2LE_32(signal[0][sample]);
*buf_++ = (FLAC__byte)a_word; 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]);
} }
} return;
else {
for(sample = 0; sample < samples; sample++) { case (BYTES_CHANNEL_SELECTOR (4, 4)):
for(channel = 0; channel < channels; channel++) { 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]; 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; a_word >>= 8;
*buf_++ = (FLAC__byte)a_word; *buf_++ = (FLAC__byte)a_word;
} }
} return;
}
} case 4:
else if(bytes_per_sample == 1) { for (sample = 0; sample < samples; sample++)
if(channels == 2) { for (channel = 0; channel < channels; channel++)
for(sample = 0; sample < samples; sample++) { *buf32++ = H2LE_32(signal[channel][sample]);
a_word = signal[0][sample]; return;
*buf_++ = (FLAC__byte)a_word;
a_word = signal[1][sample]; default:
*buf_++ = (FLAC__byte)a_word; break;
}
}
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;
}
}
} }
} }
@@ -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; const size_t bytes_needed = (size_t)channels * (size_t)samples * (size_t)bytes_per_sample;
/* overflow check */ /* 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; 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; return false;
if(ctx->capacity < bytes_needed) { if (ctx->capacity < bytes_needed) {
FLAC__byte *tmp = (FLAC__byte*) realloc(ctx->internal_buf, bytes_needed); FLAC__byte *tmp = (FLAC__byte*) realloc(ctx->internal_buf.p8, bytes_needed);
if(0 == tmp) { if (0 == tmp) {
free(ctx->internal_buf); free(ctx->internal_buf.p8);
if(0 == (ctx->internal_buf = (FLAC__byte*) safe_malloc_(bytes_needed))) if (0 == (ctx->internal_buf.p8= (FLAC__byte*) safe_malloc_(bytes_needed)))
return false; return false;
} }
else else
ctx->internal_buf = tmp; ctx->internal_buf.p8= tmp;
ctx->capacity = bytes_needed; 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; return true;
} }
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -30,10 +30,14 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include "include/private/memory.h" #include "include/private/memory.h"
#include "../assert.h" #include "../assert.h"
#include "../alloc.h" #include "../alloc.h"
@@ -46,25 +50,8 @@ void *FLAC__memory_alloc_aligned(size_t bytes, void **aligned_address)
#ifdef FLAC__ALIGN_MALLOC_DATA #ifdef FLAC__ALIGN_MALLOC_DATA
/* align on 32-byte (256-bit) boundary */ /* align on 32-byte (256-bit) boundary */
x = safe_malloc_add_2op_(bytes, /*+*/31); x = safe_malloc_add_2op_(bytes, /*+*/31L);
#ifdef SIZEOF_VOIDP *aligned_address = (void*)(((uintptr_t)x + 31L) & -32L);
#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
#else #else
x = safe_malloc_(bytes); x = safe_malloc_(bytes);
*aligned_address = x; *aligned_address = x;
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #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_(FLAC__StreamDecoder *decoder);
static FLAC__bool read_metadata_streaminfo_(FLAC__StreamDecoder *decoder, FLAC__bool is_last, unsigned length); 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_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_cuesheet_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_CueSheet *obj);
static FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj); static FLAC__bool read_metadata_picture_(FLAC__StreamDecoder *decoder, FLAC__StreamMetadata_Picture *obj);
static FLAC__bool skip_id3v2_tag_(FLAC__StreamDecoder *decoder); 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[]); 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): */ /* 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[]); 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; void *client_data;
FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */ FILE *file; /* only used if FLAC__stream_decoder_init_file()/FLAC__stream_decoder_init_file() called, else NULL */
FLAC__BitReader *input; FLAC__BitReader *input;
@@ -380,7 +377,7 @@ static FLAC__StreamDecoderInitStatus init_stream_internal_(
#if FLAC__HAS_OGG #if FLAC__HAS_OGG
decoder->private_->is_ogg = is_ogg; decoder->private_->is_ogg = is_ogg;
if(is_ogg && !FLAC__ogg_decoder_aspect_init(&decoder->protected_->ogg_decoder_aspect)) 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 #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 = FLAC__lpc_restore_signal;
decoder->private_->local_lpc_restore_signal_64bit = FLAC__lpc_restore_signal_wide; 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 = 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 */ /* now override with asm where appropriate */
#ifndef FLAC__NO_ASM #ifndef FLAC__NO_ASM
if(decoder->private_->cpuinfo.use_asm) { if(decoder->private_->cpuinfo.use_asm) {
#ifdef FLAC__CPU_IA32 #ifdef FLAC__CPU_IA32
FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
#ifdef FLAC__HAS_NASM #ifdef FLAC__HAS_NASM
#if 1 /*@@@@@@ OPT: not clearly faster, needs more testing */ 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.data.ia32.bswap) if(decoder->private_->cpuinfo.ia32.mmx) {
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 = FLAC__lpc_restore_signal_asm_ia32; 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 = FLAC__lpc_restore_signal_asm_ia32_mmx;
decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32_mmx;
} }
else { else {
decoder->private_->local_lpc_restore_signal = FLAC__lpc_restore_signal_asm_ia32; 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 = FLAC__lpc_restore_signal_asm_ia32;
decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ia32;
} }
#endif #endif
#elif defined FLAC__CPU_PPC #ifdef FLAC__HAS_X86INTRIN
FLAC__ASSERT(decoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_PPC); # if defined FLAC__SSE2_SUPPORTED && !defined FLAC__HAS_NASM /* OPT_SSE: not better than MMX asm */
if(decoder->private_->cpuinfo.data.ppc.altivec) { if(decoder->private_->cpuinfo.ia32.sse2) {
decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_asm_ppc_altivec_16; decoder->private_->local_lpc_restore_signal_16bit = FLAC__lpc_restore_signal_16_intrin_sse2;
decoder->private_->local_lpc_restore_signal_16bit_order8 = FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8;
} }
# 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
} }
#endif #endif
/* from here on, errors are fatal */ /* 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; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return FLAC__STREAM_DECODER_INIT_STATUS_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); FLAC__ASSERT(0 != file);
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) 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) 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 * 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. * in FLAC__stream_decoder_init_FILE() before the FILE* is assigned.
*/ */
if(decoder->protected_->state != FLAC__STREAM_DECODER_UNINITIALIZED) 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) 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; 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) if(decoder->protected_->state == FLAC__STREAM_DECODER_UNINITIALIZED)
return true; 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() * always call FLAC__MD5Final()
*/ */
FLAC__MD5Final(decoder->private_->computed_md5sum, &decoder->private_->md5context); 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); memset(tmp, 0, sizeof(FLAC__int32)*4);
decoder->private_->output[i] = tmp + 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])) { 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; decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR;
return false; return false;
@@ -1368,6 +1364,10 @@ FLAC__bool find_metadata_(FLAC__StreamDecoder *decoder)
id_ = 0; id_ = 0;
continue; continue;
} }
if(id_ >= 3)
return false;
if(x == ID3V2_TAG_[id_]) { if(x == ID3V2_TAG_[id_]) {
id_++; id_++;
i = 0; i = 0;
@@ -1446,6 +1446,7 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
unsigned real_length = length; unsigned real_length = length;
FLAC__StreamMetadata block; FLAC__StreamMetadata block;
memset(&block, 0, sizeof(block));
block.is_last = is_last; block.is_last = is_last;
block.type = (FLAC__MetadataType)type; block.type = (FLAC__MetadataType)type;
block.length = length; block.length = length;
@@ -1470,36 +1471,37 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
return false; /* read_callback_ sets the state for us */ return false; /* read_callback_ sets the state for us */
} }
else { else {
FLAC__bool ok = true;
switch(type) { switch(type) {
case FLAC__METADATA_TYPE_PADDING: case FLAC__METADATA_TYPE_PADDING:
/* skip the padding bytes */ /* skip the padding bytes */
if(!FLAC__bitreader_skip_byte_block_aligned_no_crc(decoder->private_->input, real_length)) 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; break;
case FLAC__METADATA_TYPE_APPLICATION: case FLAC__METADATA_TYPE_APPLICATION:
/* remember, we read the ID already */ /* remember, we read the ID already */
if(real_length > 0) { if(real_length > 0) {
if(0 == (block.data.application.data = (FLAC__byte*) malloc(real_length))) { if(0 == (block.data.application.data = (FLAC__byte*) malloc(real_length))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; 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)) else 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 */ ok = false; /* read_callback_ sets the state for us */
} }
else else
block.data.application.data = 0; block.data.application.data = 0;
break; break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT: case FLAC__METADATA_TYPE_VORBIS_COMMENT:
if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment)) if(!read_metadata_vorbiscomment_(decoder, &block.data.vorbis_comment, real_length))
return false; ok = false;
break; break;
case FLAC__METADATA_TYPE_CUESHEET: case FLAC__METADATA_TYPE_CUESHEET:
if(!read_metadata_cuesheet_(decoder, &block.data.cue_sheet)) if(!read_metadata_cuesheet_(decoder, &block.data.cue_sheet))
return false; ok = false;
break; break;
case FLAC__METADATA_TYPE_PICTURE: case FLAC__METADATA_TYPE_PICTURE:
if(!read_metadata_picture_(decoder, &block.data.picture)) if(!read_metadata_picture_(decoder, &block.data.picture))
return false; ok = false;
break; break;
case FLAC__METADATA_TYPE_STREAMINFO: case FLAC__METADATA_TYPE_STREAMINFO:
case FLAC__METADATA_TYPE_SEEKTABLE: case FLAC__METADATA_TYPE_SEEKTABLE:
@@ -1509,16 +1511,16 @@ FLAC__bool read_metadata_(FLAC__StreamDecoder *decoder)
if(real_length > 0) { if(real_length > 0) {
if(0 == (block.data.unknown.data = (FLAC__byte*) malloc(real_length))) { if(0 == (block.data.unknown.data = (FLAC__byte*) malloc(real_length))) {
decoder->protected_->state = FLAC__STREAM_DECODER_MEMORY_ALLOCATION_ERROR; 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)) else 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 */ ok = false; /* read_callback_ sets the state for us */
} }
else else
block.data.unknown.data = 0; block.data.unknown.data = 0;
break; 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); decoder->private_->metadata_callback(decoder, &block, decoder->private_->client_data);
/* now we have to free any malloc()ed data in the block */ /* 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); free(block.data.unknown.data);
break; 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; 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__uint32 i;
FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input)); FLAC__ASSERT(FLAC__bitreader_is_consumed_byte_aligned(decoder->private_->input));
/* read vendor string */ /* read vendor string */
FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32); if (length >= 8) {
if(!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &obj->vendor_string.length)) length -= 8; /* vendor string length + num comments entries alone take 8 bytes */
return false; /* read_callback_ sets the state for us */ FLAC__ASSERT(FLAC__STREAM_METADATA_VORBIS_COMMENT_ENTRY_LENGTH_LEN == 32);
if(obj->vendor_string.length > 0) { if (!FLAC__bitreader_read_uint32_little_endian(decoder->private_->input, &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 */ return false; /* read_callback_ sets the state for us */
obj->vendor_string.entry[obj->vendor_string.length] = '\0'; if (obj->vendor_string.length > 0) {
} if (length < obj->vendor_string.length) {
else obj->vendor_string.length = 0;
obj->vendor_string.entry = 0; obj->vendor_string.entry = 0;
goto skip;
/* 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';
} }
else 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; return true;
@@ -2655,12 +2690,8 @@ FLAC__bool read_subframe_lpc_(FLAC__StreamDecoder *decoder, unsigned channel, un
if( (FLAC__uint64)order * ((((FLAC__uint64)1)<<bps)-1) * ((1<<subframe->qlp_coeff_precision)-1) < (((FLAC__uint64)-1) << 32) ) if( (FLAC__uint64)order * ((((FLAC__uint64)1)<<bps)-1) * ((1<<subframe->qlp_coeff_precision)-1) < (((FLAC__uint64)-1) << 32) )
*/ */
if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32) if(bps + subframe->qlp_coeff_precision + FLAC__bitmath_ilog2(order) <= 32)
if(bps <= 16 && subframe->qlp_coeff_precision <= 16) { if(bps <= 16 && subframe->qlp_coeff_precision <= 16)
if(order <= 8) 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);
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);
}
else 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); 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 else
@@ -2708,14 +2739,16 @@ FLAC__bool read_residual_partitioned_rice_(FLAC__StreamDecoder *decoder, unsigne
if(decoder->private_->frame.header.blocksize < predictor_order) { if(decoder->private_->frame.header.blocksize < predictor_order) {
send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_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 { else {
if(partition_samples < predictor_order) { if(partition_samples < predictor_order) {
send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC); send_error_to_client_(decoder, FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC);
decoder->protected_->state = FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_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) { if(rice_parameter < pesc) {
partitioned_rice_contents->raw_bits[partition] = 0; partitioned_rice_contents->raw_bits[partition] = 0;
u = (partition_order == 0 || partition > 0)? partition_samples : partition_samples - predictor_order; 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 */ return false; /* read_callback_ sets the state for us */
sample += u; sample += u;
} }
@@ -3074,12 +3107,7 @@ FLAC__bool seek_to_absolute_sample_(FLAC__StreamDecoder *decoder, FLAC__uint64 s
return false; return false;
} }
#ifndef FLAC__INTEGER_ONLY_LIBRARY #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; 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 #else
/* a little less accurate: */ /* a little less accurate: */
if(upper_bound - lower_bound < 0xffffffff) if(upper_bound - lower_bound < 0xffffffff)
@@ -3203,12 +3231,7 @@ FLAC__bool seek_to_absolute_sample_ogg_(FLAC__StreamDecoder *decoder, FLAC__uint
} }
else { else {
#ifndef FLAC__INTEGER_ONLY_LIBRARY #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)); pos = (FLAC__uint64)((FLAC__double)(target_sample - left_sample) / (FLAC__double)(right_sample - left_sample) * (FLAC__double)(right_pos - left_pos));
#endif
#else #else
/* a little less accurate: */ /* a little less accurate: */
if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff)) if ((target_sample-left_sample <= 0xffffffff) && (right_pos-left_pos <= 0xffffffff))
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@@ -55,10 +55,10 @@
#include "include/private/ogg_helper.h" #include "include/private/ogg_helper.h"
#include "include/private/ogg_mapping.h" #include "include/private/ogg_mapping.h"
#endif #endif
#include "include/private/stream_encoder.h"
#include "include/private/stream_encoder_framing.h" #include "include/private/stream_encoder_framing.h"
#include "include/private/window.h" #include "include/private/window.h"
#include "../alloc.h" #include "../alloc.h"
#include "../compat.h"
/* Exact Rice codeword length calculation is off by default. The simple /* Exact Rice codeword length calculation is off by default. The simple
@@ -103,16 +103,18 @@ static struct CompressionLevels {
unsigned min_residual_partition_order; unsigned min_residual_partition_order;
unsigned max_residual_partition_order; unsigned max_residual_partition_order;
unsigned rice_parameter_search_dist; unsigned rice_parameter_search_dist;
const char *apodization;
} compression_levels_[] = { } compression_levels_[] = {
{ false, false, 0, 0, false, false, false, 0, 3, 0 }, { false, false, 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" },
{ true , true , 0, 0, false, false, false, 0, 3, 0 }, { true , true , 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" },
{ true , false, 0, 0, false, false, false, 0, 3, 0 }, { true , false, 0, 0, false, false, false, 0, 3, 0, "tukey(5e-1)" },
{ false, false, 6, 0, false, false, false, 0, 4, 0 }, { false, false, 6, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" },
{ true , true , 8, 0, false, false, false, 0, 4, 0 }, { true , true , 8, 0, false, false, false, 0, 4, 0, "tukey(5e-1)" },
{ true , false, 8, 0, false, false, false, 0, 5, 0 }, { true , false, 8, 0, false, false, false, 0, 5, 0, "tukey(5e-1)" },
{ true , false, 8, 0, false, false, false, 0, 6, 0 }, { true , false, 8, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2)" },
{ true , false, 8, 0, false, false, true , 0, 6, 0 }, { true , false, 12, 0, false, false, false, 0, 6, 0, "tukey(5e-1);partial_tukey(2)" },
{ true , false, 12, 0, false, false, true , 0, 6, 0 } { 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; unsigned current_frame_number;
FLAC__MD5Context md5context; FLAC__MD5Context md5context;
FLAC__CPUInfo cpuinfo; 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 #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)(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 #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)(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 #endif
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
void (*local_lpc_compute_autocorrelation)(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[]); 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 #ifndef FLAC__INTEGER_ONLY_LIBRARY
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation; encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation;
#endif #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 = FLAC__fixed_compute_best_predictor;
encoder->private_->local_fixed_compute_best_predictor_wide = FLAC__fixed_compute_best_predictor_wide;
#ifndef FLAC__INTEGER_ONLY_LIBRARY #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 = 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; 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 # ifdef FLAC__CPU_IA32
FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32); FLAC__ASSERT(encoder->private_->cpuinfo.type == FLAC__CPUINFO_TYPE_IA32);
# ifdef FLAC__HAS_NASM # ifdef FLAC__HAS_NASM
if(encoder->private_->cpuinfo.data.ia32.sse) { if(encoder->private_->cpuinfo.ia32.sse) {
if(encoder->protected_->max_lpc_order < 4) if(encoder->protected_->max_lpc_order < 4)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4; encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4;
else if(encoder->protected_->max_lpc_order < 8) else if(encoder->protected_->max_lpc_order < 8)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8; encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8;
else if(encoder->protected_->max_lpc_order < 12) else if(encoder->protected_->max_lpc_order < 12)
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_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 else
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32; 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 else
encoder->private_->local_lpc_compute_autocorrelation = FLAC__lpc_compute_autocorrelation_asm_ia32; 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 = 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; 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 = 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; 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; encoder->private_->local_fixed_compute_best_predictor = FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov;
# endif /* FLAC__HAS_NASM */ # 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__NO_ASM */
#endif /* !FLAC__INTEGER_ONLY_LIBRARY */ #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 */ /* finally override based on wide-ness if necessary */
if(encoder->private_->use_wide_by_block) { 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 */ /* 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, FLAC__StreamEncoder *encoder,
FILE *file, FILE *file,
FLAC__StreamEncoderProgressCallback progress_callback, FLAC__StreamEncoderProgressCallback progress_callback,
void * /*client_data*/, void *client_data,
FLAC__bool is_ogg FLAC__bool is_ogg
) )
{ {
@@ -1178,6 +1308,13 @@ static FLAC__StreamEncoderInitStatus init_FILE_internal_(
if(file == stdout) if(file == stdout)
file = get_binary_stdout_(); /* just to be safe */ 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_->file = file;
encoder->private_->progress_callback = progress_callback; 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_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); ok &= FLAC__stream_encoder_set_loose_mid_side_stereo (encoder, compression_levels_[value].loose_mid_side_stereo);
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
#if 0 #if 1
/* was: */
ok &= FLAC__stream_encoder_set_apodization (encoder, compression_levels_[value].apodization); 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 #else
/* equivalent to -A tukey(0.5) */
encoder->protected_->num_apodizations = 1; encoder->protected_->num_apodizations = 1;
encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY; encoder->protected_->apodizations[0].type = FLAC__APODIZATION_TUKEY;
encoder->protected_->apodizations[0].parameters.tukey.p = 0.5; 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; 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)) else if(n==5 && 0 == strncmp("welch" , specification, n))
encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_WELCH; encoder->protected_->apodizations[encoder->protected_->num_apodizations++].type = FLAC__APODIZATION_WELCH;
if (encoder->protected_->num_apodizations == 32) if (encoder->protected_->num_apodizations == 32)
@@ -2236,8 +2414,8 @@ FLAC__bool resize_buffers_(FLAC__StreamEncoder *encoder, unsigned new_blocksize)
ok = true; ok = true;
/* WATCHOUT: FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx() /* WATCHOUT: FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx() and ..._intrin_sse2()
* requires that the input arrays (in our case the integer signals) * 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 * 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. * 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: case FLAC__APODIZATION_TUKEY:
FLAC__window_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.tukey.p); FLAC__window_tukey(encoder->private_->window[i], new_blocksize, encoder->protected_->apodizations[i].parameters.tukey.p);
break; 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: case FLAC__APODIZATION_WELCH:
FLAC__window_welch(encoder->private_->window[i], new_blocksize); FLAC__window_welch(encoder->private_->window[i], new_blocksize);
break; break;
@@ -3165,7 +3349,7 @@ FLAC__bool process_subframe_(
#endif #endif
#ifndef FLAC__INTEGER_ONLY_LIBRARY #ifndef FLAC__INTEGER_ONLY_LIBRARY
FLAC__double lpc_residual_bits_per_sample; 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]; FLAC__double lpc_error[FLAC__MAX_LPC_ORDER];
unsigned min_lpc_order, max_lpc_order, lpc_order; unsigned min_lpc_order, max_lpc_order, lpc_order;
unsigned min_qlp_coeff_precision, max_qlp_coeff_precision, qlp_coeff_precision; 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) { if(encoder->protected_->do_qlp_coeff_prec_search) {
min_qlp_coeff_precision = FLAC__MIN_QLP_COEFF_PRECISION; 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 */ /* try to keep qlp coeff precision such that only 32-bit math is required for decode of <=16bps streams */
if(subframe_bps <= 17) { if(subframe_bps <= 16) {
max_qlp_coeff_precision = flac_min(32 - subframe_bps - lpc_order, FLAC__MAX_QLP_COEFF_PRECISION); 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); max_qlp_coeff_precision = flac_max(max_qlp_coeff_precision, min_qlp_coeff_precision);
} }
else else
@@ -3556,7 +3740,7 @@ unsigned evaluate_lpc_subframe_(
FLAC__EntropyCodingMethod_PartitionedRiceContents *partitioned_rice_contents 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; unsigned i, residual_bits, estimate;
int quantization, ret; int quantization, ret;
const unsigned residual_samples = blocksize - order; 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); 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); 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) if(do_escape_coding)
precompute_partition_info_escapes_(residual, raw_bits_per_partition, residual_samples, predictor_order, min_partition_order, max_partition_order); 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; 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_( void precompute_partition_info_sums_(
const FLAC__int32 residual[], const FLAC__int32 residual[],
FLAC__uint64 abs_residual_partition_sums[], FLAC__uint64 abs_residual_partition_sums[],
@@ -3769,21 +3942,12 @@ void precompute_partition_info_sums_(
FLAC__ASSERT(default_partition_samples > predictor_order); 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 */ /* first do max_partition_order */
{ {
unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order); unsigned partition, residual_sample, end = (unsigned)(-(int)predictor_order);
/* slightly pessimistic but still catches all common cases */ /* WATCHOUT: "+ bps + FLAC__MAX_EXTRA_RESIDUAL_BPS" is the maximum
/* WATCHOUT: "+ bps" is an assumption that the average residual magnitude will not be more than "bps" bits */ * assumed size of the average residual magnitude */
if(FLAC__bitmath_ilog2(default_partition_samples) + bps < 32) { if(FLAC__bitmath_ilog2(default_partition_samples) + bps + FLAC__MAX_EXTRA_RESIDUAL_BPS < 32) {
FLAC__uint32 abs_residual_partition_sum; FLAC__uint32 abs_residual_partition_sum;
for(partition = residual_sample = 0; partition < partitions; partition++) { 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 * in the partition, so the actual mean is
* mean/partition_samples * mean/partition_samples
*/ */
#if 0 /* old simple code */
for(rice_parameter = 0, k = partition_samples; k < mean; rice_parameter++, k <<= 1) 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) { if(rice_parameter >= rice_parameter_limit) {
#ifdef DEBUG_VERBOSE #ifdef DEBUG_VERBOSE
fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1); fprintf(stderr, "clipping rice_parameter (%u -> %u) @6\n", rice_parameter, rice_parameter_limit - 1);
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2006-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#if HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
# include <config.h> # include <config.h>
#endif #endif
@@ -41,11 +41,6 @@
#ifndef FLAC__INTEGER_ONLY_LIBRARY #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) 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++) for (n = 0; n <= L/2-1; n++)
window[n] = 2.0f * n / (float)N; window[n] = 2.0f * n / (float)N;
for (; n <= N; 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; FLAC__int32 n;
for (n = 0; n < L; 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) 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; FLAC__int32 n;
if (L & 1) { 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); window[n-1] = 2.0f * n / ((float)L + 1.0f);
for (; n <= L; n++) 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 { else {
for (n = 1; n <= L/2; n++) 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++) 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) void FLAC__window_welch(FLAC__real *window, const FLAC__int32 L)
{ {
const FLAC__int32 N = L - 1; const FLAC__int32 N = L - 1;
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2001-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * 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 * \retval unsigned
* The length of the metadata block at the current iterator position. * The length of the metadata block at the current iterator position.
* The is same length as that in the * The is same length as that in the
* <a href="http://flac.sourceforge.net/format.html#metadata_block_header">metadata block header</a>, * <a href="http://xiph.org/flac/format.html#metadata_block_header">metadata block header</a>,
* i.e. the length of the metadata body that follows the 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); FLAC_API unsigned FLAC__metadata_simple_iterator_get_block_length(const FLAC__Metadata_SimpleIterator *iterator);
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@@ -1,6 +1,6 @@
/* libFLAC - Free Lossless Audio Codec library /* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000-2009 Josh Coalson * 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * 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: * The actual values set for each level are:
* <table> * <table>
* <tr> * <tr>
* <td><b>level</b><td> * <td><b>level</b></td>
* <td>do mid-side stereo<td> * <td>do mid-side stereo</td>
* <td>loose mid-side stereo<td> * <td>loose mid-side stereo</td>
* <td>apodization<td> * <td>apodization</td>
* <td>max lpc order<td> * <td>max lpc order</td>
* <td>qlp coeff precision<td> * <td>qlp coeff precision</td>
* <td>qlp coeff prec search<td> * <td>qlp coeff prec search</td>
* <td>escape coding<td> * <td>escape coding</td>
* <td>exhaustive model search<td> * <td>exhaustive model search</td>
* <td>min residual partition order<td> * <td>min residual partition order</td>
* <td>max residual partition order<td> * <td>max residual partition order</td>
* <td>rice parameter search dist<td> * <td>rice parameter search dist</td>
* </tr> * </tr>
* <tr> <td><b>0</b><td> <td>false<td> <td>false<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr> * <tr> <td><b>0</b></td> <td>false</td> <td>false</td> <td>tukey(0.5)<td> <td>0</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>3</td> <td>0</td> </tr>
* <tr> <td><b>1</b><td> <td>true<td> <td>true<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr> * <tr> <td><b>1</b></td> <td>true</td> <td>true</td> <td>tukey(0.5)<td> <td>0</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>3</td> <td>0</td> </tr>
* <tr> <td><b>2</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>0<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>3<td> <td>0<td> </tr> * <tr> <td><b>2</b></td> <td>true</td> <td>false</td> <td>tukey(0.5)<td> <td>0</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>3</td> <td>0</td> </tr>
* <tr> <td><b>3</b><td> <td>false<td> <td>false<td> <td>tukey(0.5)<td> <td>6<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>4<td> <td>0<td> </tr> * <tr> <td><b>3</b></td> <td>false</td> <td>false</td> <td>tukey(0.5)<td> <td>6</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>4</td> <td>0</td> </tr>
* <tr> <td><b>4</b><td> <td>true<td> <td>true<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>4<td> <td>0<td> </tr> * <tr> <td><b>4</b></td> <td>true</td> <td>true</td> <td>tukey(0.5)<td> <td>8</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>4</td> <td>0</td> </tr>
* <tr> <td><b>5</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>5<td> <td>0<td> </tr> * <tr> <td><b>5</b></td> <td>true</td> <td>false</td> <td>tukey(0.5)<td> <td>8</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>5</td> <td>0</td> </tr>
* <tr> <td><b>6</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>false<td> <td>0<td> <td>6<td> <td>0<td> </tr> * <tr> <td><b>6</b></td> <td>true</td> <td>false</td> <td>tukey(0.5);partial_tukey(2)<td> <td>8</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>6</td> <td>0</td> </tr>
* <tr> <td><b>7</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>8<td> <td>0<td> <td>false<td> <td>false<td> <td>true<td> <td>0<td> <td>6<td> <td>0<td> </tr> * <tr> <td><b>7</b></td> <td>true</td> <td>false</td> <td>tukey(0.5);partial_tukey(2)<td> <td>12</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>6</td> <td>0</td> </tr>
* <tr> <td><b>8</b><td> <td>true<td> <td>false<td> <td>tukey(0.5)<td> <td>12<td> <td>0<td> <td>false<td> <td>false<td> <td>true<td> <td>0<td> <td>6<td> <td>0<td> </tr> * <tr> <td><b>8</b></td> <td>true</td> <td>false</td> <td>tukey(0.5);partial_tukey(2);punchout_tukey(3)</td> <td>12</td> <td>0</td> <td>false</td> <td>false</td> <td>false</td> <td>0</td> <td>6</td> <td>0</td> </tr>
* </table> * </table>
* *
* \default \c 5 * \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, * The available functions are \c bartlett, \c bartlett_hann,
* \c blackman, \c blackman_harris_4term_92db, \c connes, \c flattop, * \c blackman, \c blackman_harris_4term_92db, \c connes, \c flattop,
* \c gauss(STDDEV), \c hamming, \c hann, \c kaiser_bessel, \c nuttall, * \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 * For \c gauss(STDDEV), STDDEV specifies the standard deviation
* (0<STDDEV<=0.5). * (0<STDDEV<=0.5).
@@ -929,6 +930,24 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamE
* tapered (0<=P<=1). P=0 corresponds to \c rectangle and P=1 * tapered (0<=P<=1). P=0 corresponds to \c rectangle and P=1
* corresponds to \c hann. * corresponds to \c hann.
* *
* Specifying \c partial_tukey or \c punchout_tukey works a little
* different. These do not specify a single apodization function, but
* a series of them with some overlap. partial_tukey specifies a series
* of small windows (all treated separately) while punchout_tukey
* specifies a series of windows that have a hole in them. In this way,
* the predictor is constructed with only a part of the block, which
* helps in case a block consists of dissimilar parts.
*
* The three parameters that can be specified for the functions are
* n, ov and P. n is the number of functions to add, ov is the overlap
* of the windows in case of partial_tukey and the overlap in the gaps
* in case of punchout_tukey. P is the fraction of the window that is
* tapered, like with a regular tukey window. The function can be
* specified with only a number, a number and an overlap, or a number
* an overlap and a P, for example, partial_tukey(3), partial_tukey(3/0.3)
* and partial_tukey(3/0.3/0.5) are all valid. ov should be smaller than 1
* and can be negative.
*
* Example specifications are \c "blackman" or * Example specifications are \c "blackman" or
* \c "hann;triangle;tukey(0.5);tukey(0.25);tukey(0.125)" * \c "hann;triangle;tukey(0.5);tukey(0.25);tukey(0.125)"
* *
@@ -941,7 +960,9 @@ FLAC_API FLAC__bool FLAC__stream_encoder_set_loose_mid_side_stereo(FLAC__StreamE
* results in the smallest compressed subframe. * results in the smallest compressed subframe.
* *
* Note that each function specified causes the encoder to occupy a * Note that each function specified causes the encoder to occupy a
* floating point array in which to store the window. * floating point array in which to store the window. Also note that the
* values of P, STDDEV and ov are locale-specific, so if the comma
* separator specified by the locale is a comma, a comma should be used.
* *
* \default \c "tukey(0.5)" * \default \c "tukey(0.5)"
* \param encoder An encoder instance to set. * \param encoder An encoder instance to set.
@@ -607,7 +607,7 @@ private:
float* costab = cosTables[i]; float* costab = cosTables[i];
for (int k = 0; k < kr; ++k) for (int k = 0; k < kr; ++k)
costab[k] = (float) (1.0 / (2.0 * cos (double_Pi * (k * 2 + 1) / divv))); costab[k] = (float) (1.0 / (2.0 * std::cos (double_Pi * (k * 2 + 1) / divv)));
} }
for (i = 0, j = 0; i < 256; ++i, ++j, table += 32) for (i = 0, j = 0; i < 256; ++i, ++j, table += 32)
@@ -692,23 +692,23 @@ private:
for (i = 0; i < 18; ++i) for (i = 0; i < 18; ++i)
{ {
win[0][i] = win[1][i] = (float) (0.5 * sin (double_Pi / 72.0 * (2 * i + 1)) / cos (double_Pi * (2 * i + 19) / 72.0)); win[0][i] = win[1][i] = (float) (0.5 * std::sin (double_Pi / 72.0 * (2 * i + 1)) / std::cos (double_Pi * (2 * i + 19) / 72.0));
win[0][i + 18] = win[3][i + 18] = (float) (0.5 * sin (double_Pi / 72.0 * (2 * (i + 18) + 1)) / cos (double_Pi * (2 * (i + 18) + 19) / 72.0)); win[0][i + 18] = win[3][i + 18] = (float) (0.5 * std::sin (double_Pi / 72.0 * (2 * (i + 18) + 1)) / std::cos (double_Pi * (2 * (i + 18) + 19) / 72.0));
} }
const double piOver72 = double_Pi; const double piOver72 = double_Pi;
for (i = 0; i < 6; ++i) for (i = 0; i < 6; ++i)
{ {
win[1][i + 18] = (float) (0.5 / cos (piOver72 * (2 * (i + 18) + 19))); win[1][i + 18] = (float) (0.5 / std::cos (piOver72 * (2 * (i + 18) + 19)));
win[3][i + 12] = (float) (0.5 / cos (piOver72 * (2 * (i + 12) + 19))); win[3][i + 12] = (float) (0.5 / std::cos (piOver72 * (2 * (i + 12) + 19)));
win[1][i + 24] = (float) (0.5 * sin (double_Pi / 24.0 * (2 * i + 13)) / cos (piOver72 * (2 * (i + 24) + 19))); win[1][i + 24] = (float) (0.5 * std::sin (double_Pi / 24.0 * (2 * i + 13)) / std::cos (piOver72 * (2 * (i + 24) + 19)));
win[1][i + 30] = win[3][i] = 0; win[1][i + 30] = win[3][i] = 0;
win[3][i + 6] = (float) (0.5 * sin (double_Pi / 24.0 * (2 * i + 1)) / cos (piOver72 * (2 * (i + 6) + 19))); win[3][i + 6] = (float) (0.5 * std::sin (double_Pi / 24.0 * (2 * i + 1)) / std::cos (piOver72 * (2 * (i + 6) + 19)));
} }
for (i = 0; i < 12; ++i) for (i = 0; i < 12; ++i)
win[2][i] = (float) (0.5 * sin (double_Pi / 24.0 * (2 * i + 1)) / cos (double_Pi * (2 * i + 7) / 24.0)); win[2][i] = (float) (0.5 * std::sin (double_Pi / 24.0 * (2 * i + 1)) / std::cos (double_Pi * (2 * i + 7) / 24.0));
for (j = 0; j < 4; ++j) for (j = 0; j < 4; ++j)
{ {
@@ -721,7 +721,7 @@ private:
for (i = 0; i < 16; ++i) for (i = 0; i < 16; ++i)
{ {
const double t = tan (i * double_Pi / 12.0); const double t = std::tan (i * double_Pi / 12.0);
tan1_1[i] = (float) (t / (1.0 + t)); tan1_1[i] = (float) (t / (1.0 + t));
tan2_1[i] = (float) (1.0 / (1.0 + t)); tan2_1[i] = (float) (1.0 / (1.0 + t));
tan1_2[i] = (float) (sqrt2 * t / (1.0 + t)); tan1_2[i] = (float) (sqrt2 * t / (1.0 + t));
@@ -1,7 +1,7 @@
{ {
"id": "juce_audio_formats", "id": "juce_audio_formats",
"name": "JUCE audio file format codecs", "name": "JUCE audio file format codecs",
"version": "3.0.8", "version": "3.1.1",
"description": "Classes for reading and writing various audio file formats.", "description": "Classes for reading and writing various audio file formats.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",
@@ -119,7 +119,7 @@ void SamplerVoice::startNote (const int midiNoteNumber,
if (sound->releaseSamples > 0) if (sound->releaseSamples > 0)
releaseDelta = (float) (-pitchRatio / sound->releaseSamples); releaseDelta = (float) (-pitchRatio / sound->releaseSamples);
else else
releaseDelta = 0.0f; releaseDelta = -1.0f;
} }
else else
{ {
@@ -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::IComponentHandler3, // From VST V3.5.0 (also very well named!)
public Vst::IContextMenuTarget, public Vst::IContextMenuTarget,
public Vst::IHostApplication, public Vst::IHostApplication,
public Vst::IParamValueQueue,
public Vst::IUnitHandler public Vst::IUnitHandler
{ {
public: public:
@@ -684,31 +683,6 @@ public:
return kNotImplemented; 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 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::IComponentHandler3)
TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IContextMenuTarget) 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::IHostApplication)
TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IParamValueQueue)
TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IUnitHandler) TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IUnitHandler)
TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (iid, FUnknown, Vst::IComponentHandler) TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (iid, FUnknown, Vst::IComponentHandler)
@@ -2052,6 +2025,100 @@ public:
(void) sizeInBytes; (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<int> refCount;
const Vst::ParamID paramID;
Array<ParamPoint> points;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParamValueQueue)
};
Atomic<int> refCount;
OwnedArray<ParamValueQueue> queues;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParameterChangeList)
};
private: private:
//============================================================================== //==============================================================================
VST3ModuleHandle::Ptr module; VST3ModuleHandle::Ptr module;
@@ -2122,35 +2189,6 @@ private:
return stream; 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<int> refCount;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ParameterChangeList)
};
ComSmartPtr<ParameterChangeList> inputParameterChanges, outputParameterChanges; ComSmartPtr<ParameterChangeList> inputParameterChanges, outputParameterChanges;
ComSmartPtr<MidiEventList> midiInputs, midiOutputs; ComSmartPtr<MidiEventList> midiInputs, midiOutputs;
Vst::ProcessContext timingInfo; //< Only use this in processBlock()! Vst::ProcessContext timingInfo; //< Only use this in processBlock()!
@@ -135,7 +135,14 @@ namespace
char chunk[8]; // variable 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 VstInt32 fxbSwap (const VstInt32 x) noexcept { return (VstInt32) ByteOrder::swapIfLittleEndian ((uint32) x); }
static float fxbSwapFloat (const float x) noexcept static float fxbSwapFloat (const float x) noexcept
@@ -1013,12 +1020,12 @@ public:
if (position.isLooping) if (position.isLooping)
{ {
vstHostTime.cycleStartPos = position.ppqLoopStart; vstHostTime.cycleStartPos = position.ppqLoopStart;
vstHostTime.cycleEndPos = position.ppqLoopEnd; vstHostTime.cycleEndPos = position.ppqLoopEnd;
vstHostTime.flags |= kVstCyclePosValid; vstHostTime.flags |= (kVstCyclePosValid | kVstTransportCycleActive);
} }
else else
{ {
vstHostTime.flags &= ~kVstCyclePosValid; vstHostTime.flags &= ~(kVstCyclePosValid | kVstTransportCycleActive);
} }
} }
@@ -1432,11 +1439,10 @@ public:
const fxSet* const set = (const fxSet*) data; const fxSet* const set = (const fxSet*) data;
if ((set->chunkMagic != fxbName ("CcnK") && set->chunkMagic != fxbName ("KncC")) if ((! compareMagic (set->chunkMagic, "CcnK")) || fxbSwap (set->version) > fxbVersionNum)
|| fxbSwap (set->version) > fxbVersionNum)
return false; return false;
if (set->fxMagic == fxbName ("FxBk")) if (compareMagic (set->fxMagic, "FxBk"))
{ {
// bank of programs // bank of programs
if (fxbSwap (set->numPrograms) >= 0) if (fxbSwap (set->numPrograms) >= 0)
@@ -1472,12 +1478,12 @@ public:
return false; return false;
} }
} }
else if (set->fxMagic == fxbName ("FxCk")) else if (compareMagic (set->fxMagic, "FxCk"))
{ {
// single program // single program
const fxProgram* const prog = (const fxProgram*) data; const fxProgram* const prog = (const fxProgram*) data;
if (prog->chunkMagic != fxbName ("CcnK")) if (! compareMagic (prog->chunkMagic, "CcnK"))
return false; return false;
changeProgramName (getCurrentProgram(), prog->prgName); changeProgramName (getCurrentProgram(), prog->prgName);
@@ -1485,7 +1491,7 @@ public:
for (int i = 0; i < fxbSwap (prog->numParams); ++i) for (int i = 0; i < fxbSwap (prog->numParams); ++i)
setParameter (i, fxbSwapFloat (prog->params[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 // non-preset chunk
const fxChunkSet* const cset = (const fxChunkSet*) data; const fxChunkSet* const cset = (const fxChunkSet*) data;
@@ -1495,7 +1501,7 @@ public:
setChunkData (cset->chunk, fxbSwap (cset->chunkSize), false); 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 // preset chunk
const fxProgramSet* const cset = (const fxProgramSet*) data; const fxProgramSet* const cset = (const fxProgramSet*) data;
@@ -1671,7 +1677,8 @@ private:
bool restoreProgramSettings (const fxProgram* const prog) 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); changeProgramName (getCurrentProgram(), prog->prgName);
@@ -1,7 +1,7 @@
{ {
"id": "juce_audio_processors", "id": "juce_audio_processors",
"name": "JUCE audio plugin hosting classes", "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.", "description": "Classes for loading and playing VST, AU, or internally-generated audio processors.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",
@@ -67,7 +67,7 @@ public:
if (paramHasChanged) if (paramHasChanged)
{ {
refresh(); refresh();
startTimer (1000 / 50); startTimerHz (50);
} }
else else
{ {
@@ -133,7 +133,7 @@ public:
if (reader != nullptr) if (reader != nullptr)
{ {
if (levels.size() < (int) reader->numChannels) if (levels.size() < (int) reader->numChannels)
levels.insertMultiple (0, Range<float>(), (int) (reader->numChannels - levels.size())); levels.insertMultiple (0, Range<float>(), (int) reader->numChannels - levels.size());
reader->readMaxLevels (startSample, numSamples, levels.getRawDataPointer(), (int) reader->numChannels); reader->readMaxLevels (startSample, numSamples, levels.getRawDataPointer(), (int) reader->numChannels);
@@ -240,7 +240,7 @@ private:
for (int i = 0; i < numThumbSamps; ++i) for (int i = 0; i < numThumbSamps; ++i)
{ {
reader->readMaxLevels ((firstThumbIndex + i) * owner.samplesPerThumbSample, reader->readMaxLevels ((firstThumbIndex + i) * owner.samplesPerThumbSample,
owner.samplesPerThumbSample, levelsRead, numChannels); owner.samplesPerThumbSample, levelsRead, (int) numChannels);
for (int j = 0; j < (int) numChannels; ++j) for (int j = 0; j < (int) numChannels; ++j)
levels[j][i].setFloat (levelsRead[j]); levels[j][i].setFloat (levelsRead[j]);
@@ -26,11 +26,8 @@ class MidiKeyboardUpDownButton : public Button
{ {
public: public:
MidiKeyboardUpDownButton (MidiKeyboardComponent& comp, const int d) MidiKeyboardUpDownButton (MidiKeyboardComponent& comp, const int d)
: Button (String::empty), : Button (String::empty), owner (comp), delta (d)
owner (comp),
delta (d)
{ {
setOpaque (true);
} }
void clicked() override void clicked() override
@@ -60,8 +57,7 @@ private:
}; };
//============================================================================== //==============================================================================
MidiKeyboardComponent::MidiKeyboardComponent (MidiKeyboardState& s, MidiKeyboardComponent::MidiKeyboardComponent (MidiKeyboardState& s, Orientation o)
const Orientation o)
: state (s), : state (s),
xOffset (0), xOffset (0),
blackNoteLength (1), blackNoteLength (1),
@@ -92,12 +88,12 @@ MidiKeyboardComponent::MidiKeyboardComponent (MidiKeyboardState& s,
mouseOverNotes.insertMultiple (0, -1, 32); mouseOverNotes.insertMultiple (0, -1, 32);
mouseDownNotes.insertMultiple (0, -1, 32); mouseDownNotes.insertMultiple (0, -1, 32);
setOpaque (true); colourChanged();
setWantsKeyboardFocus (true); setWantsKeyboardFocus (true);
state.addListener (this); state.addListener (this);
startTimer (1000 / 20); startTimerHz (20);
} }
MidiKeyboardComponent::~MidiKeyboardComponent() MidiKeyboardComponent::~MidiKeyboardComponent()
@@ -169,6 +165,7 @@ void MidiKeyboardComponent::setScrollButtonsVisible (const bool newCanScroll)
void MidiKeyboardComponent::colourChanged() void MidiKeyboardComponent::colourChanged()
{ {
setOpaque (findColour (whiteNoteColourId).isOpaque());
repaint(); repaint();
} }
@@ -342,7 +339,7 @@ void MidiKeyboardComponent::repaintNote (const int noteNum)
void MidiKeyboardComponent::paint (Graphics& g) void MidiKeyboardComponent::paint (Graphics& g)
{ {
g.fillAll (Colours::white.overlaidWith (findColour (whiteNoteColourId))); g.fillAll (findColour (whiteNoteColourId));
const Colour lineColour (findColour (keySeparatorLineColourId)); const Colour lineColour (findColour (keySeparatorLineColourId));
const Colour textColour (findColour (textLabelColourId)); const Colour textColour (findColour (textLabelColourId));
@@ -45,6 +45,7 @@ namespace juce
#include "gui/juce_AudioThumbnail.cpp" #include "gui/juce_AudioThumbnail.cpp"
#include "gui/juce_AudioThumbnailCache.cpp" #include "gui/juce_AudioThumbnailCache.cpp"
#include "gui/juce_MidiKeyboardComponent.cpp" #include "gui/juce_MidiKeyboardComponent.cpp"
#include "gui/juce_AudioAppComponent.cpp"
#include "players/juce_AudioProcessorPlayer.cpp" #include "players/juce_AudioProcessorPlayer.cpp"
} }
@@ -39,6 +39,7 @@ namespace juce
#include "gui/juce_AudioThumbnail.h" #include "gui/juce_AudioThumbnail.h"
#include "gui/juce_AudioThumbnailCache.h" #include "gui/juce_AudioThumbnailCache.h"
#include "gui/juce_MidiKeyboardComponent.h" #include "gui/juce_MidiKeyboardComponent.h"
#include "gui/juce_AudioAppComponent.h"
#include "players/juce_AudioProcessorPlayer.h" #include "players/juce_AudioProcessorPlayer.h"
} }
@@ -1,7 +1,7 @@
{ {
"id": "juce_audio_utils", "id": "juce_audio_utils",
"name": "JUCE extra audio utility classes", "name": "JUCE extra audio utility classes",
"version": "3.0.8", "version": "3.1.1",
"description": "Classes for audio-related GUI and miscellaneous tasks.", "description": "Classes for audio-related GUI and miscellaneous tasks.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",
@@ -474,7 +474,11 @@ public:
numUsed += numberOfTimesToInsertIt; numUsed += numberOfTimesToInsertIt;
while (--numberOfTimesToInsertIt >= 0) 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
}
} }
} }
@@ -73,64 +73,71 @@ bool DirectoryIterator::next()
bool DirectoryIterator::next (bool* const isDirResult, bool* const isHiddenResult, int64* const fileSize, bool DirectoryIterator::next (bool* const isDirResult, bool* const isHiddenResult, int64* const fileSize,
Time* const modTime, Time* const creationTime, bool* const isReadOnly) Time* const modTime, Time* const creationTime, bool* const isReadOnly)
{ {
hasBeenAdvanced = true; for (;;)
if (subIterator != nullptr)
{ {
if (subIterator->next (isDirResult, isHiddenResult, fileSize, modTime, creationTime, isReadOnly)) hasBeenAdvanced = true;
return true;
subIterator = nullptr; if (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 ("."))
{ {
bool matches = false; if (subIterator->next (isDirResult, isHiddenResult, fileSize, modTime, creationTime, isReadOnly))
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; return true;
}
if (subIterator != nullptr) subIterator = nullptr;
return next (isDirResult, isHiddenResult, fileSize, modTime, creationTime, isReadOnly);
} }
}
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 const File& DirectoryIterator::getFile() const
@@ -219,6 +219,11 @@ bool File::setReadOnly (const bool shouldBeReadOnly,
return setFileReadOnlyInternal (shouldBeReadOnly) && worked; return setFileReadOnlyInternal (shouldBeReadOnly) && worked;
} }
bool File::setExecutePermission (bool shouldBeExecutable) const
{
return setFileExecutableInternal (shouldBeExecutable);
}
bool File::deleteRecursively() const bool File::deleteRecursively() const
{ {
bool worked = true; bool worked = true;
@@ -348,6 +348,13 @@ public:
bool setReadOnly (bool shouldBeReadOnly, bool setReadOnly (bool shouldBeReadOnly,
bool applyRecursively = false) const; 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. /** Returns true if this file is a hidden or system file.
The criteria for deciding whether a file is hidden are platform-dependent. 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; bool setFileTimesInternal (int64 m, int64 a, int64 c) const;
void getFileTimesInternal (int64& m, int64& a, int64& c) const; void getFileTimesInternal (int64& m, int64& a, int64& c) const;
bool setFileReadOnlyInternal (bool) const; bool setFileReadOnlyInternal (bool) const;
bool setFileExecutableInternal (bool) const;
}; };
#endif // JUCE_FILE_H_INCLUDED #endif // JUCE_FILE_H_INCLUDED
@@ -1,7 +1,7 @@
{ {
"id": "juce_core", "id": "juce_core",
"name": "JUCE core classes", "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.", "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", "website": "http://www.juce.com/juce",
"license": "ISC Permissive", "license": "ISC Permissive",
@@ -32,7 +32,7 @@ FileLogger::FileLogger (const File& file,
: logFile (file) : logFile (file)
{ {
if (maxInitialFileSizeBytes >= 0) if (maxInitialFileSizeBytes >= 0)
trimFileSize (maxInitialFileSizeBytes); trimFileSize (logFile, maxInitialFileSizeBytes);
if (! file.exists()) if (! file.exists())
file.create(); // (to create the parent directories) file.create(); // (to create the parent directories)
@@ -57,23 +57,23 @@ void FileLogger::logMessage (const String& message)
out << message << newLine; out << message << newLine;
} }
void FileLogger::trimFileSize (int64 maxFileSizeBytes) const void FileLogger::trimFileSize (const File& file, int64 maxFileSizeBytes)
{ {
if (maxFileSizeBytes <= 0) if (maxFileSizeBytes <= 0)
{ {
logFile.deleteFile(); file.deleteFile();
} }
else else
{ {
const int64 fileSize = logFile.getSize(); const int64 fileSize = file.getSize();
if (fileSize > maxFileSizeBytes) if (fileSize > maxFileSizeBytes)
{ {
TemporaryFile tempFile (logFile); TemporaryFile tempFile (file);
{ {
FileOutputStream out (tempFile.getFile()); FileOutputStream out (tempFile.getFile());
FileInputStream in (logFile); FileInputStream in (file);
if (! (out.openedOk() && in.openedOk())) if (! (out.openedOk() && in.openedOk()))
return; return;
@@ -121,13 +121,17 @@ public:
// (implementation of the Logger virtual method) // (implementation of the Logger virtual method)
void logMessage (const String&); 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: private:
//============================================================================== //==============================================================================
File logFile; File logFile;
CriticalSection logLock; CriticalSection logLock;
void trimFileSize (int64 maxFileSizeBytes) const;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileLogger) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FileLogger)
}; };
@@ -1162,9 +1162,9 @@ double Expression::Scope::evaluateFunction (const String& functionName, const do
if (numParams == 1) if (numParams == 1)
{ {
if (functionName == "sin") return sin (parameters[0]); if (functionName == "sin") return std::sin (parameters[0]);
if (functionName == "cos") return cos (parameters[0]); if (functionName == "cos") return std::cos (parameters[0]);
if (functionName == "tan") return tan (parameters[0]); if (functionName == "tan") return std::tan (parameters[0]);
if (functionName == "abs") return std::abs (parameters[0]); if (functionName == "abs") return std::abs (parameters[0]);
} }
} }
@@ -104,7 +104,7 @@ public:
ValueType proportion = (v - start) / (end - start); ValueType proportion = (v - start) / (end - start);
if (skew != static_cast<ValueType> (1)) if (skew != static_cast<ValueType> (1))
proportion = pow (proportion, skew); proportion = std::pow (proportion, skew);
return proportion; return proportion;
} }
@@ -115,7 +115,7 @@ public:
ValueType convertFrom0to1 (ValueType proportion) const noexcept ValueType convertFrom0to1 (ValueType proportion) const noexcept
{ {
if (skew != static_cast<ValueType> (1) && proportion > ValueType()) if (skew != static_cast<ValueType> (1) && proportion > ValueType())
proportion = exp (log (proportion) / skew); proportion = std::exp (std::log (proportion) / skew);
return start + (end - start) * proportion; return start + (end - start) * proportion;
} }
@@ -278,7 +278,7 @@ String SystemStats::getDisplayLanguage() { return getUserLanguage() + "-" + getU
//============================================================================== //==============================================================================
void CPUInformation::initialise() noexcept void CPUInformation::initialise() noexcept
{ {
numCpus = jmax (1, sysconf (_SC_NPROCESSORS_ONLN)); numCpus = jmax (1, (int) sysconf (_SC_NPROCESSORS_ONLN));
} }
//============================================================================== //==============================================================================
@@ -32,17 +32,21 @@ String String::fromCFString (CFStringRef cfString)
return String(); return String();
CFRange range = { 0, CFStringGetLength (cfString) }; CFRange range = { 0, CFStringGetLength (cfString) };
HeapBlock <UniChar> u ((size_t) range.length + 1); CFIndex bytesNeeded = 0;
CFStringGetCharacters (cfString, range, u); CFStringGetBytes (cfString, range, kCFStringEncodingUTF8, 0, false, nullptr, 0, &bytesNeeded);
u[range.length] = 0;
return String (CharPointer_UTF16 ((const CharPointer_UTF16::CharType*) u.getData())); HeapBlock<UInt8> 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 CFStringRef String::toCFString() const
{ {
CharPointer_UTF16 utf16 (toUTF16()); const char* const utf8 = toRawUTF8();
return CFStringCreateWithCharacters (kCFAllocatorDefault, (const UniChar*) utf16.getAddress(), (CFIndex) utf16.length()); return CFStringCreateWithBytes (kCFAllocatorDefault, (const UInt8*) utf8,
(CFIndex) strlen (utf8), kCFStringEncodingUTF8, false);
} }
String String::convertToPrecomposedUnicode() const String String::convertToPrecomposedUnicode() const
@@ -72,7 +76,7 @@ String String::convertToPrecomposedUnicode() const
{ {
const size_t bytesNeeded = CharPointer_UTF16::getBytesRequiredFor (getCharPointer()); const size_t bytesNeeded = CharPointer_UTF16::getBytesRequiredFor (getCharPointer());
HeapBlock <char> tempOut; HeapBlock<char> tempOut;
tempOut.calloc (bytesNeeded + 4); tempOut.calloc (bytesNeeded + 4);
ByteCount bytesRead = 0; ByteCount bytesRead = 0;
@@ -304,23 +304,33 @@ bool File::hasWriteAccess() const
return false; return false;
} }
bool File::setFileReadOnlyInternal (const bool shouldBeReadOnly) const static bool setFileModeFlags (const String& fullPath, mode_t flags, bool shouldSet) noexcept
{ {
juce_statStruct info; juce_statStruct info;
if (! juce_stat (fullPath, info)) if (! juce_stat (fullPath, info))
return false; return false;
info.st_mode &= 0777; // Just permissions info.st_mode &= 0777;
if (shouldBeReadOnly) if (shouldSet)
info.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); info.st_mode |= flags;
else else
// Give everybody write permission? info.st_mode &= ~flags;
info.st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
return chmod (fullPath.toUTF8(), info.st_mode) == 0; 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 void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int64& creationTime) const
{ {
modificationTime = 0; modificationTime = 0;
@@ -328,11 +338,12 @@ void File::getFileTimesInternal (int64& modificationTime, int64& accessTime, int
creationTime = 0; creationTime = 0;
juce_statStruct info; juce_statStruct info;
if (juce_stat (fullPath, info)) if (juce_stat (fullPath, info))
{ {
modificationTime = (int64) info.st_mtime * 1000; modificationTime = (int64) info.st_mtime * 1000;
accessTime = (int64) info.st_atime * 1000; accessTime = (int64) info.st_atime * 1000;
creationTime = (int64) info.st_ctime * 1000; creationTime = (int64) info.st_ctime * 1000;
} }
} }
@@ -163,6 +163,12 @@ bool File::setFileReadOnlyInternal (const bool shouldBeReadOnly) const
|| SetFileAttributes (fullPath.toWideCharPointer(), newAtts) != FALSE; || SetFileAttributes (fullPath.toWideCharPointer(), newAtts) != FALSE;
} }
bool File::setFileExecutableInternal (bool /*shouldBeExecutable*/) const
{
// XXX is this possible?
return false;
}
bool File::isHidden() const bool File::isHidden() const
{ {
return (WindowsFileHelpers::getAtts (fullPath) & FILE_ATTRIBUTE_HIDDEN) != 0; return (WindowsFileHelpers::getAtts (fullPath) & FILE_ATTRIBUTE_HIDDEN) != 0;
@@ -389,7 +389,10 @@ void StreamingSocket::close()
} }
if (handle != -1) if (handle != -1)
{
::shutdown (handle, SHUT_RDWR);
::close (handle); ::close (handle);
}
#endif #endif
hostName.clear(); hostName.clear();
@@ -397,6 +397,17 @@ URL URL::withParameter (const String& parameterName,
return u; 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 URL::withPOSTData (const String& newPostData) const
{ {
URL u (*this); URL u (*this);
@@ -482,8 +493,8 @@ String URL::addEscapeChars (const String& s, const bool isParameter)
|| legalChars.indexOf ((juce_wchar) c) >= 0)) || legalChars.indexOf ((juce_wchar) c) >= 0))
{ {
utf8.set (i, '%'); utf8.set (i, '%');
utf8.insert (++i, "0123456789abcdef" [((uint8) c) >> 4]); utf8.insert (++i, "0123456789ABCDEF" [((uint8) c) >> 4]);
utf8.insert (++i, "0123456789abcdef" [c & 15]); utf8.insert (++i, "0123456789ABCDEF" [c & 15]);
} }
} }
@@ -140,6 +140,12 @@ public:
URL withParameter (const String& parameterName, URL withParameter (const String& parameterName,
const String& parameterValue) const; 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. /** 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 When performing a POST where one of your parameters is a binary file, this
@@ -35,8 +35,8 @@
See also SystemStats::getJUCEVersion() for a string version. See also SystemStats::getJUCEVersion() for a string version.
*/ */
#define JUCE_MAJOR_VERSION 3 #define JUCE_MAJOR_VERSION 3
#define JUCE_MINOR_VERSION 0 #define JUCE_MINOR_VERSION 1
#define JUCE_BUILDNUMBER 8 #define JUCE_BUILDNUMBER 1
/** Current Juce version number. /** Current Juce version number.
@@ -47,28 +47,29 @@ public:
/** The set of possible results of the getOperatingSystemType() method. */ /** The set of possible results of the getOperatingSystemType() method. */
enum OperatingSystemType enum OperatingSystemType
{ {
UnknownOS = 0, UnknownOS = 0,
Linux = 0x2000, Linux = 0x2000,
Android = 0x3000, Android = 0x3000,
iOS = 0x8000, iOS = 0x8000,
MacOSX_10_4 = 0x1004, MacOSX_10_4 = 0x1004,
MacOSX_10_5 = 0x1005, MacOSX_10_5 = 0x1005,
MacOSX_10_6 = 0x1006, MacOSX_10_6 = 0x1006,
MacOSX_10_7 = 0x1007, MacOSX_10_7 = 0x1007,
MacOSX_10_8 = 0x1008, MacOSX_10_8 = 0x1008,
MacOSX_10_9 = 0x1009, MacOSX_10_9 = 0x1009,
MacOSX_10_10 = 0x100a,
Win2000 = 0x4105, Win2000 = 0x4105,
WinXP = 0x4106, WinXP = 0x4106,
WinVista = 0x4107, WinVista = 0x4107,
Windows7 = 0x4108, Windows7 = 0x4108,
Windows8_0 = 0x4109, Windows8_0 = 0x4109,
Windows8_1 = 0x410a, Windows8_1 = 0x410a,
Windows = 0x4000, /**< To test whether any version of Windows is running, Windows = 0x4000, /**< To test whether any version of Windows is running,
you can use the expression ((getOperatingSystemType() & Windows) != 0). */ you can use the expression ((getOperatingSystemType() & Windows) != 0). */
}; };
/** Returns the type of operating system we're running on. /** Returns the type of operating system we're running on.
@@ -41,7 +41,7 @@
@code @code
XmlDocument myDocument (File ("myfile.xml")); XmlDocument myDocument (File ("myfile.xml"));
XmlElement* mainElement = myDocument.getDocumentElement(); ScopedPointer<XmlElement> mainElement (myDocument.getDocumentElement());
if (mainElement == nullptr) if (mainElement == nullptr)
{ {
@@ -57,7 +57,7 @@
Or you can use the static helper methods for quick parsing.. Or you can use the static helper methods for quick parsing..
@code @code
XmlElement* xml = XmlDocument::parse (myXmlFile); ScopedPointer<XmlElement> xml (XmlDocument::parse (myXmlFile));
if (xml != nullptr && xml->hasTagName ("foobar")) if (xml != nullptr && xml->hasTagName ("foobar"))
{ {
@@ -1,7 +1,7 @@
{ {
"id": "juce_cryptography", "id": "juce_cryptography",
"name": "JUCE cryptography classes", "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.", "description": "Classes for various basic cryptography functions, including RSA, Blowfish, MD5, SHA, etc.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",
@@ -1,7 +1,7 @@
{ {
"id": "juce_data_structures", "id": "juce_data_structures",
"name": "JUCE data model helper classes", "name": "JUCE data model helper classes",
"version": "3.0.8", "version": "3.1.1",
"description": "Classes for undo/redo management, and smart data structures.", "description": "Classes for undo/redo management, and smart data structures.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",
@@ -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 #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Value::Value (Value&& other) noexcept Value::Value (Value&& other) noexcept
{ {
@@ -221,7 +221,11 @@ private:
// This is disallowed to avoid confusion about whether it should // This is disallowed to avoid confusion about whether it should
// do a by-value or by-reference copy. // 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. */ /** Writes a Value to an OutputStream as a UTF8 string. */
@@ -39,6 +39,7 @@ namespace juce
#include "messages/juce_NotificationType.h" #include "messages/juce_NotificationType.h"
#include "messages/juce_ApplicationBase.h" #include "messages/juce_ApplicationBase.h"
#include "messages/juce_Initialisation.h" #include "messages/juce_Initialisation.h"
#include "messages/juce_MountedVolumeListChangeDetector.h"
#include "broadcasters/juce_ListenerList.h" #include "broadcasters/juce_ListenerList.h"
#include "broadcasters/juce_ActionBroadcaster.h" #include "broadcasters/juce_ActionBroadcaster.h"
#include "broadcasters/juce_ActionListener.h" #include "broadcasters/juce_ActionListener.h"
@@ -1,7 +1,7 @@
{ {
"id": "juce_events", "id": "juce_events",
"name": "JUCE message and event handling classes", "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.", "description": "Classes for running an application's main event loop and sending/receiving messages, timers, etc.",
"website": "http://www.juce.com/juce", "website": "http://www.juce.com/juce",
"license": "GPL/Commercial", "license": "GPL/Commercial",
@@ -42,7 +42,7 @@ bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* cons
return true; 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 JUCE_TRY
{ {
@@ -131,7 +131,7 @@ public:
} }
//============================================================================== //==============================================================================
juce_DeclareSingleton_SingleThreaded_Minimal (InternalMessageQueue); juce_DeclareSingleton_SingleThreaded_Minimal (InternalMessageQueue)
private: private:
CriticalSection lock; CriticalSection lock;
@@ -209,7 +209,7 @@ private:
} }
}; };
juce_ImplementSingleton_SingleThreaded (InternalMessageQueue); juce_ImplementSingleton_SingleThreaded (InternalMessageQueue)
//============================================================================== //==============================================================================
@@ -365,3 +365,54 @@ void repostCurrentNSEvent()
(new EventReposter())->post(); (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<NSObject>
{
ObserverClass() : ObjCClass<NSObject> ("JUCEDriveObserver_")
{
addIvar<Pimpl*> ("owner");
addMethod (@selector (changed:), changed, "v@:@");
addProtocol (@protocol (NSTextInput));
registerClass();
}
static Pimpl* getOwner (id self) { return getIvar<Pimpl*> (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
@@ -100,7 +100,6 @@ public:
virtual ~DeviceChangeDetector() {} virtual ~DeviceChangeDetector() {}
protected:
virtual void systemDeviceChanged() = 0; virtual void systemDeviceChanged() = 0;
void triggerAsyncDeviceChangeCallback() void triggerAsyncDeviceChangeCallback()
@@ -188,3 +188,30 @@ void MessageManager::doPlatformSpecificShutdown()
OleUninitialize(); OleUninitialize();
} }
//==============================================================================
struct MountedVolumeListChangeDetector::Pimpl : private DeviceChangeDetector
{
Pimpl (MountedVolumeListChangeDetector& d) : DeviceChangeDetector (L"MountedVolumeList"), owner (d)
{
File::findFileSystemRoots (lastVolumeList);
}
void systemDeviceChanged() override
{
Array<File> newList;
File::findFileSystemRoots (newList);
if (lastVolumeList != newList)
{
lastVolumeList = newList;
owner.mountedVolumeListChanged();
}
}
MountedVolumeListChangeDetector& owner;
Array<File> lastVolumeList;
};
MountedVolumeListChangeDetector::MountedVolumeListChangeDetector() { pimpl = new Pimpl (*this); }
MountedVolumeListChangeDetector::~MountedVolumeListChangeDetector() {}

Some files were not shown because too many files have changed in this diff Show More