bug 1199559 write offline buffer in a format suitable for direct use by AudioBuffer r=padenot

saving a copy.

--HG--
extra : rebase_source : e3d477c46ca365f0d65b47355b5ecf42d81a056b
This commit is contained in:
Karl Tomlinson 2015-08-27 21:32:41 +12:00
Родитель 90d515b961
Коммит d94d65b40b
1 изменённых файлов: 17 добавлений и 34 удалений

Просмотреть файл

@ -32,8 +32,6 @@ static uint8_t gWebAudioOutputKey;
class OfflineDestinationNodeEngine final : public AudioNodeEngine
{
public:
typedef AutoFallibleTArray<nsAutoArrayPtr<float>, 2> InputChannels;
OfflineDestinationNodeEngine(AudioDestinationNode* aNode,
uint32_t aNumberOfChannels,
uint32_t aLength,
@ -61,21 +59,14 @@ public:
// These allocations might fail if content provides a huge number of
// channels or size, but it's OK since we'll deal with the failure
// gracefully.
if (mInputChannels.SetLength(mNumberOfChannels, fallible)) {
for (uint32_t i = 0; i < mNumberOfChannels; ++i) {
mInputChannels[i] = new (fallible) float[mLength];
if (!mInputChannels[i]) {
mInputChannels.Clear();
break;
}
}
}
mBuffer = ThreadSharedFloatArrayBufferList::
Create(mNumberOfChannels, mLength, fallible);
mBufferAllocated = true;
}
// Handle the case of allocation failure in the input buffer
if (mInputChannels.IsEmpty()) {
if (mBuffer) {
return;
}
@ -88,33 +79,28 @@ public:
// Record our input buffer
MOZ_ASSERT(mWriteIndex < mLength, "How did this happen?");
const uint32_t duration = std::min(WEBAUDIO_BLOCK_SIZE, mLength - mWriteIndex);
const uint32_t commonChannelCount = std::min(mInputChannels.Length(),
aInput.mChannelData.Length());
// First, copy as many channels in the input as we have
for (uint32_t i = 0; i < commonChannelCount; ++i) {
if (aInput.IsNull()) {
PodZero(mInputChannels[i] + mWriteIndex, duration);
const uint32_t inputChannelCount = aInput.mChannelData.Length();
for (uint32_t i = 0; i < mNumberOfChannels; ++i) {
float* outputData = mBuffer->GetDataForWrite(i) + mWriteIndex;
if (aInput.IsNull() || i >= inputChannelCount) {
PodZero(outputData, duration);
} else {
const float* inputBuffer = static_cast<const float*>(aInput.mChannelData[i]);
if (duration == WEBAUDIO_BLOCK_SIZE) {
// Use the optimized version of the copy with scale operation
AudioBlockCopyChannelWithScale(inputBuffer, aInput.mVolume,
mInputChannels[i] + mWriteIndex);
outputData);
} else {
if (aInput.mVolume == 1.0f) {
PodCopy(mInputChannels[i] + mWriteIndex, inputBuffer, duration);
PodCopy(outputData, inputBuffer, duration);
} else {
for (uint32_t j = 0; j < duration; ++j) {
mInputChannels[i][mWriteIndex + j] = aInput.mVolume * inputBuffer[j];
outputData[j] = aInput.mVolume * inputBuffer[j];
}
}
}
}
}
// Then, silence all of the remaining channels
for (uint32_t i = commonChannelCount; i < mInputChannels.Length(); ++i) {
PodZero(mInputChannels[i] + mWriteIndex, duration);
}
mWriteIndex += duration;
if (mWriteIndex >= mLength) {
@ -165,14 +151,11 @@ public:
// Create the input buffer
ErrorResult rv;
nsRefPtr<AudioBuffer> renderedBuffer =
AudioBuffer::Create(context, mInputChannels.Length(),
mLength, mSampleRate, cx, rv);
AudioBuffer::Create(context, mNumberOfChannels, mLength, mSampleRate,
mBuffer.forget(), cx, rv);
if (rv.Failed()) {
return;
}
for (uint32_t i = 0; i < mInputChannels.Length(); ++i) {
renderedBuffer->SetRawChannelContents(i, mInputChannels[i]);
}
aNode->ResolvePromise(renderedBuffer);
@ -186,7 +169,7 @@ public:
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override
{
size_t amount = AudioNodeEngine::SizeOfExcludingThis(aMallocSizeOf);
amount += mInputChannels.ShallowSizeOfExcludingThis(aMallocSizeOf);
amount += mBuffer->SizeOfIncludingThis(aMallocSizeOf);
return amount;
}
@ -196,11 +179,11 @@ public:
}
private:
// The input to the destination node is recorded in the mInputChannels buffer.
// The input to the destination node is recorded in mBuffer.
// When this buffer fills up with mLength frames, the buffered input is sent
// to the main thread in order to dispatch OfflineAudioCompletionEvent.
InputChannels mInputChannels;
// An index representing the next offset in mInputChannels to be written to.
nsRefPtr<ThreadSharedFloatArrayBufferList> mBuffer;
// An index representing the next offset in mBuffer to be written to.
uint32_t mWriteIndex;
uint32_t mNumberOfChannels;
// How many frames the OfflineAudioContext intends to produce.