| @@ -100,6 +100,18 @@ bool AudioFormatReader::read (int* const* destSamples, | |||
| return true; | |||
| } | |||
| static void readChannels (AudioFormatReader& reader, | |||
| int** const chans, AudioSampleBuffer* const buffer, | |||
| const int startSample, const int numSamples, | |||
| const int64 readerStartSample, const int numTargetChannels) | |||
| { | |||
| for (int j = 0; j < numTargetChannels; ++j) | |||
| chans[j] = reinterpret_cast<int*> (buffer->getSampleData (j, startSample)); | |||
| chans[numTargetChannels] = nullptr; | |||
| reader.read (chans, numTargetChannels, readerStartSample, numSamples, true); | |||
| } | |||
| void AudioFormatReader::read (AudioSampleBuffer* buffer, | |||
| int startSample, | |||
| int numSamples, | |||
| @@ -113,49 +125,51 @@ void AudioFormatReader::read (AudioSampleBuffer* buffer, | |||
| if (numSamples > 0) | |||
| { | |||
| const int numTargetChannels = buffer->getNumChannels(); | |||
| int* chans[3]; | |||
| if (useReaderLeftChan == useReaderRightChan) | |||
| if (numTargetChannels <= 2) | |||
| { | |||
| chans[0] = reinterpret_cast<int*> (buffer->getSampleData (0, startSample)); | |||
| chans[1] = (numChannels > 1 && numTargetChannels > 1) ? reinterpret_cast<int*> (buffer->getSampleData (1, startSample)) : nullptr; | |||
| } | |||
| else if (useReaderLeftChan || (numChannels == 1)) | |||
| { | |||
| chans[0] = reinterpret_cast<int*> (buffer->getSampleData (0, startSample)); | |||
| chans[1] = nullptr; | |||
| } | |||
| else if (useReaderRightChan) | |||
| { | |||
| chans[0] = nullptr; | |||
| chans[1] = reinterpret_cast<int*> (buffer->getSampleData (0, startSample)); | |||
| } | |||
| int* const dest0 = reinterpret_cast<int*> (buffer->getSampleData (0, startSample)); | |||
| int* const dest1 = reinterpret_cast<int*> (numTargetChannels > 1 ? buffer->getSampleData (1, startSample) : nullptr); | |||
| int* chans[3]; | |||
| chans[2] = nullptr; | |||
| if (useReaderLeftChan == useReaderRightChan) | |||
| { | |||
| chans[0] = dest0; | |||
| chans[1] = numChannels > 1 ? dest1 : nullptr; | |||
| } | |||
| else if (useReaderLeftChan || (numChannels == 1)) | |||
| { | |||
| chans[0] = dest0; | |||
| chans[1] = nullptr; | |||
| } | |||
| else if (useReaderRightChan) | |||
| { | |||
| chans[0] = nullptr; | |||
| chans[1] = dest0; | |||
| } | |||
| read (chans, 2, readerStartSample, numSamples, true); | |||
| chans[2] = nullptr; | |||
| read (chans, 2, readerStartSample, numSamples, true); | |||
| if (! usesFloatingPointData) | |||
| // if the target's stereo and the source is mono, dupe the first channel.. | |||
| if (numTargetChannels > 1 && (chans[0] == nullptr || chans[1] == nullptr)) | |||
| memcpy (dest1, dest0, sizeof (float) * (size_t) numSamples); | |||
| } | |||
| else if (numTargetChannels <= 64) | |||
| { | |||
| for (int j = 0; j < 2; ++j) | |||
| { | |||
| if (float* const d = reinterpret_cast <float*> (chans[j])) | |||
| { | |||
| const float multiplier = 1.0f / 0x7fffffff; | |||
| for (int i = 0; i < numSamples; ++i) | |||
| d[i] = *reinterpret_cast<int*> (d + i) * multiplier; | |||
| } | |||
| } | |||
| int* chans[65]; | |||
| readChannels (*this, chans, buffer, startSample, numSamples, readerStartSample, numTargetChannels); | |||
| } | |||
| if (numTargetChannels > 1 && (chans[0] == nullptr || chans[1] == nullptr)) | |||
| else | |||
| { | |||
| // if this is a stereo buffer and the source was mono, dupe the first channel.. | |||
| memcpy (buffer->getSampleData (1, startSample), | |||
| buffer->getSampleData (0, startSample), | |||
| sizeof (float) * (size_t) numSamples); | |||
| HeapBlock<int*> chans (numTargetChannels); | |||
| readChannels (*this, chans, buffer, startSample, numSamples, readerStartSample, numTargetChannels); | |||
| } | |||
| if (! usesFloatingPointData) | |||
| for (int j = 0; j < numTargetChannels; ++j) | |||
| if (float* const d = buffer->getSampleData (j, startSample)) | |||
| FloatVectorOperations::convertFixedToFloat (d, reinterpret_cast<const int*> (d), 1.0f / 0x7fffffff, numSamples); | |||
| } | |||
| } | |||