From 8233f9a987ab01f4fdc95938807f3995fdb56e4e Mon Sep 17 00:00:00 2001 From: falkTX Date: Sun, 9 Sep 2018 11:18:29 +0200 Subject: [PATCH] Replace BigInteger with a bool array in Synthesizer class --- source/modules/water/maths/BigInteger.cpp | 245 ------------------ source/modules/water/maths/BigInteger.h | 118 --------- .../water/synthesisers/Synthesiser.cpp | 15 +- .../modules/water/synthesisers/Synthesiser.h | 3 +- source/modules/water/water.cpp | 2 - 5 files changed, 10 insertions(+), 373 deletions(-) delete mode 100644 source/modules/water/maths/BigInteger.cpp delete mode 100644 source/modules/water/maths/BigInteger.h diff --git a/source/modules/water/maths/BigInteger.cpp b/source/modules/water/maths/BigInteger.cpp deleted file mode 100644 index d3a8b925c..000000000 --- a/source/modules/water/maths/BigInteger.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library. - Copyright (c) 2016 ROLI Ltd. - Copyright (C) 2018 Filipe Coelho - - Permission is granted to use this software under the terms of the ISC license - http://www.isc.org/downloads/software-support-policy/isc-license/ - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, - OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF - USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - OF THIS SOFTWARE. - - ============================================================================== -*/ - -#include "BigInteger.h" - -namespace water -{ - -inline uint32 bitToMask (const int bit) noexcept { return (uint32) 1 << (bit & 31); } -inline size_t bitToIndex (const int bit) noexcept { return (size_t) (bit >> 5); } -inline size_t sizeNeededToHold (int highestBit) noexcept { return (size_t) (highestBit >> 5) + 1; } - -int findHighestSetBit (uint32 n) noexcept -{ - jassert (n != 0); // (the built-in functions may not work for n = 0) - - #if defined(__GNUC__) || defined(__clang__) - return 31 - __builtin_clz (n); - #elif _MSVC_VER - unsigned long highest; - _BitScanReverse (&highest, n); - return (int) highest; - #else - n |= (n >> 1); - n |= (n >> 2); - n |= (n >> 4); - n |= (n >> 8); - n |= (n >> 16); - return countNumberOfBits (n >> 1); - #endif -} - - -//============================================================================== -BigInteger::BigInteger() noexcept - : allocatedSize (numPreallocatedInts), - highestBit (-1) -{ - for (int i = 0; i < numPreallocatedInts; ++i) - preallocated[i] = 0; -} - -BigInteger::BigInteger (const int32 value) noexcept - : allocatedSize (numPreallocatedInts), - highestBit (31) -{ - preallocated[0] = (uint32) std::abs (value); - - for (int i = 1; i < numPreallocatedInts; ++i) - preallocated[i] = 0; - - highestBit = getHighestBit(); -} - -BigInteger::BigInteger (const uint32 value) noexcept - : allocatedSize (numPreallocatedInts), - highestBit (31) -{ - preallocated[0] = value; - - for (int i = 1; i < numPreallocatedInts; ++i) - preallocated[i] = 0; - - highestBit = getHighestBit(); -} - -BigInteger::BigInteger (int64 value) noexcept - : allocatedSize (numPreallocatedInts), - highestBit (63) -{ - if (value < 0) - value = -value; - - preallocated[0] = (uint32) value; - preallocated[1] = (uint32) (value >> 32); - - for (int i = 2; i < numPreallocatedInts; ++i) - preallocated[i] = 0; - - highestBit = getHighestBit(); -} - -#if WATER_COMPILER_SUPPORTS_MOVE_SEMANTICS -BigInteger::BigInteger (BigInteger&& other) noexcept - : heapAllocation (static_cast&&> (other.heapAllocation)), - allocatedSize (other.allocatedSize), - highestBit (other.highestBit) -{ - std::memcpy (preallocated, other.preallocated, sizeof (preallocated)); -} - -BigInteger& BigInteger::operator= (BigInteger&& other) noexcept -{ - heapAllocation = static_cast&&> (other.heapAllocation); - std::memcpy (preallocated, other.preallocated, sizeof (preallocated)); - allocatedSize = other.allocatedSize; - highestBit = other.highestBit; - return *this; -} -#endif - -BigInteger::~BigInteger() noexcept -{ -} - -uint32* BigInteger::getValues() const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(heapAllocation != nullptr || allocatedSize <= numPreallocatedInts, nullptr); - - return heapAllocation != nullptr ? heapAllocation - : (uint32*) preallocated; -} - -uint32* BigInteger::ensureSize (const size_t numVals) noexcept -{ - if (numVals <= allocatedSize) - return getValues(); - - size_t oldSize = allocatedSize; - allocatedSize = ((numVals + 2) * 3) / 2; - - if (heapAllocation == nullptr) - { - CARLA_SAFE_ASSERT_RETURN(heapAllocation.calloc (allocatedSize), nullptr); - std::memcpy (heapAllocation, preallocated, sizeof (uint32) * numPreallocatedInts); - } - else - { - CARLA_SAFE_ASSERT_RETURN(heapAllocation.realloc (allocatedSize), nullptr); - - for (uint32* values = heapAllocation; oldSize < allocatedSize; ++oldSize) - values[oldSize] = 0; - } - - return heapAllocation; -} - -//============================================================================== -bool BigInteger::operator[] (const int bit) const noexcept -{ - if (bit < 0 || bit > highestBit) - return false; - - if (const uint32* const values = getValues()) - return (values [bitToIndex (bit)] & bitToMask (bit)) != 0; - - return false; -} - -//============================================================================== -void BigInteger::clear() noexcept -{ - heapAllocation.free(); - allocatedSize = numPreallocatedInts; - highestBit = -1; - - for (int i = 0; i < numPreallocatedInts; ++i) - preallocated[i] = 0; -} - -bool BigInteger::setBit (const int bit) noexcept -{ - if (bit < 0) - return false; - - CARLA_SAFE_ASSERT_RETURN(bit >= 0, false); - - if (bit > highestBit) - { - if (ensureSize (sizeNeededToHold (bit)) == nullptr) - return false; - - highestBit = bit; - } - - if (uint32* const values = getValues()) - return values [bitToIndex (bit)] |= bitToMask (bit); - - return false; -} - -bool BigInteger::setBit (const int bit, const bool shouldBeSet) noexcept -{ - if (shouldBeSet) - { - return setBit (bit); - } - else - { - clearBit (bit); - return true; - } -} - -bool BigInteger::clearBit (const int bit) noexcept -{ - if (bit < 0 || bit > highestBit) - return false; - - uint32* const values = getValues(); - CARLA_SAFE_ASSERT_RETURN(values != nullptr, false); - - values [bitToIndex (bit)] &= ~bitToMask (bit); - - if (bit == highestBit) - highestBit = getHighestBit(); - - return true; -} - -int BigInteger::getHighestBit() const noexcept -{ - const uint32* values = getValues(); - CARLA_SAFE_ASSERT_RETURN(values != nullptr, -1); - - for (int i = (int) bitToIndex (highestBit); i >= 0; --i) - if (uint32 n = values[i]) - return findHighestSetBit (n) + (i << 5); - - return -1; -} - -} diff --git a/source/modules/water/maths/BigInteger.h b/source/modules/water/maths/BigInteger.h deleted file mode 100644 index 1b5d2fd44..000000000 --- a/source/modules/water/maths/BigInteger.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - ============================================================================== - - This file is part of the Water library. - Copyright (c) 2016 ROLI Ltd. - Copyright (C) 2018 Filipe Coelho - - Permission is granted to use this software under the terms of the ISC license - http://www.isc.org/downloads/software-support-policy/isc-license/ - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD - TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, - OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF - USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE - OF THIS SOFTWARE. - - ============================================================================== -*/ - -#ifndef WATER_BIGINTEGER_H_INCLUDED -#define WATER_BIGINTEGER_H_INCLUDED - -#include "../memory/HeapBlock.h" - -#include "CarlaJuceUtils.hpp" - -namespace water { - -//============================================================================== -/** - An arbitrarily large integer class. - - A BigInteger can be used in a similar way to a normal integer, but has no size - limit (except for memory and performance constraints). - - Negative values are possible, but the value isn't stored as 2s-complement, so - be careful if you use negative values and look at the values of individual bits. -*/ -class BigInteger -{ -public: - //============================================================================== - /** Creates an empty BigInteger */ - BigInteger() noexcept; - - /** Creates a BigInteger containing an integer value in its low bits. - The low 32 bits of the number are initialised with this value. - */ - BigInteger (uint32 value) noexcept; - - /** Creates a BigInteger containing an integer value in its low bits. - The low 32 bits of the number are initialised with the absolute value - passed in, and its sign is set to reflect the sign of the number. - */ - BigInteger (int32 value) noexcept; - - /** Creates a BigInteger containing an integer value in its low bits. - The low 64 bits of the number are initialised with the absolute value - passed in, and its sign is set to reflect the sign of the number. - */ - BigInteger (int64 value) noexcept; - - #if WATER_COMPILER_SUPPORTS_MOVE_SEMANTICS - BigInteger (BigInteger&&) noexcept; - BigInteger& operator= (BigInteger&&) noexcept; - #endif - - /** Destructor. */ - ~BigInteger() noexcept; - - //============================================================================== - /** Returns the value of a specified bit in the number. - If the index is out-of-range, the result will be false. - */ - bool operator[] (int bit) const noexcept; - - //============================================================================== - /** Resets the value to 0. */ - void clear() noexcept; - - /** Clears a particular bit in the number. */ - bool clearBit (int bitNumber) noexcept; - - /** Sets a specified bit to 1. */ - bool setBit (int bitNumber) noexcept; - - /** Sets or clears a specified bit. */ - bool setBit (int bitNumber, bool shouldBeSet) noexcept; - - //============================================================================== - /** Returns the index of the highest set bit in the number. - If the value is zero, this will return -1. - */ - int getHighestBit() const noexcept; - -private: - //============================================================================== - enum { numPreallocatedInts = 4 }; - HeapBlock heapAllocation; - uint32 preallocated[numPreallocatedInts]; - size_t allocatedSize; - int highestBit; - - uint32* getValues() const noexcept; - uint32* ensureSize (size_t) noexcept; - - CARLA_LEAK_DETECTOR (BigInteger) -}; - -} - -#endif // WATER_BIGINTEGER_H_INCLUDED diff --git a/source/modules/water/synthesisers/Synthesiser.cpp b/source/modules/water/synthesisers/Synthesiser.cpp index 2f909a3c9..4b3c4c19b 100644 --- a/source/modules/water/synthesisers/Synthesiser.cpp +++ b/source/modules/water/synthesisers/Synthesiser.cpp @@ -92,6 +92,8 @@ Synthesiser::Synthesiser() { for (int i = 0; i < numElementsInArray (lastPitchWheelValues); ++i) lastPitchWheelValues[i] = 0x2000; + + zerostruct(sustainPedalsDown); } Synthesiser::~Synthesiser() @@ -303,6 +305,8 @@ void Synthesiser::startVoice (SynthesiserVoice* const voice, { if (voice != nullptr && sound != nullptr) { + CARLA_SAFE_ASSERT_RETURN(midiChannel > 0 && midiChannel <= 16,); + if (voice->currentlyPlayingSound != nullptr) voice->stopNote (0.0f, false); @@ -334,6 +338,7 @@ void Synthesiser::noteOff (const int midiChannel, const float velocity, const bool allowTailOff) { + CARLA_SAFE_ASSERT_RETURN(midiChannel > 0 && midiChannel <= 16,); for (int i = voices.size(); --i >= 0;) { @@ -361,7 +366,6 @@ void Synthesiser::noteOff (const int midiChannel, void Synthesiser::allNotesOff (const int midiChannel, const bool allowTailOff) { - for (int i = voices.size(); --i >= 0;) { SynthesiserVoice* const voice = voices.getUnchecked (i); @@ -370,12 +374,11 @@ void Synthesiser::allNotesOff (const int midiChannel, const bool allowTailOff) voice->stopNote (1.0f, allowTailOff); } - sustainPedalsDown.clear(); + zerostruct(sustainPedalsDown); } void Synthesiser::handlePitchWheel (const int midiChannel, const int wheelValue) { - for (int i = voices.size(); --i >= 0;) { SynthesiserVoice* const voice = voices.getUnchecked (i); @@ -434,11 +437,11 @@ void Synthesiser::handleChannelPressure (int midiChannel, int channelPressureVal void Synthesiser::handleSustainPedal (int midiChannel, bool isDown) { - jassert (midiChannel > 0 && midiChannel <= 16); + CARLA_SAFE_ASSERT_RETURN(midiChannel > 0 && midiChannel <= 16,); if (isDown) { - sustainPedalsDown.setBit (midiChannel); + sustainPedalsDown[midiChannel] = true; for (int i = voices.size(); --i >= 0;) { @@ -463,7 +466,7 @@ void Synthesiser::handleSustainPedal (int midiChannel, bool isDown) } } - sustainPedalsDown.clearBit (midiChannel); + sustainPedalsDown[midiChannel] = false; } } diff --git a/source/modules/water/synthesisers/Synthesiser.h b/source/modules/water/synthesisers/Synthesiser.h index e32221ec2..b57a45da6 100644 --- a/source/modules/water/synthesisers/Synthesiser.h +++ b/source/modules/water/synthesisers/Synthesiser.h @@ -29,7 +29,6 @@ #include "../buffers/AudioSampleBuffer.h" #include "../containers/OwnedArray.h" #include "../containers/ReferenceCountedArray.h" -#include "../maths/BigInteger.h" #include "CarlaJuceUtils.hpp" #include "CarlaMutex.hpp" @@ -613,7 +612,7 @@ private: int minimumSubBlockSize; bool subBlockSubdivisionIsStrict; bool shouldStealNotes; - BigInteger sustainPedalsDown; + bool sustainPedalsDown[17]; CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Synthesiser) }; diff --git a/source/modules/water/water.cpp b/source/modules/water/water.cpp index a7d10e12b..6e32e0185 100644 --- a/source/modules/water/water.cpp +++ b/source/modules/water/water.cpp @@ -45,8 +45,6 @@ HINSTANCE water_getCurrentModuleInstanceHandle() noexcept #include "files/FileOutputStream.cpp" #include "files/TemporaryFile.cpp" -#include "maths/BigInteger.cpp" - #include "maths/Random.cpp" #include "memory/MemoryBlock.cpp"