| @@ -3940,70 +3940,250 @@ END_JUCE_NAMESPACE | |||||
| /*** Start of inlined file: juce_Variant.cpp ***/ | /*** Start of inlined file: juce_Variant.cpp ***/ | ||||
| BEGIN_JUCE_NAMESPACE | 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<char> 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() | var::var() throw() | ||||
| : type (voidType) | |||||
| : type (VariantType_Void::getInstance()) | |||||
| { | { | ||||
| value.doubleValue = 0; | |||||
| } | } | ||||
| var::~var() throw() | 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; | 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_; | value.intValue = value_; | ||||
| } | } | ||||
| var::var (const bool value_) throw() | |||||
| : type (boolType) | |||||
| var::var (const bool value_) throw() : type (VariantType_Bool::getInstance()) | |||||
| { | { | ||||
| value.boolValue = value_; | value.boolValue = value_; | ||||
| } | } | ||||
| var::var (const double value_) throw() | |||||
| : type (doubleType) | |||||
| var::var (const double value_) throw() : type (VariantType_Double::getInstance()) | |||||
| { | { | ||||
| value.doubleValue = value_; | value.doubleValue = value_; | ||||
| } | } | ||||
| var::var (const String& value_) | |||||
| : type (stringType) | |||||
| var::var (const String& value_) : type (VariantType_String::getInstance()) | |||||
| { | { | ||||
| value.stringValue = new String (value_); | 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_); | 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_); | value.stringValue = new String (value_); | ||||
| } | } | ||||
| var::var (DynamicObject* const object) | |||||
| : type (objectType) | |||||
| var::var (DynamicObject* const object) : type (VariantType_Object::getInstance()) | |||||
| { | { | ||||
| value.objectValue = object; | value.objectValue = object; | ||||
| @@ -4011,125 +4191,46 @@ var::var (DynamicObject* const object) | |||||
| object->incReferenceCount(); | object->incReferenceCount(); | ||||
| } | } | ||||
| var::var (MethodFunction method_) throw() | |||||
| : type (methodType) | |||||
| var::var (MethodFunction method_) throw() : type (VariantType_Method::getInstance()) | |||||
| { | { | ||||
| value.methodValue = method_; | 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() | void var::swapWith (var& other) throw() | ||||
| { | { | ||||
| swapVariables (type, other.type); | swapVariables (type, other.type); | ||||
| swapVariables (value, other.value); | 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 <int> (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() | bool var::equals (const var& other) const throw() | ||||
| { | { | ||||
| switch (type) | |||||
| { | |||||
| case voidType: return other.isVoid(); | |||||
| case intType: return value.intValue == static_cast <int> (other); | |||||
| case boolType: return value.boolValue == static_cast <bool> (other); | |||||
| case doubleType: return value.doubleValue == static_cast <double> (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); } | 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 | 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<char> 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) | const var var::readFromStream (InputStream& input) | ||||
| @@ -4189,18 +4271,14 @@ const var var::readFromStream (InputStream& input) | |||||
| const var var::operator[] (const Identifier& propertyName) const | 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 | 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 | 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; | bufferPos %= bufferSize; | ||||
| int endOfBufferPos = bufferPos + sampsInBuffer; | int endOfBufferPos = bufferPos + sampsInBuffer; | ||||
| const int channelsToProcess = jmin (numChannels, info.buffer->getNumChannels()); | |||||
| while (sampsNeeded > sampsInBuffer) | while (sampsNeeded > sampsInBuffer) | ||||
| { | { | ||||
| @@ -23802,7 +23881,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf | |||||
| { | { | ||||
| // for down-sampling, pre-apply the filter.. | // 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]); | applyFilter (buffer.getSampleData (i, endOfBufferPos), numToDo, filterStates[i]); | ||||
| } | } | ||||
| @@ -23810,7 +23889,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf | |||||
| endOfBufferPos += numToDo; | endOfBufferPos += numToDo; | ||||
| } | } | ||||
| for (int channel = 0; channel < numChannels; ++channel) | |||||
| for (int channel = 0; channel < channelsToProcess; ++channel) | |||||
| { | { | ||||
| destBuffers[channel] = info.buffer->getSampleData (channel, info.startSample); | destBuffers[channel] = info.buffer->getSampleData (channel, info.startSample); | ||||
| srcBuffers[channel] = buffer.getSampleData (channel, 0); | srcBuffers[channel] = buffer.getSampleData (channel, 0); | ||||
| @@ -23822,7 +23901,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf | |||||
| const float alpha = (float) subSampleOffset; | const float alpha = (float) subSampleOffset; | ||||
| const float invAlpha = 1.0f - alpha; | 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; | *destBuffers[channel]++ = srcBuffers[channel][bufferPos] * invAlpha + srcBuffers[channel][nextPos] * alpha; | ||||
| subSampleOffset += ratio; | subSampleOffset += ratio; | ||||
| @@ -23844,13 +23923,13 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf | |||||
| if (ratio < 0.9999) | if (ratio < 0.9999) | ||||
| { | { | ||||
| // for up-sampling, apply the filter after transposing.. | // 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]); | applyFilter (info.buffer->getSampleData (i, info.startSample), info.numSamples, filterStates[i]); | ||||
| } | } | ||||
| else if (ratio <= 1.0001) | 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 | // 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); | const float* const endOfBuffer = info.buffer->getSampleData (i, info.startSample + info.numSamples - 1); | ||||
| FilterState& fs = filterStates[i]; | FilterState& fs = filterStates[i]; | ||||
| @@ -85751,7 +85830,7 @@ void DrawablePath::ValueTreeWrapper::Element::convertToPathBreak (UndoManager* u | |||||
| } | } | ||||
| } | } | ||||
| static const Point<float> findCubicSubdivisionPoint (double proportion, const Point<float> points[4]) | |||||
| static const Point<float> findCubicSubdivisionPoint (float proportion, const Point<float> points[4]) | |||||
| { | { | ||||
| const Point<float> mid1 (points[0] + (points[1] - points[0]) * proportion), | const Point<float> mid1 (points[0] + (points[1] - points[0]) * proportion), | ||||
| mid2 (points[1] + (points[2] - points[1]) * proportion), | mid2 (points[1] + (points[2] - points[1]) * proportion), | ||||
| @@ -85763,7 +85842,7 @@ static const Point<float> findCubicSubdivisionPoint (double proportion, const Po | |||||
| return newCp1 + (newCp2 - newCp1) * proportion; | return newCp1 + (newCp2 - newCp1) * proportion; | ||||
| } | } | ||||
| static const Point<float> findQuadraticSubdivisionPoint (double proportion, const Point<float> points[3]) | |||||
| static const Point<float> findQuadraticSubdivisionPoint (float proportion, const Point<float> points[3]) | |||||
| { | { | ||||
| const Point<float> mid1 (points[0] + (points[1] - points[0]) * proportion), | const Point<float> mid1 (points[0] + (points[1] - points[0]) * proportion), | ||||
| mid2 (points[1] + (points[2] - points[1]) * proportion); | mid2 (points[1] + (points[2] - points[1]) * proportion); | ||||
| @@ -85771,10 +85850,10 @@ static const Point<float> findQuadraticSubdivisionPoint (double proportion, cons | |||||
| return mid1 + (mid2 - mid1) * proportion; | return mid1 + (mid2 - mid1) * proportion; | ||||
| } | } | ||||
| double DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const | |||||
| float DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const | |||||
| { | { | ||||
| const Identifier i (state.getType()); | const Identifier i (state.getType()); | ||||
| double bestProp = 0; | |||||
| float bestProp = 0; | |||||
| if (i == cubicToElement) | if (i == cubicToElement) | ||||
| { | { | ||||
| @@ -85786,7 +85865,7 @@ double DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const P | |||||
| for (int i = 110; --i >= 0;) | 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<float> centre (findCubicSubdivisionPoint (prop, points)); | const Point<float> centre (findCubicSubdivisionPoint (prop, points)); | ||||
| const float distance = centre.getDistanceFrom (targetPoint); | const float distance = centre.getDistanceFrom (targetPoint); | ||||
| @@ -85806,8 +85885,8 @@ double DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const P | |||||
| for (int i = 110; --i >= 0;) | for (int i = 110; --i >= 0;) | ||||
| { | { | ||||
| double prop = i > 10 ? ((i - 10) / 100.0) : (bestProp + ((i - 5) / 1000.0)); | |||||
| const Point<float> centre (findQuadraticSubdivisionPoint (prop, points)); | |||||
| float prop = i > 10 ? ((i - 10) / 100.0f) : (bestProp + ((i - 5) / 1000.0f)); | |||||
| const Point<float> centre (findQuadraticSubdivisionPoint ((float) prop, points)); | |||||
| const float distance = centre.getDistanceFrom (targetPoint); | const float distance = centre.getDistanceFrom (targetPoint); | ||||
| if (distance < bestDistance) | if (distance < bestDistance) | ||||
| @@ -85834,7 +85913,7 @@ ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (const Point<floa | |||||
| if (i == cubicToElement) | if (i == cubicToElement) | ||||
| { | { | ||||
| double bestProp = findProportionAlongLine (targetPoint, nameFinder); | |||||
| float bestProp = findProportionAlongLine (targetPoint, nameFinder); | |||||
| RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getControlPoint (1)), rp4 (getEndPoint()); | RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getControlPoint (1)), rp4 (getEndPoint()); | ||||
| const Point<float> points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder), rp4.resolve (nameFinder) }; | const Point<float> points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder), rp4.resolve (nameFinder) }; | ||||
| @@ -85862,7 +85941,7 @@ ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (const Point<floa | |||||
| } | } | ||||
| else if (i == quadraticToElement) | else if (i == quadraticToElement) | ||||
| { | { | ||||
| double bestProp = findProportionAlongLine (targetPoint, nameFinder); | |||||
| float bestProp = findProportionAlongLine (targetPoint, nameFinder); | |||||
| RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getEndPoint()); | RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getEndPoint()); | ||||
| const Point<float> points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder) }; | const Point<float> points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder) }; | ||||
| @@ -259600,8 +259679,6 @@ public: | |||||
| callback (0), | callback (0), | ||||
| inputId (inputId_), | inputId (inputId_), | ||||
| outputId (outputId_), | outputId (outputId_), | ||||
| outputDevice (0), | |||||
| inputDevice (0), | |||||
| numCallbacks (0), | numCallbacks (0), | ||||
| inputChannelBuffer (1, 1), | inputChannelBuffer (1, 1), | ||||
| outputChannelBuffer (1, 1) | outputChannelBuffer (1, 1) | ||||
| @@ -259666,7 +259743,7 @@ public: | |||||
| if (outputDevice->error.isNotEmpty()) | if (outputDevice->error.isNotEmpty()) | ||||
| { | { | ||||
| error = outputDevice->error; | error = outputDevice->error; | ||||
| deleteAndZero (outputDevice); | |||||
| outputDevice = 0; | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -259677,7 +259754,7 @@ public: | |||||
| bufferSize)) | bufferSize)) | ||||
| { | { | ||||
| error = outputDevice->error; | error = outputDevice->error; | ||||
| deleteAndZero (outputDevice); | |||||
| outputDevice = 0; | |||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| @@ -259689,7 +259766,7 @@ public: | |||||
| if (inputDevice->error.isNotEmpty()) | if (inputDevice->error.isNotEmpty()) | ||||
| { | { | ||||
| error = inputDevice->error; | error = inputDevice->error; | ||||
| deleteAndZero (inputDevice); | |||||
| inputDevice = 0; | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -259700,7 +259777,7 @@ public: | |||||
| bufferSize)) | bufferSize)) | ||||
| { | { | ||||
| error = inputDevice->error; | error = inputDevice->error; | ||||
| deleteAndZero (inputDevice); | |||||
| inputDevice = 0; | |||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| @@ -259742,8 +259819,8 @@ public: | |||||
| { | { | ||||
| stopThread (6000); | stopThread (6000); | ||||
| deleteAndZero (inputDevice); | |||||
| deleteAndZero (outputDevice); | |||||
| inputDevice = 0; | |||||
| outputDevice = 0; | |||||
| inputChannelBuffer.setSize (1, 1); | inputChannelBuffer.setSize (1, 1); | ||||
| outputChannelBuffer.setSize (1, 1); | outputChannelBuffer.setSize (1, 1); | ||||
| @@ -259835,8 +259912,7 @@ public: | |||||
| private: | private: | ||||
| const String inputId, outputId; | const String inputId, outputId; | ||||
| ALSADevice* outputDevice; | |||||
| ALSADevice* inputDevice; | |||||
| ScopedPointer<ALSADevice> outputDevice, inputDevice; | |||||
| int numCallbacks; | int numCallbacks; | ||||
| CriticalSection callbackLock; | CriticalSection callbackLock; | ||||
| @@ -259891,7 +259967,7 @@ public: | |||||
| outputId (outputId_), | outputId (outputId_), | ||||
| isOpen_ (false), | isOpen_ (false), | ||||
| isStarted (false), | isStarted (false), | ||||
| internal (new ALSAThread (inputId_, outputId_)) | |||||
| internal (inputId_, outputId_) | |||||
| { | { | ||||
| } | } | ||||
| @@ -259901,22 +259977,22 @@ public: | |||||
| const StringArray getOutputChannelNames() | const StringArray getOutputChannelNames() | ||||
| { | { | ||||
| return internal->channelNamesOut; | |||||
| return internal.channelNamesOut; | |||||
| } | } | ||||
| const StringArray getInputChannelNames() | const StringArray getInputChannelNames() | ||||
| { | { | ||||
| return internal->channelNamesIn; | |||||
| return internal.channelNamesIn; | |||||
| } | } | ||||
| int getNumSampleRates() | int getNumSampleRates() | ||||
| { | { | ||||
| return internal->sampleRates.size(); | |||||
| return internal.sampleRates.size(); | |||||
| } | } | ||||
| double getSampleRate (int index) | double getSampleRate (int index) | ||||
| { | { | ||||
| return internal->sampleRates [index]; | |||||
| return internal.sampleRates [index]; | |||||
| } | } | ||||
| int getNumBufferSizesAvailable() | 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() | void close() | ||||
| { | { | ||||
| stop(); | stop(); | ||||
| internal->close(); | |||||
| internal.close(); | |||||
| isOpen_ = false; | isOpen_ = false; | ||||
| } | } | ||||
| @@ -259984,27 +260060,27 @@ public: | |||||
| int getCurrentBufferSizeSamples() | int getCurrentBufferSizeSamples() | ||||
| { | { | ||||
| return internal->bufferSize; | |||||
| return internal.bufferSize; | |||||
| } | } | ||||
| double getCurrentSampleRate() | double getCurrentSampleRate() | ||||
| { | { | ||||
| return internal->sampleRate; | |||||
| return internal.sampleRate; | |||||
| } | } | ||||
| int getCurrentBitDepth() | int getCurrentBitDepth() | ||||
| { | { | ||||
| return internal->getBitDepth(); | |||||
| return internal.getBitDepth(); | |||||
| } | } | ||||
| const BigInteger getActiveOutputChannels() const | const BigInteger getActiveOutputChannels() const | ||||
| { | { | ||||
| return internal->currentOutputChans; | |||||
| return internal.currentOutputChans; | |||||
| } | } | ||||
| const BigInteger getActiveInputChannels() const | const BigInteger getActiveInputChannels() const | ||||
| { | { | ||||
| return internal->currentInputChans; | |||||
| return internal.currentInputChans; | |||||
| } | } | ||||
| int getOutputLatencyInSamples() | int getOutputLatencyInSamples() | ||||
| @@ -260022,17 +260098,17 @@ public: | |||||
| if (! isOpen_) | if (! isOpen_) | ||||
| callback = 0; | callback = 0; | ||||
| internal->setCallback (callback); | |||||
| if (callback != 0) | if (callback != 0) | ||||
| callback->audioDeviceAboutToStart (this); | callback->audioDeviceAboutToStart (this); | ||||
| internal.setCallback (callback); | |||||
| isStarted = (callback != 0); | isStarted = (callback != 0); | ||||
| } | } | ||||
| void stop() | void stop() | ||||
| { | { | ||||
| AudioIODeviceCallback* const oldCallback = internal->callback; | |||||
| AudioIODeviceCallback* const oldCallback = internal.callback; | |||||
| start (0); | start (0); | ||||
| @@ -260042,19 +260118,19 @@ public: | |||||
| bool isPlaying() | bool isPlaying() | ||||
| { | { | ||||
| return isStarted && internal->error.isEmpty(); | |||||
| return isStarted && internal.error.isEmpty(); | |||||
| } | } | ||||
| const String getLastError() | const String getLastError() | ||||
| { | { | ||||
| return internal->error; | |||||
| return internal.error; | |||||
| } | } | ||||
| String inputId, outputId; | String inputId, outputId; | ||||
| private: | private: | ||||
| bool isOpen_, isStarted; | bool isOpen_, isStarted; | ||||
| ScopedPointer<ALSAThread> internal; | |||||
| ALSAThread internal; | |||||
| }; | }; | ||||
| class ALSAAudioIODeviceType : public AudioIODeviceType | class ALSAAudioIODeviceType : public AudioIODeviceType | ||||
| @@ -64,7 +64,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
| #define JUCE_BUILDNUMBER 31 | |||||
| #define JUCE_BUILDNUMBER 32 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -5544,13 +5544,13 @@ public: | |||||
| const String toString() const; | const String toString() const; | ||||
| DynamicObject* getObject() 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. | /** Writes a binary representation of this value to a stream. | ||||
| The data can be read back later using readFromStream(). | The data can be read back later using readFromStream(). | ||||
| @@ -5591,16 +5591,24 @@ public: | |||||
| bool equals (const var& other) const throw(); | bool equals (const var& other) const throw(); | ||||
| private: | 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 | union ValueUnion | ||||
| { | { | ||||
| @@ -5612,7 +5620,7 @@ private: | |||||
| MethodFunction methodValue; | MethodFunction methodValue; | ||||
| }; | }; | ||||
| Type type; | |||||
| const VariantType* type; | |||||
| ValueUnion value; | ValueUnion value; | ||||
| }; | }; | ||||
| @@ -59416,7 +59424,7 @@ public: | |||||
| void convertToPathBreak (UndoManager* undoManager); | void convertToPathBreak (UndoManager* undoManager); | ||||
| ValueTree insertPoint (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder, UndoManager* undoManager); | ValueTree insertPoint (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder, UndoManager* undoManager); | ||||
| void removePoint (UndoManager* undoManager); | void removePoint (UndoManager* undoManager); | ||||
| double findProportionAlongLine (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const; | |||||
| float findProportionAlongLine (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const; | |||||
| static const Identifier mode, startSubPathElement, closeSubPathElement, | static const Identifier mode, startSubPathElement, closeSubPathElement, | ||||
| lineToElement, quadraticToElement, cubicToElement; | lineToElement, quadraticToElement, cubicToElement; | ||||
| @@ -110,6 +110,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf | |||||
| bufferPos %= bufferSize; | bufferPos %= bufferSize; | ||||
| int endOfBufferPos = bufferPos + sampsInBuffer; | int endOfBufferPos = bufferPos + sampsInBuffer; | ||||
| const int channelsToProcess = jmin (numChannels, info.buffer->getNumChannels()); | |||||
| while (sampsNeeded > sampsInBuffer) | while (sampsNeeded > sampsInBuffer) | ||||
| { | { | ||||
| @@ -129,7 +130,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf | |||||
| { | { | ||||
| // for down-sampling, pre-apply the filter.. | // 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]); | applyFilter (buffer.getSampleData (i, endOfBufferPos), numToDo, filterStates[i]); | ||||
| } | } | ||||
| @@ -137,7 +138,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf | |||||
| endOfBufferPos += numToDo; | endOfBufferPos += numToDo; | ||||
| } | } | ||||
| for (int channel = 0; channel < numChannels; ++channel) | |||||
| for (int channel = 0; channel < channelsToProcess; ++channel) | |||||
| { | { | ||||
| destBuffers[channel] = info.buffer->getSampleData (channel, info.startSample); | destBuffers[channel] = info.buffer->getSampleData (channel, info.startSample); | ||||
| srcBuffers[channel] = buffer.getSampleData (channel, 0); | srcBuffers[channel] = buffer.getSampleData (channel, 0); | ||||
| @@ -149,7 +150,7 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf | |||||
| const float alpha = (float) subSampleOffset; | const float alpha = (float) subSampleOffset; | ||||
| const float invAlpha = 1.0f - alpha; | 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; | *destBuffers[channel]++ = srcBuffers[channel][bufferPos] * invAlpha + srcBuffers[channel][nextPos] * alpha; | ||||
| subSampleOffset += ratio; | subSampleOffset += ratio; | ||||
| @@ -171,13 +172,13 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf | |||||
| if (ratio < 0.9999) | if (ratio < 0.9999) | ||||
| { | { | ||||
| // for up-sampling, apply the filter after transposing.. | // 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]); | applyFilter (info.buffer->getSampleData (i, info.startSample), info.numSamples, filterStates[i]); | ||||
| } | } | ||||
| else if (ratio <= 1.0001) | 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 | // 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); | const float* const endOfBuffer = info.buffer->getSampleData (i, info.startSample + info.numSamples - 1); | ||||
| FilterState& fs = filterStates[i]; | FilterState& fs = filterStates[i]; | ||||
| @@ -31,72 +31,261 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "juce_DynamicObject.h" | #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<char> 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() | var::var() throw() | ||||
| : type (voidType) | |||||
| : type (VariantType_Void::getInstance()) | |||||
| { | { | ||||
| value.doubleValue = 0; | |||||
| } | } | ||||
| var::~var() throw() | 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; | 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_; | value.intValue = value_; | ||||
| } | } | ||||
| var::var (const bool value_) throw() | |||||
| : type (boolType) | |||||
| var::var (const bool value_) throw() : type (VariantType_Bool::getInstance()) | |||||
| { | { | ||||
| value.boolValue = value_; | value.boolValue = value_; | ||||
| } | } | ||||
| var::var (const double value_) throw() | |||||
| : type (doubleType) | |||||
| var::var (const double value_) throw() : type (VariantType_Double::getInstance()) | |||||
| { | { | ||||
| value.doubleValue = value_; | value.doubleValue = value_; | ||||
| } | } | ||||
| var::var (const String& value_) | |||||
| : type (stringType) | |||||
| var::var (const String& value_) : type (VariantType_String::getInstance()) | |||||
| { | { | ||||
| value.stringValue = new String (value_); | 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_); | 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_); | value.stringValue = new String (value_); | ||||
| } | } | ||||
| var::var (DynamicObject* const object) | |||||
| : type (objectType) | |||||
| var::var (DynamicObject* const object) : type (VariantType_Object::getInstance()) | |||||
| { | { | ||||
| value.objectValue = object; | value.objectValue = object; | ||||
| @@ -104,12 +293,28 @@ var::var (DynamicObject* const object) | |||||
| object->incReferenceCount(); | object->incReferenceCount(); | ||||
| } | } | ||||
| var::var (MethodFunction method_) throw() | |||||
| : type (methodType) | |||||
| var::var (MethodFunction method_) throw() : type (VariantType_Method::getInstance()) | |||||
| { | { | ||||
| value.methodValue = method_; | 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() | void var::swapWith (var& other) throw() | ||||
| { | { | ||||
| @@ -117,115 +322,20 @@ void var::swapWith (var& other) throw() | |||||
| swapVariables (value, other.value); | 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 <int> (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() | bool var::equals (const var& other) const throw() | ||||
| { | { | ||||
| switch (type) | |||||
| { | |||||
| case voidType: return other.isVoid(); | |||||
| case intType: return value.intValue == static_cast <int> (other); | |||||
| case boolType: return value.boolValue == static_cast <bool> (other); | |||||
| case doubleType: return value.doubleValue == static_cast <double> (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); } | 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 | 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<char> 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) | const var var::readFromStream (InputStream& input) | ||||
| @@ -286,18 +377,14 @@ const var var::readFromStream (InputStream& input) | |||||
| const var var::operator[] (const Identifier& propertyName) const | 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 | 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 | const var var::invoke (const var& targetObject, const var* arguments, int numArguments) const | ||||
| @@ -90,13 +90,13 @@ public: | |||||
| const String toString() const; | const String toString() const; | ||||
| DynamicObject* getObject() 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. | /** Writes a binary representation of this value to a stream. | ||||
| @@ -142,16 +142,24 @@ public: | |||||
| bool equals (const var& other) const throw(); | bool equals (const var& other) const throw(); | ||||
| private: | 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 | union ValueUnion | ||||
| { | { | ||||
| @@ -163,7 +171,7 @@ private: | |||||
| MethodFunction methodValue; | MethodFunction methodValue; | ||||
| }; | }; | ||||
| Type type; | |||||
| const VariantType* type; | |||||
| ValueUnion value; | ValueUnion value; | ||||
| }; | }; | ||||
| @@ -33,7 +33,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 52 | #define JUCE_MINOR_VERSION 52 | ||||
| #define JUCE_BUILDNUMBER 31 | |||||
| #define JUCE_BUILDNUMBER 32 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -273,7 +273,7 @@ public: | |||||
| bool relativeToComponentTopLeft) const; | bool relativeToComponentTopLeft) const; | ||||
| /** Returns the component that currently represents a given cell. | /** 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. | this may return 0. | ||||
| @see getCellPosition | @see getCellPosition | ||||
| */ | */ | ||||
| @@ -453,7 +453,7 @@ void DrawablePath::ValueTreeWrapper::Element::convertToPathBreak (UndoManager* u | |||||
| } | } | ||||
| } | } | ||||
| static const Point<float> findCubicSubdivisionPoint (double proportion, const Point<float> points[4]) | |||||
| static const Point<float> findCubicSubdivisionPoint (float proportion, const Point<float> points[4]) | |||||
| { | { | ||||
| const Point<float> mid1 (points[0] + (points[1] - points[0]) * proportion), | const Point<float> mid1 (points[0] + (points[1] - points[0]) * proportion), | ||||
| mid2 (points[1] + (points[2] - points[1]) * proportion), | mid2 (points[1] + (points[2] - points[1]) * proportion), | ||||
| @@ -465,7 +465,7 @@ static const Point<float> findCubicSubdivisionPoint (double proportion, const Po | |||||
| return newCp1 + (newCp2 - newCp1) * proportion; | return newCp1 + (newCp2 - newCp1) * proportion; | ||||
| } | } | ||||
| static const Point<float> findQuadraticSubdivisionPoint (double proportion, const Point<float> points[3]) | |||||
| static const Point<float> findQuadraticSubdivisionPoint (float proportion, const Point<float> points[3]) | |||||
| { | { | ||||
| const Point<float> mid1 (points[0] + (points[1] - points[0]) * proportion), | const Point<float> mid1 (points[0] + (points[1] - points[0]) * proportion), | ||||
| mid2 (points[1] + (points[2] - points[1]) * proportion); | mid2 (points[1] + (points[2] - points[1]) * proportion); | ||||
| @@ -473,10 +473,10 @@ static const Point<float> findQuadraticSubdivisionPoint (double proportion, cons | |||||
| return mid1 + (mid2 - mid1) * proportion; | return mid1 + (mid2 - mid1) * proportion; | ||||
| } | } | ||||
| double DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const | |||||
| float DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const | |||||
| { | { | ||||
| const Identifier i (state.getType()); | const Identifier i (state.getType()); | ||||
| double bestProp = 0; | |||||
| float bestProp = 0; | |||||
| if (i == cubicToElement) | if (i == cubicToElement) | ||||
| { | { | ||||
| @@ -488,7 +488,7 @@ double DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const P | |||||
| for (int i = 110; --i >= 0;) | 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<float> centre (findCubicSubdivisionPoint (prop, points)); | const Point<float> centre (findCubicSubdivisionPoint (prop, points)); | ||||
| const float distance = centre.getDistanceFrom (targetPoint); | const float distance = centre.getDistanceFrom (targetPoint); | ||||
| @@ -508,8 +508,8 @@ double DrawablePath::ValueTreeWrapper::Element::findProportionAlongLine (const P | |||||
| for (int i = 110; --i >= 0;) | for (int i = 110; --i >= 0;) | ||||
| { | { | ||||
| double prop = i > 10 ? ((i - 10) / 100.0) : (bestProp + ((i - 5) / 1000.0)); | |||||
| const Point<float> centre (findQuadraticSubdivisionPoint (prop, points)); | |||||
| float prop = i > 10 ? ((i - 10) / 100.0f) : (bestProp + ((i - 5) / 1000.0f)); | |||||
| const Point<float> centre (findQuadraticSubdivisionPoint ((float) prop, points)); | |||||
| const float distance = centre.getDistanceFrom (targetPoint); | const float distance = centre.getDistanceFrom (targetPoint); | ||||
| if (distance < bestDistance) | if (distance < bestDistance) | ||||
| @@ -536,7 +536,7 @@ ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (const Point<floa | |||||
| if (i == cubicToElement) | if (i == cubicToElement) | ||||
| { | { | ||||
| double bestProp = findProportionAlongLine (targetPoint, nameFinder); | |||||
| float bestProp = findProportionAlongLine (targetPoint, nameFinder); | |||||
| RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getControlPoint (1)), rp4 (getEndPoint()); | RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getControlPoint (1)), rp4 (getEndPoint()); | ||||
| const Point<float> points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder), rp4.resolve (nameFinder) }; | const Point<float> points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder), rp4.resolve (nameFinder) }; | ||||
| @@ -564,7 +564,7 @@ ValueTree DrawablePath::ValueTreeWrapper::Element::insertPoint (const Point<floa | |||||
| } | } | ||||
| else if (i == quadraticToElement) | else if (i == quadraticToElement) | ||||
| { | { | ||||
| double bestProp = findProportionAlongLine (targetPoint, nameFinder); | |||||
| float bestProp = findProportionAlongLine (targetPoint, nameFinder); | |||||
| RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getEndPoint()); | RelativePoint rp1 (getStartPoint()), rp2 (getControlPoint (0)), rp3 (getEndPoint()); | ||||
| const Point<float> points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder) }; | const Point<float> points[] = { rp1.resolve (nameFinder), rp2.resolve (nameFinder), rp3.resolve (nameFinder) }; | ||||
| @@ -176,7 +176,7 @@ public: | |||||
| void convertToPathBreak (UndoManager* undoManager); | void convertToPathBreak (UndoManager* undoManager); | ||||
| ValueTree insertPoint (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder, UndoManager* undoManager); | ValueTree insertPoint (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder, UndoManager* undoManager); | ||||
| void removePoint (UndoManager* undoManager); | void removePoint (UndoManager* undoManager); | ||||
| double findProportionAlongLine (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const; | |||||
| float findProportionAlongLine (const Point<float>& targetPoint, RelativeCoordinate::NamedCoordinateFinder* nameFinder) const; | |||||
| static const Identifier mode, startSubPathElement, closeSubPathElement, | static const Identifier mode, startSubPathElement, closeSubPathElement, | ||||
| lineToElement, quadraticToElement, cubicToElement; | lineToElement, quadraticToElement, cubicToElement; | ||||
| @@ -349,8 +349,6 @@ public: | |||||
| callback (0), | callback (0), | ||||
| inputId (inputId_), | inputId (inputId_), | ||||
| outputId (outputId_), | outputId (outputId_), | ||||
| outputDevice (0), | |||||
| inputDevice (0), | |||||
| numCallbacks (0), | numCallbacks (0), | ||||
| inputChannelBuffer (1, 1), | inputChannelBuffer (1, 1), | ||||
| outputChannelBuffer (1, 1) | outputChannelBuffer (1, 1) | ||||
| @@ -415,7 +413,7 @@ public: | |||||
| if (outputDevice->error.isNotEmpty()) | if (outputDevice->error.isNotEmpty()) | ||||
| { | { | ||||
| error = outputDevice->error; | error = outputDevice->error; | ||||
| deleteAndZero (outputDevice); | |||||
| outputDevice = 0; | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -426,7 +424,7 @@ public: | |||||
| bufferSize)) | bufferSize)) | ||||
| { | { | ||||
| error = outputDevice->error; | error = outputDevice->error; | ||||
| deleteAndZero (outputDevice); | |||||
| outputDevice = 0; | |||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| @@ -438,7 +436,7 @@ public: | |||||
| if (inputDevice->error.isNotEmpty()) | if (inputDevice->error.isNotEmpty()) | ||||
| { | { | ||||
| error = inputDevice->error; | error = inputDevice->error; | ||||
| deleteAndZero (inputDevice); | |||||
| inputDevice = 0; | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -449,7 +447,7 @@ public: | |||||
| bufferSize)) | bufferSize)) | ||||
| { | { | ||||
| error = inputDevice->error; | error = inputDevice->error; | ||||
| deleteAndZero (inputDevice); | |||||
| inputDevice = 0; | |||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| @@ -491,8 +489,8 @@ public: | |||||
| { | { | ||||
| stopThread (6000); | stopThread (6000); | ||||
| deleteAndZero (inputDevice); | |||||
| deleteAndZero (outputDevice); | |||||
| inputDevice = 0; | |||||
| outputDevice = 0; | |||||
| inputChannelBuffer.setSize (1, 1); | inputChannelBuffer.setSize (1, 1); | ||||
| outputChannelBuffer.setSize (1, 1); | outputChannelBuffer.setSize (1, 1); | ||||
| @@ -585,8 +583,7 @@ public: | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| const String inputId, outputId; | const String inputId, outputId; | ||||
| ALSADevice* outputDevice; | |||||
| ALSADevice* inputDevice; | |||||
| ScopedPointer<ALSADevice> outputDevice, inputDevice; | |||||
| int numCallbacks; | int numCallbacks; | ||||
| CriticalSection callbackLock; | CriticalSection callbackLock; | ||||
| @@ -643,7 +640,7 @@ public: | |||||
| outputId (outputId_), | outputId (outputId_), | ||||
| isOpen_ (false), | isOpen_ (false), | ||||
| isStarted (false), | isStarted (false), | ||||
| internal (new ALSAThread (inputId_, outputId_)) | |||||
| internal (inputId_, outputId_) | |||||
| { | { | ||||
| } | } | ||||
| @@ -653,22 +650,22 @@ public: | |||||
| const StringArray getOutputChannelNames() | const StringArray getOutputChannelNames() | ||||
| { | { | ||||
| return internal->channelNamesOut; | |||||
| return internal.channelNamesOut; | |||||
| } | } | ||||
| const StringArray getInputChannelNames() | const StringArray getInputChannelNames() | ||||
| { | { | ||||
| return internal->channelNamesIn; | |||||
| return internal.channelNamesIn; | |||||
| } | } | ||||
| int getNumSampleRates() | int getNumSampleRates() | ||||
| { | { | ||||
| return internal->sampleRates.size(); | |||||
| return internal.sampleRates.size(); | |||||
| } | } | ||||
| double getSampleRate (int index) | double getSampleRate (int index) | ||||
| { | { | ||||
| return internal->sampleRates [index]; | |||||
| return internal.sampleRates [index]; | |||||
| } | } | ||||
| int getNumBufferSizesAvailable() | 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() | void close() | ||||
| { | { | ||||
| stop(); | stop(); | ||||
| internal->close(); | |||||
| internal.close(); | |||||
| isOpen_ = false; | isOpen_ = false; | ||||
| } | } | ||||
| @@ -736,27 +733,27 @@ public: | |||||
| int getCurrentBufferSizeSamples() | int getCurrentBufferSizeSamples() | ||||
| { | { | ||||
| return internal->bufferSize; | |||||
| return internal.bufferSize; | |||||
| } | } | ||||
| double getCurrentSampleRate() | double getCurrentSampleRate() | ||||
| { | { | ||||
| return internal->sampleRate; | |||||
| return internal.sampleRate; | |||||
| } | } | ||||
| int getCurrentBitDepth() | int getCurrentBitDepth() | ||||
| { | { | ||||
| return internal->getBitDepth(); | |||||
| return internal.getBitDepth(); | |||||
| } | } | ||||
| const BigInteger getActiveOutputChannels() const | const BigInteger getActiveOutputChannels() const | ||||
| { | { | ||||
| return internal->currentOutputChans; | |||||
| return internal.currentOutputChans; | |||||
| } | } | ||||
| const BigInteger getActiveInputChannels() const | const BigInteger getActiveInputChannels() const | ||||
| { | { | ||||
| return internal->currentInputChans; | |||||
| return internal.currentInputChans; | |||||
| } | } | ||||
| int getOutputLatencyInSamples() | int getOutputLatencyInSamples() | ||||
| @@ -774,17 +771,17 @@ public: | |||||
| if (! isOpen_) | if (! isOpen_) | ||||
| callback = 0; | callback = 0; | ||||
| internal->setCallback (callback); | |||||
| if (callback != 0) | if (callback != 0) | ||||
| callback->audioDeviceAboutToStart (this); | callback->audioDeviceAboutToStart (this); | ||||
| internal.setCallback (callback); | |||||
| isStarted = (callback != 0); | isStarted = (callback != 0); | ||||
| } | } | ||||
| void stop() | void stop() | ||||
| { | { | ||||
| AudioIODeviceCallback* const oldCallback = internal->callback; | |||||
| AudioIODeviceCallback* const oldCallback = internal.callback; | |||||
| start (0); | start (0); | ||||
| @@ -794,19 +791,19 @@ public: | |||||
| bool isPlaying() | bool isPlaying() | ||||
| { | { | ||||
| return isStarted && internal->error.isEmpty(); | |||||
| return isStarted && internal.error.isEmpty(); | |||||
| } | } | ||||
| const String getLastError() | const String getLastError() | ||||
| { | { | ||||
| return internal->error; | |||||
| return internal.error; | |||||
| } | } | ||||
| String inputId, outputId; | String inputId, outputId; | ||||
| private: | private: | ||||
| bool isOpen_, isStarted; | bool isOpen_, isStarted; | ||||
| ScopedPointer<ALSAThread> internal; | |||||
| ALSAThread internal; | |||||
| }; | }; | ||||