diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index e8c586f8d6..595f0e68ee 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -3940,70 +3940,250 @@ END_JUCE_NAMESPACE /*** Start of inlined file: juce_Variant.cpp ***/ BEGIN_JUCE_NAMESPACE +class var::VariantType +{ +public: + VariantType() {} + virtual ~VariantType() {} + + virtual int toInt (const ValueUnion&) const { return 0; } + virtual double toDouble (const ValueUnion&) const { return 0; } + virtual float toFloat (const ValueUnion&) const { return 0; } + virtual const String toString (const ValueUnion&) const { return String::empty; } + virtual bool toBool (const ValueUnion&) const { return false; } + virtual DynamicObject* toObject (const ValueUnion&) const { return 0; } + + virtual bool isVoid() const throw() { return false; } + virtual bool isInt() const throw() { return false; } + virtual bool isBool() const throw() { return false; } + virtual bool isDouble() const throw() { return false; } + virtual bool isString() const throw() { return false; } + virtual bool isObject() const throw() { return false; } + virtual bool isMethod() const throw() { return false; } + + virtual void cleanUp (ValueUnion&) const throw() {} + virtual void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest = source; } + virtual bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() = 0; + virtual void writeToStream (const ValueUnion& data, OutputStream& output) const = 0; +}; + +class var::VariantType_Void : public var::VariantType +{ +public: + static const VariantType_Void* getInstance() { static const VariantType_Void i; return &i; } + + bool isVoid() const throw() { return true; } + bool equals (const ValueUnion&, const ValueUnion&, const VariantType& otherType) const throw() { return otherType.isVoid(); } + void writeToStream (const ValueUnion&, OutputStream& output) const { output.writeCompressedInt (0); } +}; + +class var::VariantType_Int : public var::VariantType +{ +public: + static const VariantType_Int* getInstance() { static const VariantType_Int i; return &i; } + + int toInt (const ValueUnion& data) const { return data.intValue; }; + double toDouble (const ValueUnion& data) const { return (double) data.intValue; } + float toFloat (const ValueUnion& data) const { return (float) data.intValue; } + const String toString (const ValueUnion& data) const { return String (data.intValue); } + bool toBool (const ValueUnion& data) const { return data.intValue != 0; } + + bool isInt() const throw() { return true; } + + bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() + { + return otherType.toInt (otherData) == data.intValue; + } + + void writeToStream (const ValueUnion& data, OutputStream& output) const + { + output.writeCompressedInt (5); + output.writeByte (1); + output.writeInt (data.intValue); + } +}; + +class var::VariantType_Double : public var::VariantType +{ +public: + static const VariantType_Double* getInstance() { static const VariantType_Double i; return &i; } + + int toInt (const ValueUnion& data) const { return (int) data.doubleValue; }; + double toDouble (const ValueUnion& data) const { return data.doubleValue; } + float toFloat (const ValueUnion& data) const { return (float) data.doubleValue; } + const String toString (const ValueUnion& data) const { return String (data.doubleValue); } + bool toBool (const ValueUnion& data) const { return data.doubleValue != 0; } + + bool isDouble() const throw() { return true; } + + bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() + { + return otherType.toDouble (otherData) == data.doubleValue; + } + + void writeToStream (const ValueUnion& data, OutputStream& output) const + { + output.writeCompressedInt (9); + output.writeByte (4); + output.writeDouble (data.doubleValue); + } +}; + +class var::VariantType_Bool : public var::VariantType +{ +public: + static const VariantType_Bool* getInstance() { static const VariantType_Bool i; return &i; } + + int toInt (const ValueUnion& data) const { return data.boolValue ? 1 : 0; }; + double toDouble (const ValueUnion& data) const { return data.boolValue ? 1.0 : 0.0; } + float toFloat (const ValueUnion& data) const { return data.boolValue ? 1.0f : 0.0f; } + const String toString (const ValueUnion& data) const { return String::charToString (data.boolValue ? '1' : '0'); } + bool toBool (const ValueUnion& data) const { return data.boolValue; } + + bool isBool() const throw() { return true; } + + bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() + { + return otherType.toBool (otherData) == data.boolValue; + } + + void writeToStream (const ValueUnion& data, OutputStream& output) const + { + output.writeCompressedInt (1); + output.writeByte (data.boolValue ? 2 : 3); + } +}; + +class var::VariantType_String : public var::VariantType +{ +public: + static const VariantType_String* getInstance() { static const VariantType_String i; return &i; } + + void cleanUp (ValueUnion& data) const throw() { delete data.stringValue; } + void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.stringValue = new String (*source.stringValue); } + + int toInt (const ValueUnion& data) const { return data.stringValue->getIntValue(); }; + double toDouble (const ValueUnion& data) const { return data.stringValue->getDoubleValue(); } + float toFloat (const ValueUnion& data) const { return data.stringValue->getFloatValue(); } + const String toString (const ValueUnion& data) const { return *data.stringValue; } + bool toBool (const ValueUnion& data) const { return data.stringValue->getIntValue() != 0 + || data.stringValue->trim().equalsIgnoreCase ("true") + || data.stringValue->trim().equalsIgnoreCase ("yes"); } + + bool isString() const throw() { return true; } + + bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() + { + return otherType.toString (otherData) == *data.stringValue; + } + + void writeToStream (const ValueUnion& data, OutputStream& output) const + { + const int len = data.stringValue->getNumBytesAsUTF8() + 1; + output.writeCompressedInt (len + 1); + output.writeByte (5); + HeapBlock temp (len); + data.stringValue->copyToUTF8 (temp, len); + output.write (temp, len); + } +}; + +class var::VariantType_Object : public var::VariantType +{ +public: + static const VariantType_Object* getInstance() { static const VariantType_Object i; return &i; } + + void cleanUp (ValueUnion& data) const throw() { if (data.objectValue != 0) data.objectValue->decReferenceCount(); } + void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.objectValue = source.objectValue; if (dest.objectValue != 0) dest.objectValue->incReferenceCount(); } + + const String toString (const ValueUnion& data) const { return "Object 0x" + String::toHexString ((int) (pointer_sized_int) data.objectValue); } + bool toBool (const ValueUnion& data) const { return data.objectValue != 0; } + DynamicObject* toObject (const ValueUnion& data) const { return data.objectValue; } + + bool isObject() const throw() { return true; } + + bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() + { + return otherType.toObject (otherData) == data.objectValue; + } + + void writeToStream (const ValueUnion&, OutputStream& output) const + { + jassertfalse; // Can't write an object to a stream! + output.writeCompressedInt (0); + } +}; + +class var::VariantType_Method : public var::VariantType +{ +public: + static const VariantType_Method* getInstance() { static const VariantType_Method i; return &i; } + + const String toString (const ValueUnion&) const { return "Method"; } + bool toBool (const ValueUnion& data) const { return data.methodValue != 0; } + + bool isMethod() const throw() { return true; } + + bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() + { + return otherType.isMethod() && otherData.methodValue == data.methodValue; + } + + void writeToStream (const ValueUnion&, OutputStream& output) const + { + jassertfalse; // Can't write a method to a stream! + output.writeCompressedInt (0); + } +}; + var::var() throw() - : type (voidType) + : type (VariantType_Void::getInstance()) { - value.doubleValue = 0; } var::~var() throw() { - if (type == stringType) - delete value.stringValue; - else if (type == objectType && value.objectValue != 0) - value.objectValue->decReferenceCount(); + type->cleanUp (value); } const var var::null; -var::var (const var& valueToCopy) - : type (valueToCopy.type), - value (valueToCopy.value) +var::var (const var& valueToCopy) : type (valueToCopy.type) { - if (type == stringType) - value.stringValue = new String (*(value.stringValue)); - else if (type == objectType && value.objectValue != 0) - value.objectValue->incReferenceCount(); + type->createCopy (value, valueToCopy.value); } -var::var (const int value_) throw() - : type (intType) +var::var (const int value_) throw() : type (VariantType_Int::getInstance()) { value.intValue = value_; } -var::var (const bool value_) throw() - : type (boolType) +var::var (const bool value_) throw() : type (VariantType_Bool::getInstance()) { value.boolValue = value_; } -var::var (const double value_) throw() - : type (doubleType) +var::var (const double value_) throw() : type (VariantType_Double::getInstance()) { value.doubleValue = value_; } -var::var (const String& value_) - : type (stringType) +var::var (const String& value_) : type (VariantType_String::getInstance()) { value.stringValue = new String (value_); } -var::var (const char* const value_) - : type (stringType) +var::var (const char* const value_) : type (VariantType_String::getInstance()) { value.stringValue = new String (value_); } -var::var (const juce_wchar* const value_) - : type (stringType) +var::var (const juce_wchar* const value_) : type (VariantType_String::getInstance()) { value.stringValue = new String (value_); } -var::var (DynamicObject* const object) - : type (objectType) +var::var (DynamicObject* const object) : type (VariantType_Object::getInstance()) { value.objectValue = object; @@ -4011,125 +4191,46 @@ var::var (DynamicObject* const object) object->incReferenceCount(); } -var::var (MethodFunction method_) throw() - : type (methodType) +var::var (MethodFunction method_) throw() : type (VariantType_Method::getInstance()) { value.methodValue = method_; } +bool var::isVoid() const throw() { return type->isVoid(); } +bool var::isInt() const throw() { return type->isInt(); } +bool var::isBool() const throw() { return type->isBool(); } +bool var::isDouble() const throw() { return type->isDouble(); } +bool var::isString() const throw() { return type->isString(); } +bool var::isObject() const throw() { return type->isObject(); } +bool var::isMethod() const throw() { return type->isMethod(); } + +var::operator int() const { return type->toInt (value); } +var::operator bool() const { return type->toBool (value); } +var::operator float() const { return type->toFloat (value); } +var::operator double() const { return type->toDouble (value); } +const String var::toString() const { return type->toString (value); } +var::operator const String() const { return type->toString (value); } +DynamicObject* var::getObject() const { return type->toObject (value); } + void var::swapWith (var& other) throw() { swapVariables (type, other.type); swapVariables (value, other.value); } -var& var::operator= (const var& value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (int value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (bool value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (double value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (const char* value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (const juce_wchar* value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (const String& value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (DynamicObject* value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (MethodFunction value_) { var newValue (value_); swapWith (newValue); return *this; } - -var::operator int() const -{ - switch (type) - { - case voidType: break; - case intType: return value.intValue; - case boolType: return value.boolValue ? 1 : 0; - case doubleType: return static_cast (value.doubleValue); - case stringType: return value.stringValue->getIntValue(); - case objectType: break; - default: jassertfalse; break; - } - - return 0; -} - -var::operator bool() const -{ - switch (type) - { - case voidType: break; - case intType: return value.intValue != 0; - case boolType: return value.boolValue; - case doubleType: return value.doubleValue != 0; - case stringType: return value.stringValue->getIntValue() != 0 - || value.stringValue->trim().equalsIgnoreCase ("true") - || value.stringValue->trim().equalsIgnoreCase ("yes"); - case objectType: return value.objectValue != 0; - default: jassertfalse; break; - } - - return false; -} - -var::operator float() const -{ - return (float) operator double(); -} - -var::operator double() const -{ - switch (type) - { - case voidType: break; - case intType: return value.intValue; - case boolType: return value.boolValue ? 1.0 : 0.0; - case doubleType: return value.doubleValue; - case stringType: return value.stringValue->getDoubleValue(); - case objectType: break; - default: jassertfalse; break; - } - - return 0.0; -} - -const String var::toString() const -{ - switch (type) - { - case voidType: return String::empty; - case intType: return String (value.intValue); - case boolType: return String::charToString (value.boolValue ? '1' : '0'); - case doubleType: return String (value.doubleValue); - case stringType: return *(value.stringValue); - case objectType: return "Object 0x" + String::toHexString ((int) (pointer_sized_int) value.objectValue); - case methodType: return "Method"; - default: jassertfalse; break; - } - - return String::empty; -} - -var::operator const String() const -{ - return toString(); -} - -DynamicObject* var::getObject() const -{ - return type == objectType ? value.objectValue : 0; -} +var& var::operator= (const var& newValue) { type->cleanUp (value); type = newValue.type; type->createCopy (value, newValue.value); return *this; } +var& var::operator= (int newValue) { var v (newValue); swapWith (v); return *this; } +var& var::operator= (bool newValue) { var v (newValue); swapWith (v); return *this; } +var& var::operator= (double newValue) { var v (newValue); swapWith (v); return *this; } +var& var::operator= (const char* newValue) { var v (newValue); swapWith (v); return *this; } +var& var::operator= (const juce_wchar* newValue) { var v (newValue); swapWith (v); return *this; } +var& var::operator= (const String& newValue) { var v (newValue); swapWith (v); return *this; } +var& var::operator= (DynamicObject* newValue) { var v (newValue); swapWith (v); return *this; } +var& var::operator= (MethodFunction newValue) { var v (newValue); swapWith (v); return *this; } bool var::equals (const var& other) const throw() { - switch (type) - { - case voidType: return other.isVoid(); - case intType: return value.intValue == static_cast (other); - case boolType: return value.boolValue == static_cast (other); - case doubleType: return value.doubleValue == static_cast (other); - case stringType: return (*(value.stringValue)) == other.toString(); - case objectType: return value.objectValue == other.getObject(); - case methodType: return value.methodValue == other.value.methodValue && other.isMethod(); - default: jassertfalse; break; - } - - return false; + return type->equals (value, other.value, *other.type); } bool operator== (const var& v1, const var& v2) throw() { return v1.equals (v2); } @@ -4139,26 +4240,7 @@ bool operator!= (const var& v1, const String& v2) throw() { return v1.toString void var::writeToStream (OutputStream& output) const { - switch (type) - { - case voidType: output.writeCompressedInt (0); break; - case intType: output.writeCompressedInt (5); output.writeByte (1); output.writeInt (value.intValue); break; - case boolType: output.writeCompressedInt (1); output.writeByte (value.boolValue ? 2 : 3); break; - case doubleType: output.writeCompressedInt (9); output.writeByte (4); output.writeDouble (value.doubleValue); break; - case stringType: - { - const int len = value.stringValue->getNumBytesAsUTF8() + 1; - output.writeCompressedInt (len + 1); - output.writeByte (5); - HeapBlock temp (len); - value.stringValue->copyToUTF8 (temp, len); - output.write (temp, len); - break; - } - case objectType: - case methodType: output.writeCompressedInt (0); jassertfalse; break; // Can't write an object to a stream! - default: jassertfalse; break; // Is this a corrupted object? - } + type->writeToStream (value, output); } const var var::readFromStream (InputStream& input) @@ -4189,18 +4271,14 @@ const var var::readFromStream (InputStream& input) const var var::operator[] (const Identifier& propertyName) const { - if (type == objectType && value.objectValue != 0) - return value.objectValue->getProperty (propertyName); - - return var::null; + DynamicObject* const o = getObject(); + return o != 0 ? o->getProperty (propertyName) : var::null; } const var var::invoke (const Identifier& method, const var* arguments, int numArguments) const { - if (type == objectType && value.objectValue != 0) - return value.objectValue->invokeMethod (method, arguments, numArguments); - - return var::null; + DynamicObject* const o = getObject(); + return o != 0 ? o->invokeMethod (method, arguments, numArguments) : var::null; } const var var::invoke (const var& targetObject, const var* arguments, int numArguments) const @@ -23783,6 +23861,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf bufferPos %= bufferSize; int endOfBufferPos = bufferPos + sampsInBuffer; + const int channelsToProcess = jmin (numChannels, info.buffer->getNumChannels()); while (sampsNeeded > sampsInBuffer) { @@ -23802,7 +23881,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf { // for down-sampling, pre-apply the filter.. - for (int i = jmin (numChannels, info.buffer->getNumChannels()); --i >= 0;) + for (int i = channelsToProcess; --i >= 0;) applyFilter (buffer.getSampleData (i, endOfBufferPos), numToDo, filterStates[i]); } @@ -23810,7 +23889,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf endOfBufferPos += numToDo; } - for (int channel = 0; channel < numChannels; ++channel) + for (int channel = 0; channel < channelsToProcess; ++channel) { destBuffers[channel] = info.buffer->getSampleData (channel, info.startSample); srcBuffers[channel] = buffer.getSampleData (channel, 0); @@ -23822,7 +23901,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf const float alpha = (float) subSampleOffset; const float invAlpha = 1.0f - alpha; - for (int channel = 0; channel < numChannels; ++channel) + for (int channel = 0; channel < channelsToProcess; ++channel) *destBuffers[channel]++ = srcBuffers[channel][bufferPos] * invAlpha + srcBuffers[channel][nextPos] * alpha; subSampleOffset += ratio; @@ -23844,13 +23923,13 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf if (ratio < 0.9999) { // for up-sampling, apply the filter after transposing.. - for (int i = jmin (numChannels, info.buffer->getNumChannels()); --i >= 0;) + for (int i = channelsToProcess; --i >= 0;) applyFilter (info.buffer->getSampleData (i, info.startSample), info.numSamples, filterStates[i]); } else if (ratio <= 1.0001) { // if the filter's not currently being applied, keep it stoked with the last couple of samples to avoid discontinuities - for (int i = jmin (numChannels, info.buffer->getNumChannels()); --i >= 0;) + for (int i = channelsToProcess; --i >= 0;) { const float* const endOfBuffer = info.buffer->getSampleData (i, info.startSample + info.numSamples - 1); FilterState& fs = filterStates[i]; @@ -85751,7 +85830,7 @@ void DrawablePath::ValueTreeWrapper::Element::convertToPathBreak (UndoManager* u } } -static const Point findCubicSubdivisionPoint (double proportion, const Point points[4]) +static const Point findCubicSubdivisionPoint (float proportion, const Point points[4]) { const Point mid1 (points[0] + (points[1] - points[0]) * proportion), mid2 (points[1] + (points[2] - points[1]) * proportion), @@ -85763,7 +85842,7 @@ static const Point findCubicSubdivisionPoint (double proportion, const Po return newCp1 + (newCp2 - newCp1) * proportion; } -static const Point findQuadraticSubdivisionPoint (double proportion, const Point points[3]) +static const Point findQuadraticSubdivisionPoint (float proportion, const Point points[3]) { const Point mid1 (points[0] + (points[1] - points[0]) * proportion), mid2 (points[1] + (points[2] - points[1]) * proportion); @@ -85771,10 +85850,10 @@ static const Point findQuadraticSubdivisionPoint (double proportion, cons return mid1 + (mid2 - mid1) * proportion; } -double DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const Point& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const +float DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const Point& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const { const Identifier i (state.getType()); - double bestProp = 0; + float bestProp = 0; if (i == cubicToElement) { @@ -85786,7 +85865,7 @@ double DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const P for (int i = 110; --i >= 0;) { - double prop = i > 10 ? ((i - 10) / 100.0) : (bestProp + ((i - 5) / 1000.0)); + float prop = i > 10 ? ((i - 10) / 100.0f) : (bestProp + ((i - 5) / 1000.0f)); const Point centre (findCubicSubdivisionPoint (prop, points)); const float distance = centre.getDistanceFrom (targetPoint); @@ -85806,8 +85885,8 @@ double DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const P for (int i = 110; --i >= 0;) { - double prop = i > 10 ? ((i - 10) / 100.0) : (bestProp + ((i - 5) / 1000.0)); - const Point centre (findQuadraticSubdivisionPoint (prop, points)); + float prop = i > 10 ? ((i - 10) / 100.0f) : (bestProp + ((i - 5) / 1000.0f)); + const Point centre (findQuadraticSubdivisionPoint ((float) prop, points)); const float distance = centre.getDistanceFrom (targetPoint); if (distance < bestDistance) @@ -85834,7 +85913,7 @@ ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (const Point points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder), rp4.resolve (nameFinder) }; @@ -85862,7 +85941,7 @@ ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (const Point points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder) }; @@ -259600,8 +259679,6 @@ public: callback (0), inputId (inputId_), outputId (outputId_), - outputDevice (0), - inputDevice (0), numCallbacks (0), inputChannelBuffer (1, 1), outputChannelBuffer (1, 1) @@ -259666,7 +259743,7 @@ public: if (outputDevice->error.isNotEmpty()) { error = outputDevice->error; - deleteAndZero (outputDevice); + outputDevice = 0; return; } @@ -259677,7 +259754,7 @@ public: bufferSize)) { error = outputDevice->error; - deleteAndZero (outputDevice); + outputDevice = 0; return; } } @@ -259689,7 +259766,7 @@ public: if (inputDevice->error.isNotEmpty()) { error = inputDevice->error; - deleteAndZero (inputDevice); + inputDevice = 0; return; } @@ -259700,7 +259777,7 @@ public: bufferSize)) { error = inputDevice->error; - deleteAndZero (inputDevice); + inputDevice = 0; return; } } @@ -259742,8 +259819,8 @@ public: { stopThread (6000); - deleteAndZero (inputDevice); - deleteAndZero (outputDevice); + inputDevice = 0; + outputDevice = 0; inputChannelBuffer.setSize (1, 1); outputChannelBuffer.setSize (1, 1); @@ -259835,8 +259912,7 @@ public: private: const String inputId, outputId; - ALSADevice* outputDevice; - ALSADevice* inputDevice; + ScopedPointer outputDevice, inputDevice; int numCallbacks; CriticalSection callbackLock; @@ -259891,7 +259967,7 @@ public: outputId (outputId_), isOpen_ (false), isStarted (false), - internal (new ALSAThread (inputId_, outputId_)) + internal (inputId_, outputId_) { } @@ -259901,22 +259977,22 @@ public: const StringArray getOutputChannelNames() { - return internal->channelNamesOut; + return internal.channelNamesOut; } const StringArray getInputChannelNames() { - return internal->channelNamesIn; + return internal.channelNamesIn; } int getNumSampleRates() { - return internal->sampleRates.size(); + return internal.sampleRates.size(); } double getSampleRate (int index) { - return internal->sampleRates [index]; + return internal.sampleRates [index]; } int getNumBufferSizesAvailable() @@ -259963,17 +260039,17 @@ public: } } - internal->open (inputChannels, outputChannels, - sampleRate, bufferSizeSamples); + internal.open (inputChannels, outputChannels, + sampleRate, bufferSizeSamples); - isOpen_ = internal->error.isEmpty(); - return internal->error; + isOpen_ = internal.error.isEmpty(); + return internal.error; } void close() { stop(); - internal->close(); + internal.close(); isOpen_ = false; } @@ -259984,27 +260060,27 @@ public: int getCurrentBufferSizeSamples() { - return internal->bufferSize; + return internal.bufferSize; } double getCurrentSampleRate() { - return internal->sampleRate; + return internal.sampleRate; } int getCurrentBitDepth() { - return internal->getBitDepth(); + return internal.getBitDepth(); } const BigInteger getActiveOutputChannels() const { - return internal->currentOutputChans; + return internal.currentOutputChans; } const BigInteger getActiveInputChannels() const { - return internal->currentInputChans; + return internal.currentInputChans; } int getOutputLatencyInSamples() @@ -260022,17 +260098,17 @@ public: if (! isOpen_) callback = 0; - internal->setCallback (callback); - if (callback != 0) callback->audioDeviceAboutToStart (this); + internal.setCallback (callback); + isStarted = (callback != 0); } void stop() { - AudioIODeviceCallback* const oldCallback = internal->callback; + AudioIODeviceCallback* const oldCallback = internal.callback; start (0); @@ -260042,19 +260118,19 @@ public: bool isPlaying() { - return isStarted && internal->error.isEmpty(); + return isStarted && internal.error.isEmpty(); } const String getLastError() { - return internal->error; + return internal.error; } String inputId, outputId; private: bool isOpen_, isStarted; - ScopedPointer internal; + ALSAThread internal; }; class ALSAAudioIODeviceType : public AudioIODeviceType diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 1d8358b031..6d7d60f5a6 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -64,7 +64,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 52 -#define JUCE_BUILDNUMBER 31 +#define JUCE_BUILDNUMBER 32 /** Current Juce version number. @@ -5544,13 +5544,13 @@ public: const String toString() const; DynamicObject* getObject() const; - bool isVoid() const throw() { return type == voidType; } - bool isInt() const throw() { return type == intType; } - bool isBool() const throw() { return type == boolType; } - bool isDouble() const throw() { return type == doubleType; } - bool isString() const throw() { return type == stringType; } - bool isObject() const throw() { return type == objectType; } - bool isMethod() const throw() { return type == methodType; } + bool isVoid() const throw(); + bool isInt() const throw(); + bool isBool() const throw(); + bool isDouble() const throw(); + bool isString() const throw(); + bool isObject() const throw(); + bool isMethod() const throw(); /** Writes a binary representation of this value to a stream. The data can be read back later using readFromStream(). @@ -5591,16 +5591,24 @@ public: bool equals (const var& other) const throw(); private: - enum Type - { - voidType = 0, - intType, - boolType, - doubleType, - stringType, - objectType, - methodType - }; + class VariantType; + friend class VariantType; + class VariantType_Void; + friend class VariantType_Void; + class VariantType_Int; + friend class VariantType_Int; + class VariantType_Double; + friend class VariantType_Double; + class VariantType_Float; + friend class VariantType_Float; + class VariantType_Bool; + friend class VariantType_Bool; + class VariantType_String; + friend class VariantType_String; + class VariantType_Object; + friend class VariantType_Object; + class VariantType_Method; + friend class VariantType_Method; union ValueUnion { @@ -5612,7 +5620,7 @@ private: MethodFunction methodValue; }; - Type type; + const VariantType* type; ValueUnion value; }; @@ -59416,7 +59424,7 @@ public: void convertToPathBreak (UndoManager* undoManager); ValueTree insertPoint (const Point& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder, UndoManager* undoManager); void removePoint (UndoManager* undoManager); - double findProportionAlongLine (const Point& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const; + float findProportionAlongLine (const Point& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const; static const Identifier mode, startSubPathElement, closeSubPathElement, lineToElement, quadraticToElement, cubicToElement; diff --git a/src/audio/audio_sources/juce_ResamplingAudioSource.cpp b/src/audio/audio_sources/juce_ResamplingAudioSource.cpp index d5431e8884..cea0639495 100644 --- a/src/audio/audio_sources/juce_ResamplingAudioSource.cpp +++ b/src/audio/audio_sources/juce_ResamplingAudioSource.cpp @@ -110,6 +110,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf bufferPos %= bufferSize; int endOfBufferPos = bufferPos + sampsInBuffer; + const int channelsToProcess = jmin (numChannels, info.buffer->getNumChannels()); while (sampsNeeded > sampsInBuffer) { @@ -129,7 +130,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf { // for down-sampling, pre-apply the filter.. - for (int i = jmin (numChannels, info.buffer->getNumChannels()); --i >= 0;) + for (int i = channelsToProcess; --i >= 0;) applyFilter (buffer.getSampleData (i, endOfBufferPos), numToDo, filterStates[i]); } @@ -137,7 +138,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf endOfBufferPos += numToDo; } - for (int channel = 0; channel < numChannels; ++channel) + for (int channel = 0; channel < channelsToProcess; ++channel) { destBuffers[channel] = info.buffer->getSampleData (channel, info.startSample); srcBuffers[channel] = buffer.getSampleData (channel, 0); @@ -149,7 +150,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf const float alpha = (float) subSampleOffset; const float invAlpha = 1.0f - alpha; - for (int channel = 0; channel < numChannels; ++channel) + for (int channel = 0; channel < channelsToProcess; ++channel) *destBuffers[channel]++ = srcBuffers[channel][bufferPos] * invAlpha + srcBuffers[channel][nextPos] * alpha; subSampleOffset += ratio; @@ -171,13 +172,13 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf if (ratio < 0.9999) { // for up-sampling, apply the filter after transposing.. - for (int i = jmin (numChannels, info.buffer->getNumChannels()); --i >= 0;) + for (int i = channelsToProcess; --i >= 0;) applyFilter (info.buffer->getSampleData (i, info.startSample), info.numSamples, filterStates[i]); } else if (ratio <= 1.0001) { // if the filter's not currently being applied, keep it stoked with the last couple of samples to avoid discontinuities - for (int i = jmin (numChannels, info.buffer->getNumChannels()); --i >= 0;) + for (int i = channelsToProcess; --i >= 0;) { const float* const endOfBuffer = info.buffer->getSampleData (i, info.startSample + info.numSamples - 1); FilterState& fs = filterStates[i]; diff --git a/src/containers/juce_Variant.cpp b/src/containers/juce_Variant.cpp index b12258a5d9..cd9348ded1 100644 --- a/src/containers/juce_Variant.cpp +++ b/src/containers/juce_Variant.cpp @@ -31,72 +31,261 @@ BEGIN_JUCE_NAMESPACE #include "juce_DynamicObject.h" +//============================================================================== +class var::VariantType +{ +public: + VariantType() {} + virtual ~VariantType() {} + + virtual int toInt (const ValueUnion&) const { return 0; } + virtual double toDouble (const ValueUnion&) const { return 0; } + virtual float toFloat (const ValueUnion&) const { return 0; } + virtual const String toString (const ValueUnion&) const { return String::empty; } + virtual bool toBool (const ValueUnion&) const { return false; } + virtual DynamicObject* toObject (const ValueUnion&) const { return 0; } + + virtual bool isVoid() const throw() { return false; } + virtual bool isInt() const throw() { return false; } + virtual bool isBool() const throw() { return false; } + virtual bool isDouble() const throw() { return false; } + virtual bool isString() const throw() { return false; } + virtual bool isObject() const throw() { return false; } + virtual bool isMethod() const throw() { return false; } + + virtual void cleanUp (ValueUnion&) const throw() {} + virtual void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest = source; } + virtual bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() = 0; + virtual void writeToStream (const ValueUnion& data, OutputStream& output) const = 0; +}; + +//============================================================================== +class var::VariantType_Void : public var::VariantType +{ +public: + static const VariantType_Void* getInstance() { static const VariantType_Void i; return &i; } + + bool isVoid() const throw() { return true; } + bool equals (const ValueUnion&, const ValueUnion&, const VariantType& otherType) const throw() { return otherType.isVoid(); } + void writeToStream (const ValueUnion&, OutputStream& output) const { output.writeCompressedInt (0); } +}; + +//============================================================================== +class var::VariantType_Int : public var::VariantType +{ +public: + static const VariantType_Int* getInstance() { static const VariantType_Int i; return &i; } + + int toInt (const ValueUnion& data) const { return data.intValue; }; + double toDouble (const ValueUnion& data) const { return (double) data.intValue; } + float toFloat (const ValueUnion& data) const { return (float) data.intValue; } + const String toString (const ValueUnion& data) const { return String (data.intValue); } + bool toBool (const ValueUnion& data) const { return data.intValue != 0; } + + bool isInt() const throw() { return true; } + + bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() + { + return otherType.toInt (otherData) == data.intValue; + } + + void writeToStream (const ValueUnion& data, OutputStream& output) const + { + output.writeCompressedInt (5); + output.writeByte (1); + output.writeInt (data.intValue); + } +}; + +//============================================================================== +class var::VariantType_Double : public var::VariantType +{ +public: + static const VariantType_Double* getInstance() { static const VariantType_Double i; return &i; } + + int toInt (const ValueUnion& data) const { return (int) data.doubleValue; }; + double toDouble (const ValueUnion& data) const { return data.doubleValue; } + float toFloat (const ValueUnion& data) const { return (float) data.doubleValue; } + const String toString (const ValueUnion& data) const { return String (data.doubleValue); } + bool toBool (const ValueUnion& data) const { return data.doubleValue != 0; } + + bool isDouble() const throw() { return true; } + + bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() + { + return otherType.toDouble (otherData) == data.doubleValue; + } + + void writeToStream (const ValueUnion& data, OutputStream& output) const + { + output.writeCompressedInt (9); + output.writeByte (4); + output.writeDouble (data.doubleValue); + } +}; + +//============================================================================== +class var::VariantType_Bool : public var::VariantType +{ +public: + static const VariantType_Bool* getInstance() { static const VariantType_Bool i; return &i; } + + int toInt (const ValueUnion& data) const { return data.boolValue ? 1 : 0; }; + double toDouble (const ValueUnion& data) const { return data.boolValue ? 1.0 : 0.0; } + float toFloat (const ValueUnion& data) const { return data.boolValue ? 1.0f : 0.0f; } + const String toString (const ValueUnion& data) const { return String::charToString (data.boolValue ? '1' : '0'); } + bool toBool (const ValueUnion& data) const { return data.boolValue; } + + bool isBool() const throw() { return true; } + + bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() + { + return otherType.toBool (otherData) == data.boolValue; + } + + void writeToStream (const ValueUnion& data, OutputStream& output) const + { + output.writeCompressedInt (1); + output.writeByte (data.boolValue ? 2 : 3); + } +}; + +//============================================================================== +class var::VariantType_String : public var::VariantType +{ +public: + static const VariantType_String* getInstance() { static const VariantType_String i; return &i; } + + void cleanUp (ValueUnion& data) const throw() { delete data.stringValue; } + void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.stringValue = new String (*source.stringValue); } + + int toInt (const ValueUnion& data) const { return data.stringValue->getIntValue(); }; + double toDouble (const ValueUnion& data) const { return data.stringValue->getDoubleValue(); } + float toFloat (const ValueUnion& data) const { return data.stringValue->getFloatValue(); } + const String toString (const ValueUnion& data) const { return *data.stringValue; } + bool toBool (const ValueUnion& data) const { return data.stringValue->getIntValue() != 0 + || data.stringValue->trim().equalsIgnoreCase ("true") + || data.stringValue->trim().equalsIgnoreCase ("yes"); } + + bool isString() const throw() { return true; } + + bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() + { + return otherType.toString (otherData) == *data.stringValue; + } + + void writeToStream (const ValueUnion& data, OutputStream& output) const + { + const int len = data.stringValue->getNumBytesAsUTF8() + 1; + output.writeCompressedInt (len + 1); + output.writeByte (5); + HeapBlock temp (len); + data.stringValue->copyToUTF8 (temp, len); + output.write (temp, len); + } +}; + +//============================================================================== +class var::VariantType_Object : public var::VariantType +{ +public: + static const VariantType_Object* getInstance() { static const VariantType_Object i; return &i; } + + void cleanUp (ValueUnion& data) const throw() { if (data.objectValue != 0) data.objectValue->decReferenceCount(); } + void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest.objectValue = source.objectValue; if (dest.objectValue != 0) dest.objectValue->incReferenceCount(); } + + const String toString (const ValueUnion& data) const { return "Object 0x" + String::toHexString ((int) (pointer_sized_int) data.objectValue); } + bool toBool (const ValueUnion& data) const { return data.objectValue != 0; } + DynamicObject* toObject (const ValueUnion& data) const { return data.objectValue; } + + bool isObject() const throw() { return true; } + + bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() + { + return otherType.toObject (otherData) == data.objectValue; + } + + void writeToStream (const ValueUnion&, OutputStream& output) const + { + jassertfalse; // Can't write an object to a stream! + output.writeCompressedInt (0); + } +}; + +//============================================================================== +class var::VariantType_Method : public var::VariantType +{ +public: + static const VariantType_Method* getInstance() { static const VariantType_Method i; return &i; } + + const String toString (const ValueUnion&) const { return "Method"; } + bool toBool (const ValueUnion& data) const { return data.methodValue != 0; } + + bool isMethod() const throw() { return true; } + + bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const throw() + { + return otherType.isMethod() && otherData.methodValue == data.methodValue; + } + + void writeToStream (const ValueUnion&, OutputStream& output) const + { + jassertfalse; // Can't write a method to a stream! + output.writeCompressedInt (0); + } +}; + + //============================================================================== var::var() throw() - : type (voidType) + : type (VariantType_Void::getInstance()) { - value.doubleValue = 0; } var::~var() throw() { - if (type == stringType) - delete value.stringValue; - else if (type == objectType && value.objectValue != 0) - value.objectValue->decReferenceCount(); + type->cleanUp (value); } const var var::null; //============================================================================== -var::var (const var& valueToCopy) - : type (valueToCopy.type), - value (valueToCopy.value) -{ - if (type == stringType) - value.stringValue = new String (*(value.stringValue)); - else if (type == objectType && value.objectValue != 0) - value.objectValue->incReferenceCount(); +var::var (const var& valueToCopy) : type (valueToCopy.type) +{ + type->createCopy (value, valueToCopy.value); } -var::var (const int value_) throw() - : type (intType) +var::var (const int value_) throw() : type (VariantType_Int::getInstance()) { value.intValue = value_; } -var::var (const bool value_) throw() - : type (boolType) +var::var (const bool value_) throw() : type (VariantType_Bool::getInstance()) { value.boolValue = value_; } -var::var (const double value_) throw() - : type (doubleType) +var::var (const double value_) throw() : type (VariantType_Double::getInstance()) { value.doubleValue = value_; } -var::var (const String& value_) - : type (stringType) +var::var (const String& value_) : type (VariantType_String::getInstance()) { value.stringValue = new String (value_); } -var::var (const char* const value_) - : type (stringType) +var::var (const char* const value_) : type (VariantType_String::getInstance()) { value.stringValue = new String (value_); } -var::var (const juce_wchar* const value_) - : type (stringType) +var::var (const juce_wchar* const value_) : type (VariantType_String::getInstance()) { value.stringValue = new String (value_); } -var::var (DynamicObject* const object) - : type (objectType) +var::var (DynamicObject* const object) : type (VariantType_Object::getInstance()) { value.objectValue = object; @@ -104,12 +293,28 @@ var::var (DynamicObject* const object) object->incReferenceCount(); } -var::var (MethodFunction method_) throw() - : type (methodType) +var::var (MethodFunction method_) throw() : type (VariantType_Method::getInstance()) { value.methodValue = method_; } +//============================================================================== +bool var::isVoid() const throw() { return type->isVoid(); } +bool var::isInt() const throw() { return type->isInt(); } +bool var::isBool() const throw() { return type->isBool(); } +bool var::isDouble() const throw() { return type->isDouble(); } +bool var::isString() const throw() { return type->isString(); } +bool var::isObject() const throw() { return type->isObject(); } +bool var::isMethod() const throw() { return type->isMethod(); } + +var::operator int() const { return type->toInt (value); } +var::operator bool() const { return type->toBool (value); } +var::operator float() const { return type->toFloat (value); } +var::operator double() const { return type->toDouble (value); } +const String var::toString() const { return type->toString (value); } +var::operator const String() const { return type->toString (value); } +DynamicObject* var::getObject() const { return type->toObject (value); } + //============================================================================== void var::swapWith (var& other) throw() { @@ -117,115 +322,20 @@ void var::swapWith (var& other) throw() swapVariables (value, other.value); } -var& var::operator= (const var& value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (int value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (bool value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (double value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (const char* value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (const juce_wchar* value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (const String& value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (DynamicObject* value_) { var newValue (value_); swapWith (newValue); return *this; } -var& var::operator= (MethodFunction value_) { var newValue (value_); swapWith (newValue); return *this; } - -//============================================================================== -var::operator int() const -{ - switch (type) - { - case voidType: break; - case intType: return value.intValue; - case boolType: return value.boolValue ? 1 : 0; - case doubleType: return static_cast (value.doubleValue); - case stringType: return value.stringValue->getIntValue(); - case objectType: break; - default: jassertfalse; break; - } - - return 0; -} - -var::operator bool() const -{ - switch (type) - { - case voidType: break; - case intType: return value.intValue != 0; - case boolType: return value.boolValue; - case doubleType: return value.doubleValue != 0; - case stringType: return value.stringValue->getIntValue() != 0 - || value.stringValue->trim().equalsIgnoreCase ("true") - || value.stringValue->trim().equalsIgnoreCase ("yes"); - case objectType: return value.objectValue != 0; - default: jassertfalse; break; - } - - return false; -} - -var::operator float() const -{ - return (float) operator double(); -} - -var::operator double() const -{ - switch (type) - { - case voidType: break; - case intType: return value.intValue; - case boolType: return value.boolValue ? 1.0 : 0.0; - case doubleType: return value.doubleValue; - case stringType: return value.stringValue->getDoubleValue(); - case objectType: break; - default: jassertfalse; break; - } - - return 0.0; -} - -const String var::toString() const -{ - switch (type) - { - case voidType: return String::empty; - case intType: return String (value.intValue); - case boolType: return String::charToString (value.boolValue ? '1' : '0'); - case doubleType: return String (value.doubleValue); - case stringType: return *(value.stringValue); - case objectType: return "Object 0x" + String::toHexString ((int) (pointer_sized_int) value.objectValue); - case methodType: return "Method"; - default: jassertfalse; break; - } - - return String::empty; -} - -var::operator const String() const -{ - return toString(); -} - -DynamicObject* var::getObject() const -{ - return type == objectType ? value.objectValue : 0; -} +var& var::operator= (const var& newValue) { type->cleanUp (value); type = newValue.type; type->createCopy (value, newValue.value); return *this; } +var& var::operator= (int newValue) { var v (newValue); swapWith (v); return *this; } +var& var::operator= (bool newValue) { var v (newValue); swapWith (v); return *this; } +var& var::operator= (double newValue) { var v (newValue); swapWith (v); return *this; } +var& var::operator= (const char* newValue) { var v (newValue); swapWith (v); return *this; } +var& var::operator= (const juce_wchar* newValue) { var v (newValue); swapWith (v); return *this; } +var& var::operator= (const String& newValue) { var v (newValue); swapWith (v); return *this; } +var& var::operator= (DynamicObject* newValue) { var v (newValue); swapWith (v); return *this; } +var& var::operator= (MethodFunction newValue) { var v (newValue); swapWith (v); return *this; } //============================================================================== bool var::equals (const var& other) const throw() { - switch (type) - { - case voidType: return other.isVoid(); - case intType: return value.intValue == static_cast (other); - case boolType: return value.boolValue == static_cast (other); - case doubleType: return value.doubleValue == static_cast (other); - case stringType: return (*(value.stringValue)) == other.toString(); - case objectType: return value.objectValue == other.getObject(); - case methodType: return value.methodValue == other.value.methodValue && other.isMethod(); - default: jassertfalse; break; - } - - return false; + return type->equals (value, other.value, *other.type); } bool operator== (const var& v1, const var& v2) throw() { return v1.equals (v2); } @@ -236,26 +346,7 @@ bool operator!= (const var& v1, const String& v2) throw() { return v1.toString //============================================================================== void var::writeToStream (OutputStream& output) const { - switch (type) - { - case voidType: output.writeCompressedInt (0); break; - case intType: output.writeCompressedInt (5); output.writeByte (1); output.writeInt (value.intValue); break; - case boolType: output.writeCompressedInt (1); output.writeByte (value.boolValue ? 2 : 3); break; - case doubleType: output.writeCompressedInt (9); output.writeByte (4); output.writeDouble (value.doubleValue); break; - case stringType: - { - const int len = value.stringValue->getNumBytesAsUTF8() + 1; - output.writeCompressedInt (len + 1); - output.writeByte (5); - HeapBlock temp (len); - value.stringValue->copyToUTF8 (temp, len); - output.write (temp, len); - break; - } - case objectType: - case methodType: output.writeCompressedInt (0); jassertfalse; break; // Can't write an object to a stream! - default: jassertfalse; break; // Is this a corrupted object? - } + type->writeToStream (value, output); } const var var::readFromStream (InputStream& input) @@ -286,18 +377,14 @@ const var var::readFromStream (InputStream& input) const var var::operator[] (const Identifier& propertyName) const { - if (type == objectType && value.objectValue != 0) - return value.objectValue->getProperty (propertyName); - - return var::null; + DynamicObject* const o = getObject(); + return o != 0 ? o->getProperty (propertyName) : var::null; } const var var::invoke (const Identifier& method, const var* arguments, int numArguments) const { - if (type == objectType && value.objectValue != 0) - return value.objectValue->invokeMethod (method, arguments, numArguments); - - return var::null; + DynamicObject* const o = getObject(); + return o != 0 ? o->invokeMethod (method, arguments, numArguments) : var::null; } const var var::invoke (const var& targetObject, const var* arguments, int numArguments) const diff --git a/src/containers/juce_Variant.h b/src/containers/juce_Variant.h index 17b6b8c32a..3448cd4391 100644 --- a/src/containers/juce_Variant.h +++ b/src/containers/juce_Variant.h @@ -90,13 +90,13 @@ public: const String toString() const; DynamicObject* getObject() const; - bool isVoid() const throw() { return type == voidType; } - bool isInt() const throw() { return type == intType; } - bool isBool() const throw() { return type == boolType; } - bool isDouble() const throw() { return type == doubleType; } - bool isString() const throw() { return type == stringType; } - bool isObject() const throw() { return type == objectType; } - bool isMethod() const throw() { return type == methodType; } + bool isVoid() const throw(); + bool isInt() const throw(); + bool isBool() const throw(); + bool isDouble() const throw(); + bool isString() const throw(); + bool isObject() const throw(); + bool isMethod() const throw(); //============================================================================== /** Writes a binary representation of this value to a stream. @@ -142,16 +142,24 @@ public: bool equals (const var& other) const throw(); private: - enum Type - { - voidType = 0, - intType, - boolType, - doubleType, - stringType, - objectType, - methodType - }; + class VariantType; + friend class VariantType; + class VariantType_Void; + friend class VariantType_Void; + class VariantType_Int; + friend class VariantType_Int; + class VariantType_Double; + friend class VariantType_Double; + class VariantType_Float; + friend class VariantType_Float; + class VariantType_Bool; + friend class VariantType_Bool; + class VariantType_String; + friend class VariantType_String; + class VariantType_Object; + friend class VariantType_Object; + class VariantType_Method; + friend class VariantType_Method; union ValueUnion { @@ -163,7 +171,7 @@ private: MethodFunction methodValue; }; - Type type; + const VariantType* type; ValueUnion value; }; diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 5a375d4a81..c6a8b2d9e3 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 52 -#define JUCE_BUILDNUMBER 31 +#define JUCE_BUILDNUMBER 32 /** Current Juce version number. diff --git a/src/gui/components/controls/juce_TableListBox.h b/src/gui/components/controls/juce_TableListBox.h index c3d56fdc77..e33a8e1559 100644 --- a/src/gui/components/controls/juce_TableListBox.h +++ b/src/gui/components/controls/juce_TableListBox.h @@ -273,7 +273,7 @@ public: bool relativeToComponentTopLeft) const; /** Returns the component that currently represents a given cell. - If the component for this cell is off-screen or if the position is out-of-range, + If the component for this cell is off-screen or if the position is out-of-range, this may return 0. @see getCellPosition */ diff --git a/src/gui/graphics/drawables/juce_DrawablePath.cpp b/src/gui/graphics/drawables/juce_DrawablePath.cpp index dd7cb01a95..5ee175cf45 100644 --- a/src/gui/graphics/drawables/juce_DrawablePath.cpp +++ b/src/gui/graphics/drawables/juce_DrawablePath.cpp @@ -453,7 +453,7 @@ void DrawablePath::ValueTreeWrapper::Element::convertToPathBreak (UndoManager* u } } -static const Point findCubicSubdivisionPoint (double proportion, const Point points[4]) +static const Point findCubicSubdivisionPoint (float proportion, const Point points[4]) { const Point mid1 (points[0] + (points[1] - points[0]) * proportion), mid2 (points[1] + (points[2] - points[1]) * proportion), @@ -465,7 +465,7 @@ static const Point findCubicSubdivisionPoint (double proportion, const Po return newCp1 + (newCp2 - newCp1) * proportion; } -static const Point findQuadraticSubdivisionPoint (double proportion, const Point points[3]) +static const Point findQuadraticSubdivisionPoint (float proportion, const Point points[3]) { const Point mid1 (points[0] + (points[1] - points[0]) * proportion), mid2 (points[1] + (points[2] - points[1]) * proportion); @@ -473,10 +473,10 @@ static const Point findQuadraticSubdivisionPoint (double proportion, cons return mid1 + (mid2 - mid1) * proportion; } -double DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const Point& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const +float DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const Point& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const { const Identifier i (state.getType()); - double bestProp = 0; + float bestProp = 0; if (i == cubicToElement) { @@ -488,7 +488,7 @@ double DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const P for (int i = 110; --i >= 0;) { - double prop = i > 10 ? ((i - 10) / 100.0) : (bestProp + ((i - 5) / 1000.0)); + float prop = i > 10 ? ((i - 10) / 100.0f) : (bestProp + ((i - 5) / 1000.0f)); const Point centre (findCubicSubdivisionPoint (prop, points)); const float distance = centre.getDistanceFrom (targetPoint); @@ -508,8 +508,8 @@ double DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const P for (int i = 110; --i >= 0;) { - double prop = i > 10 ? ((i - 10) / 100.0) : (bestProp + ((i - 5) / 1000.0)); - const Point centre (findQuadraticSubdivisionPoint (prop, points)); + float prop = i > 10 ? ((i - 10) / 100.0f) : (bestProp + ((i - 5) / 1000.0f)); + const Point centre (findQuadraticSubdivisionPoint ((float) prop, points)); const float distance = centre.getDistanceFrom (targetPoint); if (distance < bestDistance) @@ -536,7 +536,7 @@ ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (const Point points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder), rp4.resolve (nameFinder) }; @@ -564,7 +564,7 @@ ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (const Point points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder) }; diff --git a/src/gui/graphics/drawables/juce_DrawablePath.h b/src/gui/graphics/drawables/juce_DrawablePath.h index 861ca0cb17..e6ed14290f 100644 --- a/src/gui/graphics/drawables/juce_DrawablePath.h +++ b/src/gui/graphics/drawables/juce_DrawablePath.h @@ -176,7 +176,7 @@ public: void convertToPathBreak (UndoManager* undoManager); ValueTree insertPoint (const Point& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder, UndoManager* undoManager); void removePoint (UndoManager* undoManager); - double findProportionAlongLine (const Point& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const; + float findProportionAlongLine (const Point& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const; static const Identifier mode, startSubPathElement, closeSubPathElement, lineToElement, quadraticToElement, cubicToElement; diff --git a/src/native/linux/juce_linux_Audio.cpp b/src/native/linux/juce_linux_Audio.cpp index 59b977374e..ac1adeeec6 100644 --- a/src/native/linux/juce_linux_Audio.cpp +++ b/src/native/linux/juce_linux_Audio.cpp @@ -349,8 +349,6 @@ public: callback (0), inputId (inputId_), outputId (outputId_), - outputDevice (0), - inputDevice (0), numCallbacks (0), inputChannelBuffer (1, 1), outputChannelBuffer (1, 1) @@ -415,7 +413,7 @@ public: if (outputDevice->error.isNotEmpty()) { error = outputDevice->error; - deleteAndZero (outputDevice); + outputDevice = 0; return; } @@ -426,7 +424,7 @@ public: bufferSize)) { error = outputDevice->error; - deleteAndZero (outputDevice); + outputDevice = 0; return; } } @@ -438,7 +436,7 @@ public: if (inputDevice->error.isNotEmpty()) { error = inputDevice->error; - deleteAndZero (inputDevice); + inputDevice = 0; return; } @@ -449,7 +447,7 @@ public: bufferSize)) { error = inputDevice->error; - deleteAndZero (inputDevice); + inputDevice = 0; return; } } @@ -491,8 +489,8 @@ public: { stopThread (6000); - deleteAndZero (inputDevice); - deleteAndZero (outputDevice); + inputDevice = 0; + outputDevice = 0; inputChannelBuffer.setSize (1, 1); outputChannelBuffer.setSize (1, 1); @@ -585,8 +583,7 @@ public: private: //============================================================================== const String inputId, outputId; - ALSADevice* outputDevice; - ALSADevice* inputDevice; + ScopedPointer outputDevice, inputDevice; int numCallbacks; CriticalSection callbackLock; @@ -643,7 +640,7 @@ public: outputId (outputId_), isOpen_ (false), isStarted (false), - internal (new ALSAThread (inputId_, outputId_)) + internal (inputId_, outputId_) { } @@ -653,22 +650,22 @@ public: const StringArray getOutputChannelNames() { - return internal->channelNamesOut; + return internal.channelNamesOut; } const StringArray getInputChannelNames() { - return internal->channelNamesIn; + return internal.channelNamesIn; } int getNumSampleRates() { - return internal->sampleRates.size(); + return internal.sampleRates.size(); } double getSampleRate (int index) { - return internal->sampleRates [index]; + return internal.sampleRates [index]; } int getNumBufferSizesAvailable() @@ -715,17 +712,17 @@ public: } } - internal->open (inputChannels, outputChannels, - sampleRate, bufferSizeSamples); + internal.open (inputChannels, outputChannels, + sampleRate, bufferSizeSamples); - isOpen_ = internal->error.isEmpty(); - return internal->error; + isOpen_ = internal.error.isEmpty(); + return internal.error; } void close() { stop(); - internal->close(); + internal.close(); isOpen_ = false; } @@ -736,27 +733,27 @@ public: int getCurrentBufferSizeSamples() { - return internal->bufferSize; + return internal.bufferSize; } double getCurrentSampleRate() { - return internal->sampleRate; + return internal.sampleRate; } int getCurrentBitDepth() { - return internal->getBitDepth(); + return internal.getBitDepth(); } const BigInteger getActiveOutputChannels() const { - return internal->currentOutputChans; + return internal.currentOutputChans; } const BigInteger getActiveInputChannels() const { - return internal->currentInputChans; + return internal.currentInputChans; } int getOutputLatencyInSamples() @@ -774,17 +771,17 @@ public: if (! isOpen_) callback = 0; - internal->setCallback (callback); - if (callback != 0) callback->audioDeviceAboutToStart (this); + internal.setCallback (callback); + isStarted = (callback != 0); } void stop() { - AudioIODeviceCallback* const oldCallback = internal->callback; + AudioIODeviceCallback* const oldCallback = internal.callback; start (0); @@ -794,19 +791,19 @@ public: bool isPlaying() { - return isStarted && internal->error.isEmpty(); + return isStarted && internal.error.isEmpty(); } const String getLastError() { - return internal->error; + return internal.error; } String inputId, outputId; private: bool isOpen_, isStarted; - ScopedPointer internal; + ALSAThread internal; };