void Reverb::initialize(const nsTArray<const float*>& impulseResponseBuffer, size_t impulseResponseBufferLength, size_t maxFFTSize, bool useBackgroundThreads) { m_impulseResponseLength = impulseResponseBufferLength; // The reverb can handle a mono impulse response and still do stereo processing size_t numResponseChannels = impulseResponseBuffer.Length(); m_convolvers.SetCapacity(numResponseChannels); int convolverRenderPhase = 0; for (size_t i = 0; i < numResponseChannels; ++i) { const float* channel = impulseResponseBuffer[i]; size_t length = impulseResponseBufferLength; nsAutoPtr<ReverbConvolver> convolver(new ReverbConvolver(channel, length, maxFFTSize, convolverRenderPhase, useBackgroundThreads)); m_convolvers.AppendElement(convolver.forget()); convolverRenderPhase += WEBAUDIO_BLOCK_SIZE; } // For "True" stereo processing we allocate a temporary buffer to avoid repeatedly allocating it in the process() method. // It can be bad to allocate memory in a real-time thread. if (numResponseChannels == 4) { m_tempBuffer.AllocateChannels(2); WriteZeroesToAudioBlock(&m_tempBuffer, 0, WEBAUDIO_BLOCK_SIZE); } }
/** * Fill aOutput with as many zero frames as we can, and advance * aOffsetWithinBlock and aCurrentPosition based on how many frames we write. * This will never advance aOffsetWithinBlock past WEBAUDIO_BLOCK_SIZE or * aCurrentPosition past aMaxPos. This function knows when it needs to * allocate the output buffer, and also optimizes the case where it can avoid * memory allocations. */ void FillWithZeroes(AudioChunk* aOutput, uint32_t aChannels, uint32_t* aOffsetWithinBlock, TrackTicks* aCurrentPosition, TrackTicks aMaxPos) { uint32_t numFrames = std::min(WEBAUDIO_BLOCK_SIZE - *aOffsetWithinBlock, uint32_t(aMaxPos - *aCurrentPosition)); if (numFrames == WEBAUDIO_BLOCK_SIZE) { aOutput->SetNull(numFrames); } else { if (aOutput->IsNull()) { AllocateAudioBlock(aChannels, aOutput); } WriteZeroesToAudioBlock(aOutput, *aOffsetWithinBlock, numFrames); } *aOffsetWithinBlock += numFrames; *aCurrentPosition += numFrames; }
/** * Fill aOutput with as many zero frames as we can, and advance * aOffsetWithinBlock and aCurrentPosition based on how many frames we write. * This will never advance aOffsetWithinBlock past WEBAUDIO_BLOCK_SIZE or * aCurrentPosition past aMaxPos. This function knows when it needs to * allocate the output buffer, and also optimizes the case where it can avoid * memory allocations. */ void FillWithZeroes(AudioBlock* aOutput, uint32_t aChannels, uint32_t* aOffsetWithinBlock, StreamTime* aCurrentPosition, StreamTime aMaxPos) { MOZ_ASSERT(*aCurrentPosition < aMaxPos); uint32_t numFrames = std::min<StreamTime>(WEBAUDIO_BLOCK_SIZE - *aOffsetWithinBlock, aMaxPos - *aCurrentPosition); if (numFrames == WEBAUDIO_BLOCK_SIZE || !aChannels) { aOutput->SetNull(numFrames); } else { if (*aOffsetWithinBlock == 0) { aOutput->AllocateChannels(aChannels); } WriteZeroesToAudioBlock(aOutput, *aOffsetWithinBlock, numFrames); } *aOffsetWithinBlock += numFrames; *aCurrentPosition += numFrames; }