| @@ -192,6 +192,7 @@ public: | |||||
| } | } | ||||
| /** Copies another buffer onto this one. | /** Copies another buffer onto this one. | ||||
| This buffer's size will be changed to that of the other buffer. | This buffer's size will be changed to that of the other buffer. | ||||
| */ | */ | ||||
| AudioBuffer& operator= (const AudioBuffer& other) | AudioBuffer& operator= (const AudioBuffer& other) | ||||
| @@ -217,11 +218,12 @@ public: | |||||
| } | } | ||||
| /** Destructor. | /** Destructor. | ||||
| This will free any memory allocated by the buffer. | This will free any memory allocated by the buffer. | ||||
| */ | */ | ||||
| ~AudioBuffer() = default; | ~AudioBuffer() = default; | ||||
| /** Move constructor */ | |||||
| /** Move constructor. */ | |||||
| AudioBuffer (AudioBuffer&& other) noexcept | AudioBuffer (AudioBuffer&& other) noexcept | ||||
| : numChannels (other.numChannels), | : numChannels (other.numChannels), | ||||
| size (other.size), | size (other.size), | ||||
| @@ -246,7 +248,7 @@ public: | |||||
| other.allocatedBytes = 0; | other.allocatedBytes = 0; | ||||
| } | } | ||||
| /** Move assignment */ | |||||
| /** Move assignment. */ | |||||
| AudioBuffer& operator= (AudioBuffer&& other) noexcept | AudioBuffer& operator= (AudioBuffer&& other) noexcept | ||||
| { | { | ||||
| numChannels = other.numChannels; | numChannels = other.numChannels; | ||||
| @@ -275,18 +277,22 @@ public: | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the number of channels of audio data that this buffer contains. | /** Returns the number of channels of audio data that this buffer contains. | ||||
| @see getNumSamples, getReadPointer, getWritePointer | @see getNumSamples, getReadPointer, getWritePointer | ||||
| */ | */ | ||||
| int getNumChannels() const noexcept { return numChannels; } | int getNumChannels() const noexcept { return numChannels; } | ||||
| /** Returns the number of samples allocated in each of the buffer's channels. | /** Returns the number of samples allocated in each of the buffer's channels. | ||||
| @see getNumChannels, getReadPointer, getWritePointer | @see getNumChannels, getReadPointer, getWritePointer | ||||
| */ | */ | ||||
| int getNumSamples() const noexcept { return size; } | int getNumSamples() const noexcept { return size; } | ||||
| /** Returns a pointer to an array of read-only samples in one of the buffer's channels. | /** Returns a pointer to an array of read-only samples in one of the buffer's channels. | ||||
| For speed, this doesn't check whether the channel number is out of range, | For speed, this doesn't check whether the channel number is out of range, | ||||
| so be careful when using it! | so be careful when using it! | ||||
| If you need to write to the data, do NOT call this method and const_cast the | If you need to write to the data, do NOT call this method and const_cast the | ||||
| result! Instead, you must call getWritePointer so that the buffer knows you're | result! Instead, you must call getWritePointer so that the buffer knows you're | ||||
| planning on modifying the data. | planning on modifying the data. | ||||
| @@ -298,8 +304,10 @@ public: | |||||
| } | } | ||||
| /** Returns a pointer to an array of read-only samples in one of the buffer's channels. | /** Returns a pointer to an array of read-only samples in one of the buffer's channels. | ||||
| For speed, this doesn't check whether the channel number or index are out of range, | For speed, this doesn't check whether the channel number or index are out of range, | ||||
| so be careful when using it! | so be careful when using it! | ||||
| If you need to write to the data, do NOT call this method and const_cast the | If you need to write to the data, do NOT call this method and const_cast the | ||||
| result! Instead, you must call getWritePointer so that the buffer knows you're | result! Instead, you must call getWritePointer so that the buffer knows you're | ||||
| planning on modifying the data. | planning on modifying the data. | ||||
| @@ -312,10 +320,20 @@ public: | |||||
| } | } | ||||
| /** Returns a writeable pointer to one of the buffer's channels. | /** Returns a writeable pointer to one of the buffer's channels. | ||||
| For speed, this doesn't check whether the channel number is out of range, | For speed, this doesn't check whether the channel number is out of range, | ||||
| so be careful when using it! | so be careful when using it! | ||||
| Note that if you're not planning on writing to the data, you should always | Note that if you're not planning on writing to the data, you should always | ||||
| use getReadPointer instead. | use getReadPointer instead. | ||||
| This will mark the buffer as not cleared and the hasBeenCleared method will return | |||||
| false after this call. If you retain this write pointer and write some data to | |||||
| the buffer after calling its clear method, subsequent clear calls will do nothing. | |||||
| To avoid this either call this method each time you need to write data, or use the | |||||
| setNotClear method to force the internal cleared flag to false. | |||||
| @see setNotClear | |||||
| */ | */ | ||||
| Type* getWritePointer (int channelNumber) noexcept | Type* getWritePointer (int channelNumber) noexcept | ||||
| { | { | ||||
| @@ -325,10 +343,20 @@ public: | |||||
| } | } | ||||
| /** Returns a writeable pointer to one of the buffer's channels. | /** Returns a writeable pointer to one of the buffer's channels. | ||||
| For speed, this doesn't check whether the channel number or index are out of range, | For speed, this doesn't check whether the channel number or index are out of range, | ||||
| so be careful when using it! | so be careful when using it! | ||||
| Note that if you're not planning on writing to the data, you should | Note that if you're not planning on writing to the data, you should | ||||
| use getReadPointer instead. | use getReadPointer instead. | ||||
| This will mark the buffer as not cleared and the hasBeenCleared method will return | |||||
| false after this call. If you retain this write pointer and write some data to | |||||
| the buffer after calling its clear method, subsequent clear calls will do nothing. | |||||
| To avoid this either call this method each time you need to write data, or use the | |||||
| setNotClear method to force the internal cleared flag to false. | |||||
| @see setNotClear | |||||
| */ | */ | ||||
| Type* getWritePointer (int channelNumber, int sampleIndex) noexcept | Type* getWritePointer (int channelNumber, int sampleIndex) noexcept | ||||
| { | { | ||||
| @@ -349,6 +377,14 @@ public: | |||||
| Don't modify any of the pointers that are returned, and bear in mind that | Don't modify any of the pointers that are returned, and bear in mind that | ||||
| these will become invalid if the buffer is resized. | these will become invalid if the buffer is resized. | ||||
| This will mark the buffer as not cleared and the hasBeenCleared method will return | |||||
| false after this call. If you retain this write pointer and write some data to | |||||
| the buffer after calling its clear method, subsequent clear calls will do nothing. | |||||
| To avoid this either call this method each time you need to write data, or use the | |||||
| setNotClear method to force the internal cleared flag to false. | |||||
| @see setNotClear | |||||
| */ | */ | ||||
| Type** getArrayOfWritePointers() noexcept { isClear = false; return channels; } | Type** getArrayOfWritePointers() noexcept { isClear = false; return channels; } | ||||
| @@ -357,23 +393,23 @@ public: | |||||
| This can expand or contract the buffer's length, and add or remove channels. | This can expand or contract the buffer's length, and add or remove channels. | ||||
| If keepExistingContent is true, it will try to preserve as much of the | |||||
| old data as it can in the new buffer. | |||||
| If clearExtraSpace is true, then any extra channels or space that is | |||||
| allocated will be also be cleared. If false, then this space is left | |||||
| uninitialised. | |||||
| If avoidReallocating is true, then changing the buffer's size won't reduce the | |||||
| amount of memory that is currently allocated (but it will still increase it if | |||||
| the new size is bigger than the amount it currently has). If this is false, then | |||||
| a new allocation will be done so that the buffer uses takes up the minimum amount | |||||
| of memory that it needs. | |||||
| Note that if keepExistingContent and avoidReallocating are both true, then it will | Note that if keepExistingContent and avoidReallocating are both true, then it will | ||||
| only avoid reallocating if neither the channel count or length in samples increase. | only avoid reallocating if neither the channel count or length in samples increase. | ||||
| If the required memory can't be allocated, this will throw a std::bad_alloc exception. | If the required memory can't be allocated, this will throw a std::bad_alloc exception. | ||||
| @param newNumChannels the new number of channels. | |||||
| @param newNumSamples the new number of samples. | |||||
| @param keepExistingContent if this is true, it will try to preserve as much of the | |||||
| old data as it can in the new buffer. | |||||
| @param clearExtraSpace if this is true, then any extra channels or space that is | |||||
| allocated will be also be cleared. If false, then this space is left | |||||
| uninitialised. | |||||
| @param avoidReallocating if this is true, then changing the buffer's size won't reduce the | |||||
| amount of memory that is currently allocated (but it will still | |||||
| increase it if the new size is bigger than the amount it currently has). | |||||
| If this is false, then a new allocation will be done so that the buffer | |||||
| uses takes up the minimum amount of memory that it needs. | |||||
| */ | */ | ||||
| void setSize (int newNumChannels, | void setSize (int newNumChannels, | ||||
| int newNumSamples, | int newNumSamples, | ||||
| @@ -464,6 +500,8 @@ public: | |||||
| will re-allocate memory internally and copy the existing data to this new area, | will re-allocate memory internally and copy the existing data to this new area, | ||||
| so it will then stop directly addressing this memory. | so it will then stop directly addressing this memory. | ||||
| The hasBeenCleared method will return false after this call. | |||||
| @param dataToReferTo a pre-allocated array containing pointers to the data | @param dataToReferTo a pre-allocated array containing pointers to the data | ||||
| for each channel that should be used by this buffer. The | for each channel that should be used by this buffer. The | ||||
| buffer will only refer to this memory, it won't try to delete | buffer will only refer to this memory, it won't try to delete | ||||
| @@ -504,6 +542,8 @@ public: | |||||
| will re-allocate memory internally and copy the existing data to this new area, | will re-allocate memory internally and copy the existing data to this new area, | ||||
| so it will then stop directly addressing this memory. | so it will then stop directly addressing this memory. | ||||
| The hasBeenCleared method will return false after this call. | |||||
| @param dataToReferTo a pre-allocated array containing pointers to the data | @param dataToReferTo a pre-allocated array containing pointers to the data | ||||
| for each channel that should be used by this buffer. The | for each channel that should be used by this buffer. The | ||||
| buffer will only refer to this memory, it won't try to delete | buffer will only refer to this memory, it won't try to delete | ||||
| @@ -521,8 +561,12 @@ public: | |||||
| } | } | ||||
| /** Resizes this buffer to match the given one, and copies all of its content across. | /** Resizes this buffer to match the given one, and copies all of its content across. | ||||
| The source buffer can contain a different floating point type, so this can be used to | The source buffer can contain a different floating point type, so this can be used to | ||||
| convert between 32 and 64 bit float buffer types. | convert between 32 and 64 bit float buffer types. | ||||
| The hasBeenCleared method will return false after this call if the other buffer | |||||
| contains data. | |||||
| */ | */ | ||||
| template <typename OtherType> | template <typename OtherType> | ||||
| void makeCopyOf (const AudioBuffer<OtherType>& other, bool avoidReallocating = false) | void makeCopyOf (const AudioBuffer<OtherType>& other, bool avoidReallocating = false) | ||||
| @@ -549,7 +593,13 @@ public: | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| /** Clears all the samples in all channels. */ | |||||
| /** Clears all the samples in all channels and marks the buffer as cleared. | |||||
| This method will do nothing if the buffer has been marked as cleared (i.e. the | |||||
| hasBeenCleared method returns true.) | |||||
| @see hasBeenCleared, setNotClear | |||||
| */ | |||||
| void clear() noexcept | void clear() noexcept | ||||
| { | { | ||||
| if (! isClear) | if (! isClear) | ||||
| @@ -563,8 +613,15 @@ public: | |||||
| /** Clears a specified region of all the channels. | /** Clears a specified region of all the channels. | ||||
| This will mark the buffer as cleared if the entire buffer contents are cleared. | |||||
| For speed, this doesn't check whether the channel and sample number | For speed, this doesn't check whether the channel and sample number | ||||
| are in-range, so be careful! | are in-range, so be careful! | ||||
| This method will do nothing if the buffer has been marked as cleared (i.e. the | |||||
| hasBeenCleared method returns true.) | |||||
| @see hasBeenCleared, setNotClear | |||||
| */ | */ | ||||
| void clear (int startSample, int numSamples) noexcept | void clear (int startSample, int numSamples) noexcept | ||||
| { | { | ||||
| @@ -572,11 +629,10 @@ public: | |||||
| if (! isClear) | if (! isClear) | ||||
| { | { | ||||
| if (startSample == 0 && numSamples == size) | |||||
| isClear = true; | |||||
| for (int i = 0; i < numChannels; ++i) | for (int i = 0; i < numChannels; ++i) | ||||
| FloatVectorOperations::clear (channels[i] + startSample, numSamples); | FloatVectorOperations::clear (channels[i] + startSample, numSamples); | ||||
| isClear = (startSample == 0 && numSamples == size); | |||||
| } | } | ||||
| } | } | ||||
| @@ -584,6 +640,11 @@ public: | |||||
| For speed, this doesn't check whether the channel and sample number | For speed, this doesn't check whether the channel and sample number | ||||
| are in-range, so be careful! | are in-range, so be careful! | ||||
| This method will do nothing if the buffer has been marked as cleared (i.e. the | |||||
| hasBeenCleared method returns true.) | |||||
| @see hasBeenCleared, setNotClear | |||||
| */ | */ | ||||
| void clear (int channel, int startSample, int numSamples) noexcept | void clear (int channel, int startSample, int numSamples) noexcept | ||||
| { | { | ||||
| @@ -595,15 +656,26 @@ public: | |||||
| } | } | ||||
| /** Returns true if the buffer has been entirely cleared. | /** Returns true if the buffer has been entirely cleared. | ||||
| Note that this does not actually measure the contents of the buffer - it simply | Note that this does not actually measure the contents of the buffer - it simply | ||||
| returns a flag that is set when the buffer is cleared, and which is reset whenever | returns a flag that is set when the buffer is cleared, and which is reset whenever | ||||
| functions like getWritePointer() are invoked. That means the method does not take | |||||
| any time, but it may return false negatives when in fact the buffer is still empty. | |||||
| functions like getWritePointer are invoked. That means the method is quick, but it | |||||
| may return false negatives when in fact the buffer is still empty. | |||||
| */ | */ | ||||
| bool hasBeenCleared() const noexcept { return isClear; } | bool hasBeenCleared() const noexcept { return isClear; } | ||||
| /** Forces the internal cleared flag of the buffer to false. | |||||
| This may be useful in the case where you are holding on to a write pointer and call | |||||
| the clear method before writing some data. You can then use this method to mark the | |||||
| buffer as containing data so that subsequent clear calls will succeed. However a | |||||
| better solution is to call getWritePointer each time you need to write data. | |||||
| */ | |||||
| void setNotClear() noexcept { isClear = false; } | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns a sample from the buffer. | /** Returns a sample from the buffer. | ||||
| The channel and index are not checked - they are expected to be in-range. If not, | The channel and index are not checked - they are expected to be in-range. If not, | ||||
| an assertion will be thrown, but in a release build, you're into 'undefined behaviour' | an assertion will be thrown, but in a release build, you're into 'undefined behaviour' | ||||
| territory. | territory. | ||||
| @@ -616,9 +688,12 @@ public: | |||||
| } | } | ||||
| /** Sets a sample in the buffer. | /** Sets a sample in the buffer. | ||||
| The channel and index are not checked - they are expected to be in-range. If not, | The channel and index are not checked - they are expected to be in-range. If not, | ||||
| an assertion will be thrown, but in a release build, you're into 'undefined behaviour' | an assertion will be thrown, but in a release build, you're into 'undefined behaviour' | ||||
| territory. | territory. | ||||
| The hasBeenCleared method will return false after this call. | |||||
| */ | */ | ||||
| void setSample (int destChannel, int destSample, Type newValue) noexcept | void setSample (int destChannel, int destSample, Type newValue) noexcept | ||||
| { | { | ||||
| @@ -629,9 +704,12 @@ public: | |||||
| } | } | ||||
| /** Adds a value to a sample in the buffer. | /** Adds a value to a sample in the buffer. | ||||
| The channel and index are not checked - they are expected to be in-range. If not, | The channel and index are not checked - they are expected to be in-range. If not, | ||||
| an assertion will be thrown, but in a release build, you're into 'undefined behaviour' | an assertion will be thrown, but in a release build, you're into 'undefined behaviour' | ||||
| territory. | territory. | ||||
| The hasBeenCleared method will return false after this call. | |||||
| */ | */ | ||||
| void addSample (int destChannel, int destSample, Type valueToAdd) noexcept | void addSample (int destChannel, int destSample, Type valueToAdd) noexcept | ||||
| { | { | ||||
| @@ -732,6 +810,9 @@ public: | |||||
| /** Adds samples from another buffer to this one. | /** Adds samples from another buffer to this one. | ||||
| The hasBeenCleared method will return false after this call if samples have | |||||
| been added. | |||||
| @param destChannel the channel within this buffer to add the samples to | @param destChannel the channel within this buffer to add the samples to | ||||
| @param destStartSample the start sample within this buffer's channel | @param destStartSample the start sample within this buffer's channel | ||||
| @param source the source buffer to add from | @param source the source buffer to add from | ||||
| @@ -786,6 +867,9 @@ public: | |||||
| /** Adds samples from an array of floats to one of the channels. | /** Adds samples from an array of floats to one of the channels. | ||||
| The hasBeenCleared method will return false after this call if samples have | |||||
| been added. | |||||
| @param destChannel the channel within this buffer to add the samples to | @param destChannel the channel within this buffer to add the samples to | ||||
| @param destStartSample the start sample within this buffer's channel | @param destStartSample the start sample within this buffer's channel | ||||
| @param source the source data to use | @param source the source data to use | ||||
| @@ -831,6 +915,9 @@ public: | |||||
| /** Adds samples from an array of floats, applying a gain ramp to them. | /** Adds samples from an array of floats, applying a gain ramp to them. | ||||
| The hasBeenCleared method will return false after this call if samples have | |||||
| been added. | |||||
| @param destChannel the channel within this buffer to add the samples to | @param destChannel the channel within this buffer to add the samples to | ||||
| @param destStartSample the start sample within this buffer's channel | @param destStartSample the start sample within this buffer's channel | ||||
| @param source the source data to use | @param source the source data to use | ||||
| @@ -918,6 +1005,9 @@ public: | |||||
| /** Copies samples from an array of floats into one of the channels. | /** Copies samples from an array of floats into one of the channels. | ||||
| The hasBeenCleared method will return false after this call if samples have | |||||
| been copied. | |||||
| @param destChannel the channel within this buffer to copy the samples to | @param destChannel the channel within this buffer to copy the samples to | ||||
| @param destStartSample the start sample within this buffer's channel | @param destStartSample the start sample within this buffer's channel | ||||
| @param source the source buffer to read from | @param source the source buffer to read from | ||||
| @@ -943,6 +1033,9 @@ public: | |||||
| /** Copies samples from an array of floats into one of the channels, applying a gain to it. | /** Copies samples from an array of floats into one of the channels, applying a gain to it. | ||||
| The hasBeenCleared method will return false after this call if samples have | |||||
| been copied. | |||||
| @param destChannel the channel within this buffer to copy the samples to | @param destChannel the channel within this buffer to copy the samples to | ||||
| @param destStartSample the start sample within this buffer's channel | @param destStartSample the start sample within this buffer's channel | ||||
| @param source the source buffer to read from | @param source the source buffer to read from | ||||
| @@ -988,6 +1081,9 @@ public: | |||||
| /** Copies samples from an array of floats into one of the channels, applying a gain ramp. | /** Copies samples from an array of floats into one of the channels, applying a gain ramp. | ||||
| The hasBeenCleared method will return false after this call if samples have | |||||
| been copied. | |||||
| @param destChannel the channel within this buffer to copy the samples to | @param destChannel the channel within this buffer to copy the samples to | ||||
| @param destStartSample the start sample within this buffer's channel | @param destStartSample the start sample within this buffer's channel | ||||
| @param source the source buffer to read from | @param source the source buffer to read from | ||||