Browse Source

ALSA fix. Removed some win32 compile warnings. Refactored Variant class internally.

tags/2021-05-28
Julian Storer 15 years ago
parent
commit
366c8fb7e2
10 changed files with 632 additions and 455 deletions
  1. +282
    -206
      juce_amalgamated.cpp
  2. +28
    -20
      juce_amalgamated.h
  3. +6
    -5
      src/audio/audio_sources/juce_ResamplingAudioSource.cpp
  4. +250
    -163
      src/containers/juce_Variant.cpp
  5. +26
    -18
      src/containers/juce_Variant.h
  6. +1
    -1
      src/core/juce_StandardHeader.h
  7. +1
    -1
      src/gui/components/controls/juce_TableListBox.h
  8. +9
    -9
      src/gui/graphics/drawables/juce_DrawablePath.cpp
  9. +1
    -1
      src/gui/graphics/drawables/juce_DrawablePath.h
  10. +28
    -31
      src/native/linux/juce_linux_Audio.cpp

+ 282
- 206
juce_amalgamated.cpp View File

@@ -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


+ 28
- 20
juce_amalgamated.h View File

@@ -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;


+ 6
- 5
src/audio/audio_sources/juce_ResamplingAudioSource.cpp View File

@@ -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];


+ 250
- 163
src/containers/juce_Variant.cpp View File

@@ -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


+ 26
- 18
src/containers/juce_Variant.h View File

@@ -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;
}; };


+ 1
- 1
src/core/juce_StandardHeader.h View File

@@ -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.


+ 1
- 1
src/gui/components/controls/juce_TableListBox.h View File

@@ -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
*/ */


+ 9
- 9
src/gui/graphics/drawables/juce_DrawablePath.cpp View File

@@ -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) };


+ 1
- 1
src/gui/graphics/drawables/juce_DrawablePath.h View File

@@ -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;


+ 28
- 31
src/native/linux/juce_linux_Audio.cpp View File

@@ -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;
}; };


Loading…
Cancel
Save