зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
90d515b961
Коммит
d94d65b40b
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче