| @@ -25,6 +25,12 @@ | |||
| BEGIN_JUCE_NAMESPACE | |||
| #if JUCE_INTEL | |||
| #define JUCE_SNAP_TO_ZERO(n) if (! (n < -1.0e-8 || n > 1.0e-8)) n = 0; | |||
| #else | |||
| #define JUCE_SNAP_TO_ZERO(n) | |||
| #endif | |||
| //============================================================================== | |||
| IIRFilter::IIRFilter() | |||
| : active (false) | |||
| @@ -63,10 +69,7 @@ float IIRFilter::processSingleSampleRaw (const float in) noexcept | |||
| - coefficients[4] * y1 | |||
| - coefficients[5] * y2; | |||
| #if JUCE_INTEL | |||
| if (! (out < -1.0e-8 || out > 1.0e-8)) | |||
| out = 0; | |||
| #endif | |||
| JUCE_SNAP_TO_ZERO (out); | |||
| x2 = x1; | |||
| x1 = in; | |||
| @@ -93,10 +96,7 @@ void IIRFilter::processSamples (float* const samples, | |||
| - coefficients[4] * y1 | |||
| - coefficients[5] * y2; | |||
| #if JUCE_INTEL | |||
| if (! (out < -1.0e-8 || out > 1.0e-8)) | |||
| out = 0; | |||
| #endif | |||
| JUCE_SNAP_TO_ZERO (out); | |||
| x2 = x1; | |||
| x1 = in; | |||
| @@ -251,5 +251,6 @@ void IIRFilter::setCoefficients (double c1, double c2, double c3, | |||
| active = true; | |||
| } | |||
| #undef JUCE_SNAP_TO_ZERO | |||
| END_JUCE_NAMESPACE | |||
| @@ -52,11 +52,11 @@ public: | |||
| struct Parameters | |||
| { | |||
| Parameters() noexcept | |||
| : roomSize (0.5f), | |||
| damping (0.5f), | |||
| wetLevel (0.33f), | |||
| dryLevel (0.4f), | |||
| width (1.0f), | |||
| : roomSize (0.5f), | |||
| damping (0.5f), | |||
| wetLevel (0.33f), | |||
| dryLevel (0.4f), | |||
| width (1.0f), | |||
| freezeMode (0) | |||
| {} | |||
| @@ -25,6 +25,24 @@ | |||
| BEGIN_JUCE_NAMESPACE | |||
| namespace MidiBufferHelpers | |||
| { | |||
| inline int getEventTime (const void* const d) noexcept | |||
| { | |||
| return *static_cast <const int*> (d); | |||
| } | |||
| inline uint16 getEventDataSize (const void* const d) noexcept | |||
| { | |||
| return *reinterpret_cast <const uint16*> (static_cast <const char*> (d) + sizeof (int)); | |||
| } | |||
| inline uint16 getEventTotalSize (const void* const d) noexcept | |||
| { | |||
| return getEventDataSize (d) + sizeof (int) + sizeof (uint16); | |||
| } | |||
| } | |||
| //============================================================================== | |||
| MidiBuffer::MidiBuffer() noexcept | |||
| : bytesUsed (0) | |||
| @@ -66,21 +84,6 @@ inline uint8* MidiBuffer::getData() const noexcept | |||
| return static_cast <uint8*> (data.getData()); | |||
| } | |||
| inline int MidiBuffer::getEventTime (const void* const d) noexcept | |||
| { | |||
| return *static_cast <const int*> (d); | |||
| } | |||
| inline uint16 MidiBuffer::getEventDataSize (const void* const d) noexcept | |||
| { | |||
| return *reinterpret_cast <const uint16*> (static_cast <const char*> (d) + sizeof (int)); | |||
| } | |||
| inline uint16 MidiBuffer::getEventTotalSize (const void* const d) noexcept | |||
| { | |||
| return getEventDataSize (d) + sizeof (int) + sizeof (uint16); | |||
| } | |||
| void MidiBuffer::clear() noexcept | |||
| { | |||
| bytesUsed = 0; | |||
| @@ -201,7 +204,7 @@ int MidiBuffer::getNumEvents() const noexcept | |||
| while (d < end) | |||
| { | |||
| d += getEventTotalSize (d); | |||
| d += MidiBufferHelpers::getEventTotalSize (d); | |||
| ++n; | |||
| } | |||
| @@ -210,7 +213,7 @@ int MidiBuffer::getNumEvents() const noexcept | |||
| int MidiBuffer::getFirstEventTime() const noexcept | |||
| { | |||
| return bytesUsed > 0 ? getEventTime (data.getData()) : 0; | |||
| return bytesUsed > 0 ? MidiBufferHelpers::getEventTime (data.getData()) : 0; | |||
| } | |||
| int MidiBuffer::getLastEventTime() const noexcept | |||
| @@ -223,10 +226,10 @@ int MidiBuffer::getLastEventTime() const noexcept | |||
| for (;;) | |||
| { | |||
| const uint8* const nextOne = d + getEventTotalSize (d); | |||
| const uint8* const nextOne = d + MidiBufferHelpers::getEventTotalSize (d); | |||
| if (nextOne >= endData) | |||
| return getEventTime (d); | |||
| return MidiBufferHelpers::getEventTime (d); | |||
| d = nextOne; | |||
| } | |||
| @@ -236,8 +239,8 @@ uint8* MidiBuffer::findEventAfter (uint8* d, const int samplePosition) const noe | |||
| { | |||
| const uint8* const endData = getData() + bytesUsed; | |||
| while (d < endData && getEventTime (d) <= samplePosition) | |||
| d += getEventTotalSize (d); | |||
| while (d < endData && MidiBufferHelpers::getEventTime (d) <= samplePosition) | |||
| d += MidiBufferHelpers::getEventTotalSize (d); | |||
| return d; | |||
| } | |||
| @@ -259,8 +262,8 @@ void MidiBuffer::Iterator::setNextSamplePosition (const int samplePosition) noex | |||
| data = buffer.getData(); | |||
| const uint8* dataEnd = data + buffer.bytesUsed; | |||
| while (data < dataEnd && getEventTime (data) < samplePosition) | |||
| data += getEventTotalSize (data); | |||
| while (data < dataEnd && MidiBufferHelpers::getEventTime (data) < samplePosition) | |||
| data += MidiBufferHelpers::getEventTotalSize (data); | |||
| } | |||
| bool MidiBuffer::Iterator::getNextEvent (const uint8* &midiData, int& numBytes, int& samplePosition) noexcept | |||
| @@ -268,8 +271,8 @@ bool MidiBuffer::Iterator::getNextEvent (const uint8* &midiData, int& numBytes, | |||
| if (data >= buffer.getData() + buffer.bytesUsed) | |||
| return false; | |||
| samplePosition = getEventTime (data); | |||
| numBytes = getEventDataSize (data); | |||
| samplePosition = MidiBufferHelpers::getEventTime (data); | |||
| numBytes = MidiBufferHelpers::getEventDataSize (data); | |||
| data += sizeof (int) + sizeof (uint16); | |||
| midiData = data; | |||
| data += numBytes; | |||
| @@ -282,8 +285,8 @@ bool MidiBuffer::Iterator::getNextEvent (MidiMessage& result, int& samplePositio | |||
| if (data >= buffer.getData() + buffer.bytesUsed) | |||
| return false; | |||
| samplePosition = getEventTime (data); | |||
| const int numBytes = getEventDataSize (data); | |||
| samplePosition = MidiBufferHelpers::getEventTime (data); | |||
| const int numBytes = MidiBufferHelpers::getEventDataSize (data); | |||
| data += sizeof (int) + sizeof (uint16); | |||
| result = MidiMessage (data, numBytes, samplePosition); | |||
| data += numBytes; | |||
| @@ -227,10 +227,7 @@ private: | |||
| int bytesUsed; | |||
| uint8* getData() const noexcept; | |||
| uint8* findEventAfter (uint8* d, int samplePosition) const noexcept; | |||
| static int getEventTime (const void* d) noexcept; | |||
| static uint16 getEventDataSize (const void* d) noexcept; | |||
| static uint16 getEventTotalSize (const void* d) noexcept; | |||
| uint8* findEventAfter (uint8*, int samplePosition) const noexcept; | |||
| JUCE_LEAK_DETECTOR (MidiBuffer); | |||
| }; | |||
| @@ -25,17 +25,17 @@ | |||
| BEGIN_JUCE_NAMESPACE | |||
| //============================================================================== | |||
| namespace MidiFileHelpers | |||
| { | |||
| void writeVariableLengthInt (OutputStream& out, unsigned int v) | |||
| { | |||
| unsigned int buffer = v & 0x7F; | |||
| unsigned int buffer = v & 0x7f; | |||
| while ((v >>= 7) != 0) | |||
| { | |||
| buffer <<= 8; | |||
| buffer |= ((v & 0x7F) | 0x80); | |||
| buffer |= ((v & 0x7f) | 0x80); | |||
| } | |||
| for (;;) | |||
| @@ -97,8 +97,7 @@ namespace MidiFileHelpers | |||
| { | |||
| if (timeFormat > 0) | |||
| { | |||
| int numer = 4, denom = 4; | |||
| double tempoTime = 0.0, correctedTempoTime = 0.0; | |||
| double lastTime = 0.0, correctedTime = 0.0; | |||
| const double tickLen = 1.0 / (timeFormat & 0x7fff); | |||
| double secsPerTick = 0.5 * tickLen; | |||
| const int numEvents = tempoEvents.getNumEvents(); | |||
| @@ -106,47 +105,32 @@ namespace MidiFileHelpers | |||
| for (int i = 0; i < numEvents; ++i) | |||
| { | |||
| const MidiMessage& m = tempoEvents.getEventPointer(i)->message; | |||
| const double eventTime = m.getTimeStamp(); | |||
| if (time <= m.getTimeStamp()) | |||
| if (eventTime >= time) | |||
| break; | |||
| if (timeFormat > 0) | |||
| { | |||
| correctedTempoTime = correctedTempoTime | |||
| + (m.getTimeStamp() - tempoTime) * secsPerTick; | |||
| } | |||
| else | |||
| { | |||
| correctedTempoTime = tickLen * m.getTimeStamp() / (((timeFormat & 0x7fff) >> 8) * (timeFormat & 0xff)); | |||
| } | |||
| tempoTime = m.getTimeStamp(); | |||
| correctedTime += (eventTime - lastTime) * secsPerTick; | |||
| lastTime = eventTime; | |||
| if (m.isTempoMetaEvent()) | |||
| secsPerTick = tickLen * m.getTempoSecondsPerQuarterNote(); | |||
| else if (m.isTimeSignatureMetaEvent()) | |||
| m.getTimeSignatureInfo (numer, denom); | |||
| while (i + 1 < numEvents) | |||
| { | |||
| const MidiMessage& m2 = tempoEvents.getEventPointer(i + 1)->message; | |||
| if (m2.getTimeStamp() == tempoTime) | |||
| { | |||
| ++i; | |||
| if (m2.isTempoMetaEvent()) | |||
| secsPerTick = tickLen * m2.getTempoSecondsPerQuarterNote(); | |||
| else if (m2.isTimeSignatureMetaEvent()) | |||
| m2.getTimeSignatureInfo (numer, denom); | |||
| } | |||
| else | |||
| { | |||
| if (m2.getTimeStamp() != eventTime) | |||
| break; | |||
| } | |||
| if (m2.isTempoMetaEvent()) | |||
| secsPerTick = tickLen * m2.getTempoSecondsPerQuarterNote(); | |||
| ++i; | |||
| } | |||
| } | |||
| return correctedTempoTime + (time - tempoTime) * secsPerTick; | |||
| return correctedTime + (time - lastTime) * secsPerTick; | |||
| } | |||
| else | |||
| { | |||
| @@ -180,7 +164,6 @@ MidiFile::MidiFile() | |||
| MidiFile::~MidiFile() | |||
| { | |||
| clear(); | |||
| } | |||
| void MidiFile::clear() | |||
| @@ -296,9 +279,7 @@ bool MidiFile::readFrom (InputStream& sourceStream) | |||
| break; | |||
| if (chunkType == (int) ByteOrder::bigEndianInt ("MTrk")) | |||
| { | |||
| readNextTrack (d, chunkSize); | |||
| } | |||
| size -= chunkSize + 8; | |||
| d += chunkSize; | |||
| @@ -315,7 +296,7 @@ bool MidiFile::readFrom (InputStream& sourceStream) | |||
| void MidiFile::readNextTrack (const uint8* data, int size) | |||
| { | |||
| double time = 0; | |||
| char lastStatusByte = 0; | |||
| uint8 lastStatusByte = 0; | |||
| MidiMessageSequence result; | |||
| @@ -338,7 +319,7 @@ void MidiFile::readNextTrack (const uint8* data, int size) | |||
| result.addEvent (mm); | |||
| const char firstByte = *(mm.getRawData()); | |||
| const uint8 firstByte = *(mm.getRawData()); | |||
| if ((firstByte & 0xf0) != 0xf0) | |||
| lastStatusByte = firstByte; | |||
| } | |||
| @@ -361,7 +342,7 @@ void MidiFile::convertTimestampTicksToSeconds() | |||
| for (int i = 0; i < tracks.size(); ++i) | |||
| { | |||
| MidiMessageSequence& ms = *tracks.getUnchecked(i); | |||
| const MidiMessageSequence& ms = *tracks.getUnchecked(i); | |||
| for (int j = ms.getNumEvents(); --j >= 0;) | |||
| { | |||
| @@ -393,11 +374,10 @@ bool MidiFile::writeTo (OutputStream& out) | |||
| void MidiFile::writeTrack (OutputStream& mainOut, const int trackNum) | |||
| { | |||
| MemoryOutputStream out; | |||
| const MidiMessageSequence& ms = *tracks[trackNum]; | |||
| const MidiMessageSequence& ms = *tracks.getUnchecked (trackNum); | |||
| int lastTick = 0; | |||
| char lastStatusByte = 0; | |||
| uint8 lastStatusByte = 0; | |||
| for (int i = 0; i < ms.getNumEvents(); ++i) | |||
| { | |||
| @@ -408,27 +388,30 @@ void MidiFile::writeTrack (OutputStream& mainOut, const int trackNum) | |||
| MidiFileHelpers::writeVariableLengthInt (out, delta); | |||
| lastTick = tick; | |||
| const char statusByte = *(mm.getRawData()); | |||
| const uint8* data = mm.getRawData(); | |||
| int dataSize = mm.getRawDataSize(); | |||
| if ((statusByte == lastStatusByte) | |||
| && ((statusByte & 0xf0) != 0xf0) | |||
| && i > 0 | |||
| && mm.getRawDataSize() > 1) | |||
| { | |||
| out.write (mm.getRawData() + 1, mm.getRawDataSize() - 1); | |||
| } | |||
| else | |||
| const uint8 statusByte = data[0]; | |||
| if (statusByte == lastStatusByte | |||
| && (statusByte & 0xf0) != 0xf0 | |||
| && dataSize > 1 | |||
| && i > 0) | |||
| { | |||
| out.write (mm.getRawData(), mm.getRawDataSize()); | |||
| ++data; | |||
| --dataSize; | |||
| } | |||
| out.write (data, dataSize); | |||
| lastStatusByte = statusByte; | |||
| } | |||
| out.writeByte (0); | |||
| const MidiMessage m (MidiMessage::endOfTrack()); | |||
| out.write (m.getRawData(), | |||
| m.getRawDataSize()); | |||
| { | |||
| const MidiMessage m (MidiMessage::endOfTrack()); | |||
| out.write (m.getRawData(), m.getRawDataSize()); | |||
| } | |||
| mainOut.writeIntBigEndian ((int) ByteOrder::bigEndianInt ("MTrk")); | |||
| mainOut.writeIntBigEndian ((int) out.getDataSize()); | |||
| @@ -106,26 +106,18 @@ int MidiMessageSequence::getNextIndexAtTime (const double timeStamp) const | |||
| //============================================================================== | |||
| double MidiMessageSequence::getStartTime() const | |||
| { | |||
| if (list.size() > 0) | |||
| return list.getUnchecked(0)->message.getTimeStamp(); | |||
| else | |||
| return 0; | |||
| return getEventTime (0); | |||
| } | |||
| double MidiMessageSequence::getEndTime() const | |||
| { | |||
| if (list.size() > 0) | |||
| return list.getLast()->message.getTimeStamp(); | |||
| else | |||
| return 0; | |||
| return getEventTime (list.size() - 1); | |||
| } | |||
| double MidiMessageSequence::getEventTime (const int index) const | |||
| { | |||
| if (isPositiveAndBelow (index, list.size())) | |||
| return list.getUnchecked (index)->message.getTimeStamp(); | |||
| return 0.0; | |||
| const MidiEventHolder* const e = list [index]; | |||
| return e != nullptr ? e->message.getTimeStamp() : 0.0; | |||
| } | |||
| //============================================================================== | |||
| @@ -157,6 +149,16 @@ void MidiMessageSequence::deleteEvent (const int index, | |||
| } | |||
| } | |||
| struct MidiMessageSequenceSorter | |||
| { | |||
| static int compareElements (const MidiMessageSequence::MidiEventHolder* const first, | |||
| const MidiMessageSequence::MidiEventHolder* const second) noexcept | |||
| { | |||
| const double diff = first->message.getTimeStamp() - second->message.getTimeStamp(); | |||
| return (diff > 0) - (diff < 0); | |||
| } | |||
| }; | |||
| void MidiMessageSequence::addSequence (const MidiMessageSequence& other, | |||
| double timeAdjustment, | |||
| double firstAllowableTime, | |||
| @@ -179,22 +181,8 @@ void MidiMessageSequence::addSequence (const MidiMessageSequence& other, | |||
| } | |||
| } | |||
| sort(); | |||
| } | |||
| //============================================================================== | |||
| int MidiMessageSequence::compareElements (const MidiMessageSequence::MidiEventHolder* const first, | |||
| const MidiMessageSequence::MidiEventHolder* const second) noexcept | |||
| { | |||
| const double diff = first->message.getTimeStamp() | |||
| - second->message.getTimeStamp(); | |||
| return (diff > 0) - (diff < 0); | |||
| } | |||
| void MidiMessageSequence::sort() | |||
| { | |||
| list.sort (*this, true); | |||
| MidiMessageSequenceSorter sorter; | |||
| list.sort (sorter, true); | |||
| } | |||
| //============================================================================== | |||
| @@ -264,18 +264,11 @@ public: | |||
| /** Swaps this sequence with another one. */ | |||
| void swapWith (MidiMessageSequence& other) noexcept; | |||
| //============================================================================== | |||
| /** @internal */ | |||
| static int compareElements (const MidiMessageSequence::MidiEventHolder* first, | |||
| const MidiMessageSequence::MidiEventHolder* second) noexcept; | |||
| private: | |||
| //============================================================================== | |||
| friend class MidiFile; | |||
| OwnedArray <MidiEventHolder> list; | |||
| void sort(); | |||
| JUCE_LEAK_DETECTOR (MidiMessageSequence); | |||
| }; | |||
| @@ -25,6 +25,13 @@ | |||
| BEGIN_JUCE_NAMESPACE | |||
| //============================================================================== | |||
| namespace | |||
| { | |||
| inline size_t bitToIndex (const int bit) noexcept { return (size_t) (bit >> 5); } | |||
| inline uint32 bitToMask (const int bit) noexcept { return (uint32) 1 << (bit & 31); } | |||
| } | |||
| //============================================================================== | |||
| BigInteger::BigInteger() | |||
| : numValues (4), | |||
| @@ -783,7 +790,7 @@ void BigInteger::shiftBits (int bits, const int startBit) | |||
| } | |||
| //============================================================================== | |||
| BigInteger BigInteger::simpleGCD (BigInteger* m, BigInteger* n) | |||
| static BigInteger simpleGCD (BigInteger* m, BigInteger* n) | |||
| { | |||
| while (! m->isZero()) | |||
| { | |||
| @@ -319,10 +319,6 @@ private: | |||
| void ensureSize (size_t numVals); | |||
| void shiftLeft (int bits, int startBit); | |||
| void shiftRight (int bits, int startBit); | |||
| static BigInteger simpleGCD (BigInteger* m, BigInteger* n); | |||
| static inline size_t bitToIndex (const int bit) noexcept { return (size_t) (bit >> 5); } | |||
| static inline uint32 bitToMask (const int bit) noexcept { return (uint32) 1 << (bit & 31); } | |||
| JUCE_LEAK_DETECTOR (BigInteger); | |||
| }; | |||
| @@ -265,7 +265,7 @@ private: | |||
| friend class ReferenceCountedObjectPtr<Term>; | |||
| ReferenceCountedObjectPtr<Term> term; | |||
| explicit Expression (Term* term); | |||
| explicit Expression (Term*); | |||
| }; | |||
| #endif // __JUCE_EXPRESSION_JUCEHEADER__ | |||
| @@ -288,7 +288,6 @@ private: | |||
| bool volatile threadShouldExit_; | |||
| #ifndef DOXYGEN | |||
| friend class MessageManager; | |||
| friend void JUCE_API juce_threadEntryPoint (void*); | |||
| #endif | |||
| @@ -296,7 +295,7 @@ private: | |||
| void closeThreadHandle(); | |||
| void killThread(); | |||
| void threadEntryPoint(); | |||
| static bool setThreadPriority (void* handle, int priority); | |||
| static bool setThreadPriority (void*, int priority); | |||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Thread); | |||
| }; | |||