| @@ -1745,31 +1745,12 @@ AudioCDReader::~AudioCDReader() | |||
| decUserCount(); | |||
| } | |||
| bool AudioCDReader::read (int** destSamples, | |||
| int64 startSampleInFile, | |||
| int numSamples) | |||
| bool AudioCDReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples) | |||
| { | |||
| CDDeviceWrapper* const device = (CDDeviceWrapper*)handle; | |||
| CDDeviceWrapper* const device = (CDDeviceWrapper*) handle; | |||
| bool ok = true; | |||
| int offset = 0; | |||
| if (startSampleInFile < 0) | |||
| { | |||
| int* l = destSamples[0]; | |||
| int* r = destSamples[1]; | |||
| numSamples += (int) startSampleInFile; | |||
| offset -= (int) startSampleInFile; | |||
| while (++startSampleInFile <= 0) | |||
| { | |||
| *l++ = 0; | |||
| if (r != 0) | |||
| *r++ = 0; | |||
| } | |||
| } | |||
| while (numSamples > 0) | |||
| { | |||
| @@ -1781,8 +1762,8 @@ bool AudioCDReader::read (int** destSamples, | |||
| { | |||
| const int toDo = (int) jmin ((int64) numSamples, bufferEndSample - startSampleInFile); | |||
| int* const l = destSamples[0] + offset; | |||
| int* const r = destSamples[1] + offset; | |||
| int* const l = destSamples[0] + startOffsetInDestBuffer; | |||
| int* const r = numDestChannels > 1 ? (destSamples[1] + startOffsetInDestBuffer) : 0; | |||
| const short* src = (const short*) buffer.getData(); | |||
| src += 2 * (startSampleInFile - bufferStartSample); | |||
| @@ -1794,7 +1775,7 @@ bool AudioCDReader::read (int** destSamples, | |||
| r[i] = src [(i << 1) + 1] << 16; | |||
| } | |||
| offset += toDo; | |||
| startOffsetInDestBuffer += toDo; | |||
| startSampleInFile += toDo; | |||
| numSamples -= toDo; | |||
| } | |||
| @@ -1840,8 +1821,8 @@ bool AudioCDReader::read (int** destSamples, | |||
| } | |||
| else | |||
| { | |||
| int* l = destSamples[0] + offset; | |||
| int* r = destSamples[1] + offset; | |||
| int* l = destSamples[0] + startOffsetInDestBuffer; | |||
| int* r = numDestChannels > 1 ? (destSamples[1] + startOffsetInDestBuffer) : 0; | |||
| while (--numSamples >= 0) | |||
| { | |||
| @@ -3291,8 +3291,8 @@ public: | |||
| @see ArrayAllocationBase | |||
| */ | |||
| OwnedArray (const int granularity_ = juceDefaultArrayGranularity) throw() | |||
| : ArrayAllocationBase <ObjectClass*> (granularity_), | |||
| OwnedArray (const int granularity = juceDefaultArrayGranularity) throw() | |||
| : ArrayAllocationBase <ObjectClass*> (granularity), | |||
| numUsed (0) | |||
| { | |||
| } | |||
| @@ -4567,8 +4567,8 @@ public: | |||
| @see ArrayAllocationBase | |||
| */ | |||
| Array (const int granularity_ = juceDefaultArrayGranularity) throw() | |||
| : ArrayAllocationBase <ElementType> (granularity_), | |||
| Array (const int granularity = juceDefaultArrayGranularity) throw() | |||
| : ArrayAllocationBase <ElementType> (granularity), | |||
| numUsed (0) | |||
| { | |||
| } | |||
| @@ -10484,8 +10484,8 @@ public: | |||
| @see ArrayAllocationBase | |||
| */ | |||
| SortedSet (const int granularity_ = juceDefaultArrayGranularity) throw() | |||
| : ArrayAllocationBase <ElementType> (granularity_), | |||
| SortedSet (const int granularity = juceDefaultArrayGranularity) throw() | |||
| : ArrayAllocationBase <ElementType> (granularity), | |||
| numUsed (0) | |||
| { | |||
| } | |||
| @@ -31519,28 +31519,37 @@ public: | |||
| range -1.0 to 1.0 or beyond) | |||
| If the format is stereo, then destSamples[0] is the left channel | |||
| data, and destSamples[1] is the right channel. | |||
| The array passed in should be zero-terminated, and it's ok to | |||
| pass in an array with a different number of channels than | |||
| the number in the stream, so if you pass in an array with only | |||
| one channel and the stream is stereo, the reader will | |||
| put a merged sum of the stereo channels into the single | |||
| destination channel. | |||
| @param startSample the offset into the audio stream from which the samples | |||
| The numDestChannels parameter indicates how many pointers this array | |||
| contains, but some of these pointers can be null if you don't want to | |||
| read data for some of the channels | |||
| @param numDestChannels the number of array elements in the destChannels array | |||
| @param startSampleInSource the position in the audio file or stream at which the samples | |||
| should be read, as a number of samples from the start of the | |||
| stream. It's ok for this to be beyond the start or end of the | |||
| available data - any samples that can't be read will be padded | |||
| with zeros. | |||
| @param numSamples the number of samples to read. If this is greater than the | |||
| number of samples available, the result will be padded with | |||
| zeros | |||
| available data - any samples that are out-of-range will be returned | |||
| as zeros. | |||
| @param numSamplesToRead the number of samples to read. If this is greater than the number | |||
| of samples that the file or stream contains. the result will be padded | |||
| with zeros | |||
| @param fillLeftoverChannelsWithCopies if true, this indicates that if there's no source data available | |||
| for some of the channels that you pass in, then they should be filled with | |||
| copies of valid source channels. | |||
| E.g. if you're reading a mono file and you pass 2 channels to this method, then | |||
| if fillLeftoverChannelsWithCopies is true, both destination channels will be filled | |||
| with the same data from the file's single channel. If fillLeftoverChannelsWithCopies | |||
| was false, then only the first channel would be filled with the file's contents, and | |||
| the second would be cleared. If there are many channels, e.g. you try to read 4 channels | |||
| from a stereo file, then the last 3 would all end up with copies of the same data. | |||
| @returns true if the operation succeeded, false if there was an error. Note | |||
| that reading sections of data beyond the extent of the stream isn't an | |||
| error - the reader should just return zeros for these regions | |||
| @see readMaxLevels | |||
| */ | |||
| virtual bool read (int** destSamples, | |||
| int64 startSample, | |||
| int numSamples) = 0; | |||
| bool read (int** destSamples, | |||
| int numDestChannels, | |||
| int64 startSampleInSource, | |||
| int numSamplesToRead, | |||
| const bool fillLeftoverChannelsWithCopies); | |||
| /** Finds the highest and lowest sample levels from a section of the audio stream. | |||
| @@ -31620,6 +31629,27 @@ public: | |||
| /** The input stream, for use by subclasses. */ | |||
| InputStream* input; | |||
| /** Subclasses must implement this method to perform the low-level read operation. | |||
| Callers should use read() instead of calling this directly. | |||
| @param destSamples the array of destination buffers to fill. Some of these | |||
| pointers may be null | |||
| @param numDestChannels the number of items in the destSamples array. This | |||
| value is guaranteed not to be greater than the number of | |||
| channels that this reader object contains | |||
| @param startOffsetInDestBuffer the number of samples from the start of the | |||
| dest data at which to begin writing | |||
| @param startSampleInFile the number of samples into the source data at which | |||
| to begin reading. This value is guaranteed to be >= 0. | |||
| @param numSamples the number of samples to read | |||
| */ | |||
| virtual bool readSamples (int** destSamples, | |||
| int numDestChannels, | |||
| int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, | |||
| int numSamples) = 0; | |||
| juce_UseDebuggingNewOperator | |||
| private: | |||
| @@ -33915,6 +33945,15 @@ protected: | |||
| */ | |||
| virtual void textWasChanged(); | |||
| /** Called when the text editor has just appeared, due to a user click or other | |||
| focus change. | |||
| */ | |||
| virtual void editorShown (TextEditor* editorComponent); | |||
| /** Called when the text editor is going to be deleted, after editing has finished. | |||
| */ | |||
| virtual void editorAboutToBeHidden (TextEditor* editorComponent); | |||
| private: | |||
| String text; | |||
| Font font; | |||
| @@ -36861,9 +36900,8 @@ public: | |||
| ~AudioCDReader(); | |||
| /** Implementation of the AudioFormatReader method. */ | |||
| bool read (int** destSamples, | |||
| int64 startSampleInFile, | |||
| int numSamples); | |||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples); | |||
| /** Checks whether the CD has been removed from the drive. | |||
| */ | |||
| @@ -37138,9 +37176,8 @@ public: | |||
| /** Destructor. */ | |||
| ~AudioSubsectionReader(); | |||
| bool read (int** destSamples, | |||
| int64 startSample, | |||
| int numSamples); | |||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples); | |||
| void readMaxLevels (int64 startSample, | |||
| int64 numSamples, | |||
| @@ -50568,7 +50605,7 @@ class FilenameComponent; | |||
| Use FilenameComponent::addListener() and FilenameComponent::removeListener() to | |||
| register one of these objects for event callbacks when the filename is changed. | |||
| @See FilenameComponent | |||
| @see FilenameComponent | |||
| */ | |||
| class JUCE_API FilenameComponentListener | |||
| { | |||
| @@ -53750,7 +53787,7 @@ public: | |||
| const bool isMouseOverButton, | |||
| const bool isButtonDown); | |||
| /** AlertWindow handling.. | |||
| /* AlertWindow handling.. | |||
| */ | |||
| virtual AlertWindow* createAlertWindow (const String& title, | |||
| const String& message, | |||
| @@ -158,91 +158,57 @@ public: | |||
| } | |||
| //============================================================================== | |||
| bool read (int** destSamples, | |||
| int64 startSampleInFile, | |||
| int numSamples) | |||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples) | |||
| { | |||
| int64 start = startSampleInFile; | |||
| int startOffsetInDestBuffer = 0; | |||
| if (startSampleInFile < 0) | |||
| { | |||
| const int silence = (int) jmin (-startSampleInFile, (int64) numSamples); | |||
| int** destChan = destSamples; | |||
| for (int i = 2; --i >= 0;) | |||
| { | |||
| if (*destChan != 0) | |||
| { | |||
| zeromem (*destChan, sizeof (int) * silence); | |||
| ++destChan; | |||
| } | |||
| } | |||
| numSamples = (int) jmin ((int64) numSamples, lengthInSamples - startSampleInFile); | |||
| if (numSamples <= 0) | |||
| return true; | |||
| startOffsetInDestBuffer += silence; | |||
| numSamples -= silence; | |||
| start = 0; | |||
| } | |||
| input->setPosition (dataChunkStart + startSampleInFile * bytesPerFrame); | |||
| int numToDo = jlimit (0, numSamples, (int) (lengthInSamples - start)); | |||
| const int tempBufSize = 480 * 3 * 4; // (keep this a multiple of 3) | |||
| char tempBuffer [tempBufSize]; | |||
| if (numToDo > 0) | |||
| while (numSamples > 0) | |||
| { | |||
| input->setPosition (dataChunkStart + start * bytesPerFrame); | |||
| int num = numToDo; | |||
| int* left = destSamples[0]; | |||
| if (left != 0) | |||
| left += startOffsetInDestBuffer; | |||
| left += startOffsetInDestBuffer; | |||
| int* right = destSamples[1]; | |||
| int* right = numDestChannels > 1 ? destSamples[1] : 0; | |||
| if (right != 0) | |||
| right += startOffsetInDestBuffer; | |||
| // (keep this a multiple of 3) | |||
| const int tempBufSize = 1440 * 4; | |||
| char tempBuffer [tempBufSize]; | |||
| const int numThisTime = jmin (tempBufSize / bytesPerFrame, numSamples); | |||
| const int bytesRead = input->read (tempBuffer, numThisTime * bytesPerFrame); | |||
| while (num > 0) | |||
| { | |||
| const int numThisTime = jmin (tempBufSize / bytesPerFrame, num); | |||
| const int bytesRead = input->read (tempBuffer, numThisTime * bytesPerFrame); | |||
| if (bytesRead < numThisTime * bytesPerFrame) | |||
| zeromem (tempBuffer + bytesRead, numThisTime * bytesPerFrame - bytesRead); | |||
| if (bytesRead < numThisTime * bytesPerFrame) | |||
| zeromem (tempBuffer + bytesRead, numThisTime * bytesPerFrame - bytesRead); | |||
| if (bitsPerSample == 16) | |||
| if (bitsPerSample == 16) | |||
| { | |||
| if (littleEndian) | |||
| { | |||
| if (littleEndian) | |||
| { | |||
| const short* src = (const short*) tempBuffer; | |||
| const short* src = (const short*) tempBuffer; | |||
| if (numChannels > 1) | |||
| if (numChannels > 1) | |||
| { | |||
| if (left == 0) | |||
| { | |||
| if (left == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *right++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| ++src; | |||
| } | |||
| } | |||
| else if (right == 0) | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| ++src; | |||
| *left++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| } | |||
| *right++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| ++src; | |||
| } | |||
| else | |||
| } | |||
| else if (right == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| *right++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| } | |||
| ++src; | |||
| *left++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| } | |||
| } | |||
| else | |||
| @@ -250,41 +216,39 @@ public: | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| *right++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| } | |||
| } | |||
| } | |||
| else | |||
| { | |||
| const char* src = (const char*) tempBuffer; | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| } | |||
| } | |||
| } | |||
| else | |||
| { | |||
| const char* src = (const char*) tempBuffer; | |||
| if (numChannels > 1) | |||
| if (numChannels > 1) | |||
| { | |||
| if (left == 0) | |||
| { | |||
| if (left == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *right++ = bigEndianShort (src) << 16; | |||
| src += 4; | |||
| } | |||
| } | |||
| else if (right == 0) | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| src += 2; | |||
| *left++ = bigEndianShort (src) << 16; | |||
| src += 2; | |||
| } | |||
| *right++ = bigEndianShort (src) << 16; | |||
| src += 4; | |||
| } | |||
| else | |||
| } | |||
| else if (right == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = bigEndianShort (src) << 16; | |||
| src += 2; | |||
| *right++ = bigEndianShort (src) << 16; | |||
| src += 2; | |||
| } | |||
| src += 2; | |||
| *left++ = bigEndianShort (src) << 16; | |||
| src += 2; | |||
| } | |||
| } | |||
| else | |||
| @@ -293,44 +257,44 @@ public: | |||
| { | |||
| *left++ = bigEndianShort (src) << 16; | |||
| src += 2; | |||
| *right++ = bigEndianShort (src) << 16; | |||
| src += 2; | |||
| } | |||
| } | |||
| } | |||
| else | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = bigEndianShort (src) << 16; | |||
| src += 2; | |||
| } | |||
| } | |||
| } | |||
| else if (bitsPerSample == 24) | |||
| { | |||
| const char* src = (const char*)tempBuffer; | |||
| } | |||
| else if (bitsPerSample == 24) | |||
| { | |||
| const char* src = (const char*)tempBuffer; | |||
| if (littleEndian) | |||
| if (littleEndian) | |||
| { | |||
| if (numChannels > 1) | |||
| { | |||
| if (numChannels > 1) | |||
| if (left == 0) | |||
| { | |||
| if (left == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *right++ = littleEndian24Bit (src) << 8; | |||
| src += 6; | |||
| } | |||
| } | |||
| else if (right == 0) | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| src += 3; | |||
| *left++ = littleEndian24Bit (src) << 8; | |||
| src += 3; | |||
| } | |||
| *right++ = littleEndian24Bit (src) << 8; | |||
| src += 6; | |||
| } | |||
| else | |||
| } | |||
| else if (right == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = littleEndian24Bit (src) << 8; | |||
| src += 3; | |||
| *right++ = littleEndian24Bit (src) << 8; | |||
| src += 3; | |||
| } | |||
| src += 3; | |||
| *left++ = littleEndian24Bit (src) << 8; | |||
| src += 3; | |||
| } | |||
| } | |||
| else | |||
| @@ -339,39 +303,39 @@ public: | |||
| { | |||
| *left++ = littleEndian24Bit (src) << 8; | |||
| src += 3; | |||
| *right++ = littleEndian24Bit (src) << 8; | |||
| src += 3; | |||
| } | |||
| } | |||
| } | |||
| else | |||
| { | |||
| if (numChannels > 1) | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| if (left == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *right++ = bigEndian24Bit (src) << 8; | |||
| src += 6; | |||
| } | |||
| } | |||
| else if (right == 0) | |||
| *left++ = littleEndian24Bit (src) << 8; | |||
| src += 3; | |||
| } | |||
| } | |||
| } | |||
| else | |||
| { | |||
| if (numChannels > 1) | |||
| { | |||
| if (left == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| src += 3; | |||
| *left++ = bigEndian24Bit (src) << 8; | |||
| src += 3; | |||
| } | |||
| *right++ = bigEndian24Bit (src) << 8; | |||
| src += 6; | |||
| } | |||
| else | |||
| } | |||
| else if (right == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = bigEndian24Bit (src) << 8; | |||
| src += 3; | |||
| *right++ = bigEndian24Bit (src) << 8; | |||
| src += 3; | |||
| } | |||
| src += 3; | |||
| *left++ = bigEndian24Bit (src) << 8; | |||
| src += 3; | |||
| } | |||
| } | |||
| else | |||
| @@ -380,43 +344,45 @@ public: | |||
| { | |||
| *left++ = bigEndian24Bit (src) << 8; | |||
| src += 3; | |||
| *right++ = bigEndian24Bit (src) << 8; | |||
| src += 3; | |||
| } | |||
| } | |||
| } | |||
| else | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = bigEndian24Bit (src) << 8; | |||
| src += 3; | |||
| } | |||
| } | |||
| } | |||
| else if (bitsPerSample == 32) | |||
| { | |||
| const unsigned int* src = (const unsigned int*) tempBuffer; | |||
| unsigned int* l = (unsigned int*) left; | |||
| unsigned int* r = (unsigned int*) right; | |||
| } | |||
| else if (bitsPerSample == 32) | |||
| { | |||
| const unsigned int* src = (const unsigned int*) tempBuffer; | |||
| unsigned int* l = (unsigned int*) left; | |||
| unsigned int* r = (unsigned int*) right; | |||
| if (littleEndian) | |||
| if (littleEndian) | |||
| { | |||
| if (numChannels > 1) | |||
| { | |||
| if (numChannels > 1) | |||
| if (l == 0) | |||
| { | |||
| if (l == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| ++src; | |||
| *r++ = swapIfBigEndian (*src++); | |||
| } | |||
| } | |||
| else if (r == 0) | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *l++ = swapIfBigEndian (*src++); | |||
| ++src; | |||
| } | |||
| ++src; | |||
| *r++ = swapIfBigEndian (*src++); | |||
| } | |||
| else | |||
| } | |||
| else if (r == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *l++ = swapIfBigEndian (*src++); | |||
| *r++ = swapIfBigEndian (*src++); | |||
| } | |||
| *l++ = swapIfBigEndian (*src++); | |||
| ++src; | |||
| } | |||
| } | |||
| else | |||
| @@ -424,78 +390,44 @@ public: | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *l++ = swapIfBigEndian (*src++); | |||
| *r++ = swapIfBigEndian (*src++); | |||
| } | |||
| } | |||
| } | |||
| else | |||
| { | |||
| if (numChannels > 1) | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| if (l == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| ++src; | |||
| *r++ = swapIfLittleEndian (*src++); | |||
| } | |||
| } | |||
| else if (r == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *l++ = swapIfLittleEndian (*src++); | |||
| ++src; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *l++ = swapIfLittleEndian (*src++); | |||
| *r++ = swapIfLittleEndian (*src++); | |||
| } | |||
| } | |||
| } | |||
| else | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *l++ = swapIfLittleEndian (*src++); | |||
| } | |||
| *l++ = swapIfBigEndian (*src++); | |||
| } | |||
| } | |||
| left = (int*) l; | |||
| right = (int*) r; | |||
| } | |||
| else if (bitsPerSample == 8) | |||
| else | |||
| { | |||
| const char* src = (const char*) tempBuffer; | |||
| if (numChannels > 1) | |||
| { | |||
| if (left == 0) | |||
| if (l == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *right++ = ((int) *src++) << 24; | |||
| ++src; | |||
| *r++ = swapIfLittleEndian (*src++); | |||
| } | |||
| } | |||
| else if (right == 0) | |||
| else if (r == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *l++ = swapIfLittleEndian (*src++); | |||
| ++src; | |||
| *left++ = ((int) *src++) << 24; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = ((int) *src++) << 24; | |||
| *right++ = ((int) *src++) << 24; | |||
| *l++ = swapIfLittleEndian (*src++); | |||
| *r++ = swapIfLittleEndian (*src++); | |||
| } | |||
| } | |||
| } | |||
| @@ -503,24 +435,64 @@ public: | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = ((int) *src++) << 24; | |||
| *l++ = swapIfLittleEndian (*src++); | |||
| } | |||
| } | |||
| } | |||
| num -= numThisTime; | |||
| left = (int*) l; | |||
| right = (int*) r; | |||
| } | |||
| else if (bitsPerSample == 8) | |||
| { | |||
| const char* src = (const char*) tempBuffer; | |||
| if (numChannels > 1) | |||
| { | |||
| if (left == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *right++ = ((int) *src++) << 24; | |||
| ++src; | |||
| } | |||
| } | |||
| else if (right == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| ++src; | |||
| *left++ = ((int) *src++) << 24; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = ((int) *src++) << 24; | |||
| *right++ = ((int) *src++) << 24; | |||
| } | |||
| } | |||
| } | |||
| else | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = ((int) *src++) << 24; | |||
| } | |||
| } | |||
| } | |||
| startOffsetInDestBuffer += numThisTime; | |||
| numSamples -= numThisTime; | |||
| } | |||
| if (numToDo < numSamples) | |||
| if (numSamples > 0) | |||
| { | |||
| int** destChan = destSamples; | |||
| while (*destChan != 0) | |||
| { | |||
| zeromem ((*destChan) + (startOffsetInDestBuffer + numToDo), | |||
| sizeof (int) * (numSamples - numToDo)); | |||
| ++destChan; | |||
| } | |||
| for (int i = numDestChannels; --i >= 0;) | |||
| if (destSamples[i] != 0) | |||
| zeromem (destSamples[i] + startOffsetInDestBuffer, | |||
| sizeof (int) * numSamples); | |||
| } | |||
| return true; | |||
| @@ -149,9 +149,8 @@ void AudioCDReader::refreshTrackLengths() | |||
| lengthInSamples = sample; | |||
| } | |||
| bool AudioCDReader::read (int** destSamples, | |||
| int64 startSampleInFile, | |||
| int numSamples) | |||
| bool AudioCDReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples) | |||
| { | |||
| while (numSamples > 0) | |||
| { | |||
| @@ -198,7 +197,7 @@ bool AudioCDReader::read (int** destSamples, | |||
| const int startPos = (int) (startSampleInFile - trackStartSamples.getUnchecked (track)); | |||
| const int numAvailable = (int) jmin ((int64) numSamples, reader->lengthInSamples - startPos); | |||
| reader->read (destSamples, startPos, numAvailable); | |||
| reader->readSamples (destSamples, numDestChannels, startOffsetInDestBuffer, startPos, numAvailable); | |||
| numSamples -= numAvailable; | |||
| startSampleInFile += numAvailable; | |||
| @@ -76,9 +76,8 @@ public: | |||
| ~AudioCDReader(); | |||
| /** Implementation of the AudioFormatReader method. */ | |||
| bool read (int** destSamples, | |||
| int64 startSampleInFile, | |||
| int numSamples); | |||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples); | |||
| /** Checks whether the CD has been removed from the drive. | |||
| */ | |||
| @@ -55,6 +55,67 @@ AudioFormatReader::~AudioFormatReader() | |||
| delete input; | |||
| } | |||
| bool AudioFormatReader::read (int** destSamples, | |||
| int numDestChannels, | |||
| int64 startSampleInSource, | |||
| int numSamplesToRead, | |||
| const bool fillLeftoverChannelsWithCopies) | |||
| { | |||
| jassert (numDestChannels > 0); // you have to actually give this some channels to work with! | |||
| int startOffsetInDestBuffer = 0; | |||
| if (startSampleInSource < 0) | |||
| { | |||
| const int silence = (int) jmin (-startSampleInSource, (int64) numSamplesToRead); | |||
| for (int i = numDestChannels; --i >= 0;) | |||
| if (destSamples[i] != 0) | |||
| zeromem (destSamples[i], sizeof (int) * silence); | |||
| startOffsetInDestBuffer += silence; | |||
| numSamplesToRead -= silence; | |||
| startSampleInSource = 0; | |||
| } | |||
| if (numSamplesToRead <= 0) | |||
| return true; | |||
| if (! readSamples (destSamples, jmin (numChannels, numDestChannels), startOffsetInDestBuffer, | |||
| startSampleInSource, numSamplesToRead)) | |||
| return false; | |||
| if (numDestChannels > numChannels) | |||
| { | |||
| if (fillLeftoverChannelsWithCopies) | |||
| { | |||
| int* lastFullChannel = destSamples[0]; | |||
| for (int i = numDestChannels; --i > 0;) | |||
| { | |||
| if (destSamples[i] != 0) | |||
| { | |||
| lastFullChannel = destSamples[i]; | |||
| break; | |||
| } | |||
| } | |||
| if (lastFullChannel != 0) | |||
| for (int i = numChannels; i < numDestChannels; ++i) | |||
| if (destSamples[i] != 0) | |||
| memcpy (destSamples[i], lastFullChannel, sizeof (int) * numSamplesToRead); | |||
| } | |||
| else | |||
| { | |||
| for (int i = numChannels; i < numDestChannels; ++i) | |||
| if (destSamples[i] != 0) | |||
| zeromem (destSamples[i], sizeof (int) * numSamplesToRead); | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| static void findMaxMin (const float* src, const int num, | |||
| float& maxVal, float& minVal) | |||
| { | |||
| @@ -106,7 +167,7 @@ void AudioFormatReader::readMaxLevels (int64 startSampleInFile, | |||
| while (numSamples > 0) | |||
| { | |||
| const int numToDo = (int) jmin (numSamples, (int64) bufferSize); | |||
| read ((int**) tempBuffer, startSampleInFile, numToDo); | |||
| read ((int**) tempBuffer, 2, startSampleInFile, numToDo, false); | |||
| numSamples -= numToDo; | |||
| @@ -144,7 +205,7 @@ void AudioFormatReader::readMaxLevels (int64 startSampleInFile, | |||
| while (numSamples > 0) | |||
| { | |||
| const int numToDo = (int) jmin (numSamples, (int64) bufferSize); | |||
| read ((int**) tempBuffer, startSampleInFile, numToDo); | |||
| read ((int**) tempBuffer, 2, startSampleInFile, numToDo, false); | |||
| numSamples -= numToDo; | |||
| @@ -230,7 +291,7 @@ int64 AudioFormatReader::searchForLevel (int64 startSample, | |||
| if (bufferStart >= (int) lengthInSamples) | |||
| break; | |||
| read ((int**) tempBuffer, bufferStart, numThisTime); | |||
| read ((int**) tempBuffer, 2, bufferStart, numThisTime, false); | |||
| int num = numThisTime; | |||
| while (--num >= 0) | |||
| @@ -350,7 +411,7 @@ bool AudioFormatWriter::writeFromAudioReader (AudioFormatReader& reader, | |||
| for (int i = tempBuffer.getNumChannels(); --i >= 0;) | |||
| buffers[i] = (int*) tempBuffer.getSampleData (i, 0); | |||
| if (! reader.read (buffers, startSample, numToDo)) | |||
| if (! reader.read (buffers, maxChans, startSample, numToDo, false)) | |||
| return false; | |||
| if (reader.usesFloatingPointData != isFloatingPoint()) | |||
| @@ -86,28 +86,37 @@ public: | |||
| range -1.0 to 1.0 or beyond) | |||
| If the format is stereo, then destSamples[0] is the left channel | |||
| data, and destSamples[1] is the right channel. | |||
| The array passed in should be zero-terminated, and it's ok to | |||
| pass in an array with a different number of channels than | |||
| the number in the stream, so if you pass in an array with only | |||
| one channel and the stream is stereo, the reader will | |||
| put a merged sum of the stereo channels into the single | |||
| destination channel. | |||
| @param startSample the offset into the audio stream from which the samples | |||
| The numDestChannels parameter indicates how many pointers this array | |||
| contains, but some of these pointers can be null if you don't want to | |||
| read data for some of the channels | |||
| @param numDestChannels the number of array elements in the destChannels array | |||
| @param startSampleInSource the position in the audio file or stream at which the samples | |||
| should be read, as a number of samples from the start of the | |||
| stream. It's ok for this to be beyond the start or end of the | |||
| available data - any samples that can't be read will be padded | |||
| with zeros. | |||
| @param numSamples the number of samples to read. If this is greater than the | |||
| number of samples available, the result will be padded with | |||
| zeros | |||
| available data - any samples that are out-of-range will be returned | |||
| as zeros. | |||
| @param numSamplesToRead the number of samples to read. If this is greater than the number | |||
| of samples that the file or stream contains. the result will be padded | |||
| with zeros | |||
| @param fillLeftoverChannelsWithCopies if true, this indicates that if there's no source data available | |||
| for some of the channels that you pass in, then they should be filled with | |||
| copies of valid source channels. | |||
| E.g. if you're reading a mono file and you pass 2 channels to this method, then | |||
| if fillLeftoverChannelsWithCopies is true, both destination channels will be filled | |||
| with the same data from the file's single channel. If fillLeftoverChannelsWithCopies | |||
| was false, then only the first channel would be filled with the file's contents, and | |||
| the second would be cleared. If there are many channels, e.g. you try to read 4 channels | |||
| from a stereo file, then the last 3 would all end up with copies of the same data. | |||
| @returns true if the operation succeeded, false if there was an error. Note | |||
| that reading sections of data beyond the extent of the stream isn't an | |||
| error - the reader should just return zeros for these regions | |||
| @see readMaxLevels | |||
| */ | |||
| virtual bool read (int** destSamples, | |||
| int64 startSample, | |||
| int numSamples) = 0; | |||
| bool read (int** destSamples, | |||
| int numDestChannels, | |||
| int64 startSampleInSource, | |||
| int numSamplesToRead, | |||
| const bool fillLeftoverChannelsWithCopies); | |||
| /** Finds the highest and lowest sample levels from a section of the audio stream. | |||
| @@ -188,6 +197,30 @@ public: | |||
| /** The input stream, for use by subclasses. */ | |||
| InputStream* input; | |||
| //============================================================================== | |||
| /** Subclasses must implement this method to perform the low-level read operation. | |||
| Callers should use read() instead of calling this directly. | |||
| @param destSamples the array of destination buffers to fill. Some of these | |||
| pointers may be null | |||
| @param numDestChannels the number of items in the destSamples array. This | |||
| value is guaranteed not to be greater than the number of | |||
| channels that this reader object contains | |||
| @param startOffsetInDestBuffer the number of samples from the start of the | |||
| dest data at which to begin writing | |||
| @param startSampleInFile the number of samples into the source data at which | |||
| to begin reading. This value is guaranteed to be >= 0. | |||
| @param numSamples the number of samples to read | |||
| */ | |||
| virtual bool readSamples (int** destSamples, | |||
| int numDestChannels, | |||
| int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, | |||
| int numSamples) = 0; | |||
| //============================================================================== | |||
| juce_UseDebuggingNewOperator | |||
| @@ -62,26 +62,23 @@ AudioSubsectionReader::~AudioSubsectionReader() | |||
| } | |||
| //============================================================================== | |||
| bool AudioSubsectionReader::read (int** destSamples, | |||
| int64 startSampleInFile, | |||
| int numSamples) | |||
| bool AudioSubsectionReader::readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples) | |||
| { | |||
| if (startSampleInFile < 0 || startSampleInFile + numSamples > length) | |||
| if (startSampleInFile + numSamples > length) | |||
| { | |||
| int** d = destSamples; | |||
| while (*d != 0) | |||
| { | |||
| zeromem (*d, sizeof (int) * numSamples); | |||
| ++d; | |||
| } | |||
| startSampleInFile = jmax ((int64) 0, startSampleInFile); | |||
| numSamples = jmax (0, jmin (numSamples, (int) (length - startSampleInFile))); | |||
| for (int i = numDestChannels; --i >= 0;) | |||
| if (destSamples[i] != 0) | |||
| zeromem (destSamples[i], sizeof (int) * numSamples); | |||
| numSamples = jmin (numSamples, (int) (length - startSampleInFile)); | |||
| if (numSamples <= 0) | |||
| return true; | |||
| } | |||
| return source->read (destSamples, | |||
| startSampleInFile + startSample, | |||
| numSamples); | |||
| return source->readSamples (destSamples, numDestChannels, startOffsetInDestBuffer, | |||
| startSampleInFile + startSample, numSamples); | |||
| } | |||
| void AudioSubsectionReader::readMaxLevels (int64 startSampleInFile, | |||
| @@ -73,9 +73,8 @@ public: | |||
| //============================================================================== | |||
| bool read (int** destSamples, | |||
| int64 startSample, | |||
| int numSamples); | |||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples); | |||
| void readMaxLevels (int64 startSample, | |||
| int64 numSamples, | |||
| @@ -153,33 +153,14 @@ public: | |||
| } | |||
| // returns the number of samples read | |||
| bool read (int** destSamples, | |||
| int64 startSampleInFile, | |||
| int numSamples) | |||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples) | |||
| { | |||
| using namespace FlacNamespace; | |||
| if (! ok) | |||
| return false; | |||
| int offset = 0; | |||
| if (startSampleInFile < 0) | |||
| { | |||
| const int num = (int) jmin ((int64) numSamples, -startSampleInFile); | |||
| int n = 0; | |||
| while (destSamples[n] != 0) | |||
| { | |||
| zeromem (destSamples[n], sizeof (int) * num); | |||
| ++n; | |||
| } | |||
| offset += num; | |||
| startSampleInFile += num; | |||
| numSamples -= num; | |||
| } | |||
| while (numSamples > 0) | |||
| { | |||
| if (startSampleInFile >= reservoirStart | |||
| @@ -190,16 +171,13 @@ public: | |||
| jassert (num > 0); | |||
| int n = 0; | |||
| while (destSamples[n] != 0) | |||
| { | |||
| memcpy (destSamples[n] + offset, | |||
| reservoir.getSampleData (n, (int) (startSampleInFile - reservoirStart)), | |||
| sizeof (int) * num); | |||
| ++n; | |||
| } | |||
| for (int i = jmin (numDestChannels, reservoir.getNumChannels()); --i >= 0;) | |||
| if (destSamples[i] != 0) | |||
| memcpy (destSamples[i] + startOffsetInDestBuffer, | |||
| reservoir.getSampleData (i, (int) (startSampleInFile - reservoirStart)), | |||
| sizeof (int) * num); | |||
| offset += num; | |||
| startOffsetInDestBuffer += num; | |||
| startSampleInFile += num; | |||
| numSamples -= num; | |||
| } | |||
| @@ -235,12 +213,10 @@ public: | |||
| if (numSamples > 0) | |||
| { | |||
| int n = 0; | |||
| while (destSamples[n] != 0) | |||
| { | |||
| zeromem (destSamples[n] + offset, sizeof (int) * numSamples); | |||
| ++n; | |||
| } | |||
| for (int i = numDestChannels; --i >= 0;) | |||
| if (destSamples[i] != 0) | |||
| zeromem (destSamples[i] + startOffsetInDestBuffer, | |||
| sizeof (int) * numSamples); | |||
| } | |||
| return true; | |||
| @@ -137,31 +137,9 @@ public: | |||
| } | |||
| //============================================================================== | |||
| bool read (int** destSamples, | |||
| int64 startSampleInFile, | |||
| int numSamples) | |||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples) | |||
| { | |||
| int startOffsetInDestBuffer = 0; | |||
| if (startSampleInFile < 0) | |||
| { | |||
| const int silence = (int) jmin (-startSampleInFile, (int64) numSamples); | |||
| int** destChan = destSamples; | |||
| for (int i = 2; --i >= 0;) | |||
| { | |||
| if (*destChan != 0) | |||
| { | |||
| zeromem (*destChan, sizeof (int) * silence); | |||
| ++destChan; | |||
| } | |||
| } | |||
| startOffsetInDestBuffer += silence; | |||
| numSamples -= silence; | |||
| } | |||
| while (numSamples > 0) | |||
| { | |||
| const int numAvailable = reservoirStart + samplesInReservoir - startSampleInFile; | |||
| @@ -172,16 +150,11 @@ public: | |||
| const int numToUse = jmin (numSamples, numAvailable); | |||
| for (unsigned int i = 0; i < numChannels; ++i) | |||
| { | |||
| if (destSamples[i] == 0) | |||
| break; | |||
| memcpy (destSamples[i] + startOffsetInDestBuffer, | |||
| reservoir.getSampleData (jmin (i, reservoir.getNumChannels()), | |||
| (int) (startSampleInFile - reservoirStart)), | |||
| sizeof (float) * numToUse); | |||
| } | |||
| for (int i = jmin (numDestChannels, reservoir.getNumChannels()); --i >= 0;) | |||
| if (destSamples[i] != 0) | |||
| memcpy (destSamples[i] + startOffsetInDestBuffer, | |||
| reservoir.getSampleData (i, (int) (startSampleInFile - reservoirStart)), | |||
| sizeof (float) * numToUse); | |||
| startSampleInFile += numToUse; | |||
| numSamples -= numToUse; | |||
| @@ -232,6 +205,14 @@ public: | |||
| } | |||
| } | |||
| if (numSamples > 0) | |||
| { | |||
| for (int i = numDestChannels; --i >= 0;) | |||
| if (destSamples[i] != 0) | |||
| zeromem (destSamples[i] + startOffsetInDestBuffer, | |||
| sizeof (int) * numSamples); | |||
| } | |||
| return true; | |||
| } | |||
| @@ -237,33 +237,31 @@ public: | |||
| #endif | |||
| } | |||
| bool read (int** destSamples, | |||
| int64 startSample, | |||
| int numSamples) | |||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples) | |||
| { | |||
| checkThreadIsAttached(); | |||
| int done = 0; | |||
| while (numSamples > 0) | |||
| { | |||
| if (! loadFrame ((int) startSample)) | |||
| if (! loadFrame ((int) startSampleInFile)) | |||
| return false; | |||
| const int numToDo = jmin (numSamples, samplesPerFrame); | |||
| for (unsigned int j = 0; j < inputStreamDesc.mChannelsPerFrame; ++j) | |||
| for (int j = numDestChannels; --j >= 0;) | |||
| { | |||
| if (destSamples[j] != 0) | |||
| { | |||
| const short* const src = ((const short*) bufferList->mBuffers[0].mData) + j; | |||
| for (int i = 0; i < numToDo; ++i) | |||
| destSamples[j][done + i] = src [i << 1] << 16; | |||
| destSamples[j][startOffsetInDestBuffer + i] = src [i << 1] << 16; | |||
| } | |||
| } | |||
| done += numToDo; | |||
| startSample += numToDo; | |||
| startOffsetInDestBuffer += numToDo; | |||
| startSampleInFile += numToDo; | |||
| numSamples -= numToDo; | |||
| } | |||
| @@ -310,89 +310,55 @@ public: | |||
| } | |||
| //============================================================================== | |||
| bool read (int** destSamples, | |||
| int64 startSampleInFile, | |||
| int numSamples) | |||
| bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, | |||
| int64 startSampleInFile, int numSamples) | |||
| { | |||
| int64 start = startSampleInFile; | |||
| int startOffsetInDestBuffer = 0; | |||
| numSamples = (int) jmin ((int64) numSamples, lengthInSamples - startSampleInFile); | |||
| if (startSampleInFile < 0) | |||
| { | |||
| const int silence = (int) jmin (-startSampleInFile, (int64) numSamples); | |||
| int** destChan = destSamples; | |||
| for (int i = 2; --i >= 0;) | |||
| { | |||
| if (*destChan != 0) | |||
| { | |||
| zeromem (*destChan, sizeof (int) * silence); | |||
| ++destChan; | |||
| } | |||
| } | |||
| if (numSamples <= 0) | |||
| return true; | |||
| startOffsetInDestBuffer += silence; | |||
| numSamples -= silence; | |||
| start = 0; | |||
| } | |||
| input->setPosition (dataChunkStart + startSampleInFile * bytesPerFrame); | |||
| const int numToDo = (int) jlimit ((int64) 0, (int64) numSamples, lengthInSamples - start); | |||
| const int tempBufSize = 480 * 3 * 4; // (keep this a multiple of 3) | |||
| char tempBuffer [tempBufSize]; | |||
| if (numToDo > 0) | |||
| while (numSamples > 0) | |||
| { | |||
| input->setPosition (dataChunkStart + start * bytesPerFrame); | |||
| int num = numToDo; | |||
| int* left = destSamples[0]; | |||
| if (left != 0) | |||
| left += startOffsetInDestBuffer; | |||
| left += startOffsetInDestBuffer; | |||
| int* right = destSamples[1]; | |||
| int* right = numDestChannels > 1 ? destSamples[1] : 0; | |||
| if (right != 0) | |||
| right += startOffsetInDestBuffer; | |||
| // (keep this a multiple of 3) | |||
| const int tempBufSize = 1440 * 4; | |||
| char tempBuffer [tempBufSize]; | |||
| const int numThisTime = jmin (tempBufSize / bytesPerFrame, numSamples); | |||
| const int bytesRead = input->read (tempBuffer, numThisTime * bytesPerFrame); | |||
| while (num > 0) | |||
| { | |||
| const int numThisTime = jmin (tempBufSize / bytesPerFrame, num); | |||
| const int bytesRead = input->read (tempBuffer, numThisTime * bytesPerFrame); | |||
| if (bytesRead < numThisTime * bytesPerFrame) | |||
| zeromem (tempBuffer + bytesRead, numThisTime * bytesPerFrame - bytesRead); | |||
| if (bytesRead < numThisTime * bytesPerFrame) | |||
| zeromem (tempBuffer + bytesRead, numThisTime * bytesPerFrame - bytesRead); | |||
| if (bitsPerSample == 16) | |||
| { | |||
| const short* src = (const short*) tempBuffer; | |||
| if (bitsPerSample == 16) | |||
| if (numChannels > 1) | |||
| { | |||
| const short* src = (const short*) tempBuffer; | |||
| if (numChannels > 1) | |||
| if (left == 0) | |||
| { | |||
| if (left == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| ++src; | |||
| *right++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| } | |||
| } | |||
| else if (right == 0) | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = ((int) swapIfBigEndian ((unsigned short) *src++) | |||
| + (int) swapIfBigEndian ((unsigned short) *src++)) << 15; | |||
| } | |||
| ++src; | |||
| *right++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| } | |||
| else | |||
| } | |||
| else if (right == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| *right++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| } | |||
| *left++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| ++src; | |||
| } | |||
| } | |||
| else | |||
| @@ -400,40 +366,39 @@ public: | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| *right++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| } | |||
| } | |||
| } | |||
| else if (bitsPerSample == 24) | |||
| else | |||
| { | |||
| const char* src = (const char*) tempBuffer; | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = (int) swapIfBigEndian ((unsigned short) *src++) << 16; | |||
| } | |||
| } | |||
| } | |||
| else if (bitsPerSample == 24) | |||
| { | |||
| const char* src = (const char*) tempBuffer; | |||
| if (numChannels > 1) | |||
| if (numChannels > 1) | |||
| { | |||
| if (left == 0) | |||
| { | |||
| if (left == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| src += 6; | |||
| *right++ = littleEndian24Bit (src) << 8; | |||
| } | |||
| } | |||
| else if (right == 0) | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = (littleEndian24Bit (src) + littleEndian24Bit (src + 3)) << 7; | |||
| src += 6; | |||
| } | |||
| src += 3; | |||
| *right++ = littleEndian24Bit (src) << 8; | |||
| src += 3; | |||
| } | |||
| else | |||
| } | |||
| else if (right == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = 0; i < numThisTime; ++i) | |||
| { | |||
| *left++ = littleEndian24Bit (src) << 8; | |||
| src += 3; | |||
| *right++ = littleEndian24Bit (src) << 8; | |||
| src += 3; | |||
| } | |||
| *left++ = littleEndian24Bit (src) << 8; | |||
| src += 6; | |||
| } | |||
| } | |||
| else | |||
| @@ -442,40 +407,42 @@ public: | |||
| { | |||
| *left++ = littleEndian24Bit (src) << 8; | |||
| src += 3; | |||
| *right++ = littleEndian24Bit (src) << 8; | |||
| src += 3; | |||
| } | |||
| } | |||
| } | |||
| else if (bitsPerSample == 32) | |||
| else | |||
| { | |||
| const unsigned int* src = (const unsigned int*) tempBuffer; | |||
| unsigned int* l = (unsigned int*) left; | |||
| unsigned int* r = (unsigned int*) right; | |||
| for (int i = 0; i < numThisTime; ++i) | |||
| { | |||
| *left++ = littleEndian24Bit (src) << 8; | |||
| src += 3; | |||
| } | |||
| } | |||
| } | |||
| else if (bitsPerSample == 32) | |||
| { | |||
| const unsigned int* src = (const unsigned int*) tempBuffer; | |||
| unsigned int* l = (unsigned int*) left; | |||
| unsigned int* r = (unsigned int*) right; | |||
| if (numChannels > 1) | |||
| if (numChannels > 1) | |||
| { | |||
| if (l == 0) | |||
| { | |||
| if (l == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| ++src; | |||
| *r++ = swapIfBigEndian (*src++); | |||
| } | |||
| } | |||
| else if (r == 0) | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *l++ = (swapIfBigEndian (*src++) >> 1) | |||
| + (swapIfBigEndian (*src++) >> 1); | |||
| } | |||
| ++src; | |||
| *r++ = swapIfBigEndian (*src++); | |||
| } | |||
| else | |||
| } | |||
| else if (r == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *l++ = swapIfBigEndian (*src++); | |||
| *r++ = swapIfBigEndian (*src++); | |||
| } | |||
| *l++ = swapIfBigEndian (*src++); | |||
| ++src; | |||
| } | |||
| } | |||
| else | |||
| @@ -483,66 +450,71 @@ public: | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *l++ = swapIfBigEndian (*src++); | |||
| *r++ = swapIfBigEndian (*src++); | |||
| } | |||
| } | |||
| left = (int*)l; | |||
| right = (int*)r; | |||
| } | |||
| else if (bitsPerSample == 8) | |||
| else | |||
| { | |||
| const unsigned char* src = (const unsigned char*) tempBuffer; | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *l++ = swapIfBigEndian (*src++); | |||
| } | |||
| } | |||
| left = (int*)l; | |||
| right = (int*)r; | |||
| } | |||
| else if (bitsPerSample == 8) | |||
| { | |||
| const unsigned char* src = (const unsigned char*) tempBuffer; | |||
| if (numChannels > 1) | |||
| if (numChannels > 1) | |||
| { | |||
| if (left == 0) | |||
| { | |||
| if (left == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| ++src; | |||
| *right++ = ((int) *src++ - 128) << 24; | |||
| } | |||
| } | |||
| else if (right == 0) | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = ((int) *src++ - 128) << 24; | |||
| ++src; | |||
| } | |||
| ++src; | |||
| *right++ = ((int) *src++ - 128) << 24; | |||
| } | |||
| else | |||
| } | |||
| else if (right == 0) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = ((int) *src++ - 128) << 24; | |||
| *right++ = ((int) *src++ - 128) << 24; | |||
| } | |||
| *left++ = ((int) *src++ - 128) << 24; | |||
| ++src; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = ((int)*src++ - 128) << 24; | |||
| *left++ = ((int) *src++ - 128) << 24; | |||
| *right++ = ((int) *src++ - 128) << 24; | |||
| } | |||
| } | |||
| } | |||
| num -= numThisTime; | |||
| else | |||
| { | |||
| for (int i = numThisTime; --i >= 0;) | |||
| { | |||
| *left++ = ((int)*src++ - 128) << 24; | |||
| } | |||
| } | |||
| } | |||
| startOffsetInDestBuffer += numThisTime; | |||
| numSamples -= numThisTime; | |||
| } | |||
| if (numToDo < numSamples) | |||
| if (numSamples > 0) | |||
| { | |||
| int** destChan = destSamples; | |||
| while (*destChan != 0) | |||
| { | |||
| zeromem ((*destChan) + (startOffsetInDestBuffer + numToDo), | |||
| sizeof (int) * (numSamples - numToDo)); | |||
| ++destChan; | |||
| } | |||
| for (int i = numDestChannels; --i >= 0;) | |||
| if (destSamples[i] != 0) | |||
| zeromem (destSamples[i] + startOffsetInDestBuffer, | |||
| sizeof (int) * numSamples); | |||
| } | |||
| return true; | |||
| @@ -626,7 +626,7 @@ void AudioSampleBuffer::readFromAudioReader (AudioFormatReader* reader, | |||
| chans[2] = 0; | |||
| reader->read (chans, readerStartSample, numSamples); | |||
| reader->read (chans, 2, readerStartSample, numSamples, true); | |||
| if (! reader->usesFloatingPointData) | |||
| { | |||