mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
0935b39ced
The basic idea is to write out the signal that came in with the same number of channels as it had when it came in. Things get a bit more complicated when one output block may be derived from more than one input block, each having different numbers of channels. When this happens, the input blocks with fewer channels are upmixed, so as not to lose (or distort) any signal in the block with more channels. HRTFPanner no longer uses exponential decay (with time constant 20ms) for delay changes, but a smoother linear transition during cross-fade time (~45ms). --HG-- rename : content/media/webaudio/DelayProcessor.cpp => content/media/webaudio/DelayBuffer.cpp rename : content/media/webaudio/DelayProcessor.h => content/media/webaudio/DelayBuffer.h extra : rebase_source : 18453d631779cd7d0672b5325e110b107ab4237d
97 lines
3.5 KiB
C++
97 lines
3.5 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef DelayBuffer_h_
|
|
#define DelayBuffer_h_
|
|
|
|
#include "nsTArray.h"
|
|
#include "AudioSegment.h"
|
|
#include "mozilla/dom/AudioNodeBinding.h" // for ChannelInterpretation
|
|
|
|
namespace mozilla {
|
|
|
|
class DelayBuffer {
|
|
typedef dom::ChannelInterpretation ChannelInterpretation;
|
|
|
|
public:
|
|
// See WebAudioUtils::ComputeSmoothingRate() for frame to frame exponential
|
|
// |smoothingRate| multiplier.
|
|
DelayBuffer(int aMaxDelayTicks, double aSmoothingRate)
|
|
: mSmoothingRate(aSmoothingRate)
|
|
, mCurrentDelay(-1.0)
|
|
, mMaxDelayTicks(aMaxDelayTicks)
|
|
, mCurrentChunk(0)
|
|
// mLastReadChunk is initialized in EnsureBuffer
|
|
{
|
|
}
|
|
|
|
// Write a WEBAUDIO_BLOCK_SIZE block for aChannelCount channels.
|
|
void Write(const AudioChunk& aInputChunk);
|
|
|
|
// Read a block with an array of delays, in ticks, for each sample frame.
|
|
// Each delay must be > 0 and < MaxDelayTicks().
|
|
void Read(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
|
|
AudioChunk* aOutputChunk,
|
|
ChannelInterpretation aChannelInterpretation);
|
|
// Read a block with a constant delay, which will be smoothed with the
|
|
// previous delay. The delay must be > 0 and < MaxDelayTicks().
|
|
void Read(double aDelayTicks, AudioChunk* aOutputChunk,
|
|
ChannelInterpretation aChannelInterpretation);
|
|
|
|
// Read into one of the channels of aOutputChunk, given an array of
|
|
// delays in ticks. This is useful when delays are different on different
|
|
// channels. aOutputChunk must have already been allocated with at least as
|
|
// many channels as were in any of the blocks passed to Write().
|
|
void ReadChannel(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
|
|
const AudioChunk* aOutputChunk, uint32_t aChannel,
|
|
ChannelInterpretation aChannelInterpretation);
|
|
|
|
// Advance the buffer pointer
|
|
void NextBlock()
|
|
{
|
|
mCurrentChunk = (mCurrentChunk + 1) % mChunks.Length();
|
|
}
|
|
|
|
void Reset() {
|
|
mChunks.Clear();
|
|
mCurrentDelay = -1.0;
|
|
};
|
|
|
|
int MaxDelayTicks() const { return mMaxDelayTicks; }
|
|
|
|
private:
|
|
void ReadChannels(const double aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
|
|
const AudioChunk* aOutputChunk,
|
|
uint32_t aFirstChannel, uint32_t aNumChannelsToRead,
|
|
ChannelInterpretation aChannelInterpretation);
|
|
bool EnsureBuffer();
|
|
int PositionForDelay(int aDelay);
|
|
int ChunkForPosition(int aPosition);
|
|
int OffsetForPosition(int aPosition);
|
|
int ChunkForDelay(int aDelay);
|
|
void UpdateUpmixChannels(int aNewReadChunk, uint32_t channelCount,
|
|
ChannelInterpretation aChannelInterpretation);
|
|
|
|
// Circular buffer for capturing delayed samples.
|
|
FallibleTArray<AudioChunk> mChunks;
|
|
// Cache upmixed channel arrays.
|
|
nsAutoTArray<const void*,GUESS_AUDIO_CHANNELS> mUpmixChannels;
|
|
double mSmoothingRate;
|
|
// Current delay, in fractional ticks
|
|
double mCurrentDelay;
|
|
// Maximum delay, in ticks
|
|
int mMaxDelayTicks;
|
|
// The current position in the circular buffer. The next write will be to
|
|
// this chunk, and the next read may begin before this chunk.
|
|
int mCurrentChunk;
|
|
// The chunk owning the pointers in mUpmixChannels
|
|
int mLastReadChunk;
|
|
};
|
|
|
|
} // mozilla
|
|
|
|
#endif // DelayBuffer_h_
|