void AudioNodeStream::ObtainInputBlock(AudioBlock& aTmpChunk, uint32_t aPortIndex) { uint32_t inputCount = mInputs.Length(); uint32_t outputChannelCount = 1; nsAutoTArray<const AudioBlock*,250> inputChunks; for (uint32_t i = 0; i < inputCount; ++i) { if (aPortIndex != mInputs[i]->InputNumber()) { // This input is connected to a different port continue; } MediaStream* s = mInputs[i]->GetSource(); AudioNodeStream* a = static_cast<AudioNodeStream*>(s); MOZ_ASSERT(a == s->AsAudioNodeStream()); if (a->IsAudioParamStream()) { continue; } const AudioBlock* chunk = &a->mLastChunks[mInputs[i]->OutputNumber()]; MOZ_ASSERT(chunk); if (chunk->IsNull() || chunk->mChannelData.IsEmpty()) { continue; } inputChunks.AppendElement(chunk); outputChannelCount = GetAudioChannelsSuperset(outputChannelCount, chunk->ChannelCount()); } outputChannelCount = ComputedNumberOfChannels(outputChannelCount); uint32_t inputChunkCount = inputChunks.Length(); if (inputChunkCount == 0 || (inputChunkCount == 1 && inputChunks[0]->ChannelCount() == 0)) { aTmpChunk.SetNull(WEBAUDIO_BLOCK_SIZE); return; } if (inputChunkCount == 1 && inputChunks[0]->ChannelCount() == outputChannelCount) { aTmpChunk = *inputChunks[0]; return; } if (outputChannelCount == 0) { aTmpChunk.SetNull(WEBAUDIO_BLOCK_SIZE); return; } aTmpChunk.AllocateChannels(outputChannelCount); // The static storage here should be 1KB, so it's fine nsAutoTArray<float, GUESS_AUDIO_CHANNELS*WEBAUDIO_BLOCK_SIZE> downmixBuffer; for (uint32_t i = 0; i < inputChunkCount; ++i) { AccumulateInputChunk(i, *inputChunks[i], &aTmpChunk, &downmixBuffer); } }
void AudioNodeStream::ObtainInputBlock(AudioChunk& aTmpChunk, uint32_t aPortIndex) { uint32_t inputCount = mInputs.Length(); uint32_t outputChannelCount = 1; nsAutoTArray<AudioChunk*,250> inputChunks; for (uint32_t i = 0; i < inputCount; ++i) { if (aPortIndex != mInputs[i]->InputNumber()) { // This input is connected to a different port continue; } MediaStream* s = mInputs[i]->GetSource(); AudioNodeStream* a = static_cast<AudioNodeStream*>(s); MOZ_ASSERT(a == s->AsAudioNodeStream()); if (a->IsAudioParamStream()) { continue; } // It is possible for mLastChunks to be empty here, because `a` might be a // AudioNodeStream that has not been scheduled yet, because it is further // down the graph _but_ as a connection to this node. Because we enforce the // presence of at least one DelayNode, with at least one block of delay, and // because the output of a DelayNode when it has been fed less that // `delayTime` amount of audio is silence, we can simply continue here, // because this input would not influence the output of this node. Next // iteration, a->mLastChunks.IsEmpty() will be false, and everthing will // work as usual. if (a->mLastChunks.IsEmpty()) { continue; } AudioChunk* chunk = &a->mLastChunks[mInputs[i]->OutputNumber()]; MOZ_ASSERT(chunk); if (chunk->IsNull() || chunk->mChannelData.IsEmpty()) { continue; } inputChunks.AppendElement(chunk); outputChannelCount = GetAudioChannelsSuperset(outputChannelCount, chunk->mChannelData.Length()); } outputChannelCount = ComputedNumberOfChannels(outputChannelCount); uint32_t inputChunkCount = inputChunks.Length(); if (inputChunkCount == 0 || (inputChunkCount == 1 && inputChunks[0]->mChannelData.Length() == 0)) { aTmpChunk.SetNull(WEBAUDIO_BLOCK_SIZE); return; } if (inputChunkCount == 1 && inputChunks[0]->mChannelData.Length() == outputChannelCount) { aTmpChunk = *inputChunks[0]; return; } if (outputChannelCount == 0) { aTmpChunk.SetNull(WEBAUDIO_BLOCK_SIZE); return; } AllocateAudioBlock(outputChannelCount, &aTmpChunk); // The static storage here should be 1KB, so it's fine nsAutoTArray<float, GUESS_AUDIO_CHANNELS*WEBAUDIO_BLOCK_SIZE> downmixBuffer; for (uint32_t i = 0; i < inputChunkCount; ++i) { AccumulateInputChunk(i, *inputChunks[i], &aTmpChunk, &downmixBuffer); } }