AudioChunkList.cpp |
|
4129 |
AudioChunkList.h |
AudioChunkList provides a way to have preallocated audio buffers in
AudioSegment. The idea is that the amount of AudioChunks is created in
advance. Each AudioChunk is able to hold a specific amount of audio
(capacity). The total capacity of AudioChunkList is specified by the number
of AudioChunks. The important aspect of the AudioChunkList is that
preallocates everything and reuse the same chunks similar to a ring buffer.
Why the whole AudioChunk is preallocated and not some raw memory buffer? This
is due to the limitations of MediaTrackGraph. The way that MTG works depends
on `AudioSegment`s to convey the actual audio data. An AudioSegment consists
of AudioChunks. The AudioChunk is built in a way, that owns and allocates the
audio buffers. Thus, since the use of AudioSegment is mandatory if the audio
data was in a different form, the only way to use it from the audio thread
would be to create the AudioChunk there. That would result in a copy
operation (not very important) and most of all an allocation of the audio
buffer in the audio thread. This happens in many places inside MTG it's a bad
practice, though, and it has been avoided due to the AudioChunkList.
After construction the sample format must be set, when it is available. It
can be set in the audio thread. Before setting the sample format is not
possible to use any method of AudioChunkList.
Every AudioChunk in the AudioChunkList is preallocated with a capacity of 128
frames of float audio. Nevertheless, the sample format is not available at
that point. Thus if the sample format is set to short, the capacity of each
chunk changes to 256 number of frames, and the total duration becomes twice
big. There are methods to get the chunk capacity and total capacity in frames
and must always be used.
Two things to note. First, when the channel count changes everything is
recreated which means reallocations. Second, the total capacity might differs
from the requested total capacity for two reasons. First, if the sample
format is set to short and second because the number of chunks in the list
divides exactly the final total capacity. The corresponding method must
always be used to query the total capacity.
|
5194 |
AudioDriftCorrection.cpp |
|
7727 |
AudioDriftCorrection.h |
Correct the drift between two independent clocks, the source, and the target
clock. The target clock is the master clock so the correction syncs the drift
of the source clock to the target. The nominal sampling rates of source and
target must be provided.
It works with AudioSegment in order to be able to be used from the
MediaTrackGraph/MediaTrack. The audio buffers are pre-allocated so the only
new allocation taking place during operation happens if the input buffer
outgrows the memory allocated. The preallocation capacity is 100ms for input
and 100ms for output. The class consists of DriftController and
AudioResampler check there for more details.
The class is not thread-safe. The construction can happen in any thread but
the member method must be used in a single thread that can be different than
the construction thread. Appropriate for being used in the high priority
audio thread.
|
3189 |
AudioResampler.cpp |
|
3959 |
AudioResampler.h |
Audio Resampler is a resampler able to change the input rate and channels
count on the fly. The API is simple and it is based in AudioSegment in order
to be used MTG. Memory allocations, for input and output buffers, will happen
in the constructor, when channel count changes and if the amount of input
data outgrows the input buffer. The memory is recycled in order to avoid
reallocations. It also supports prebuffering of silence. It consists of
DynamicResampler and AudioChunkList so please read their documentation if you
are interested in more details.
The output buffer is preallocated and returned in the form of AudioSegment.
The intention is to be used directly in a MediaTrack. Since an AudioChunk
must no be "shared" in order to be written, the AudioSegment returned by
resampler method must be cleaned up in order to be able for the `AudioChunk`s
that it consists of to be reused. For `MediaTrack::mSegment` this happens
every ~50ms (look at MediaTrack::AdvanceTimeVaryingValuesToCurrentTime). Thus
memory capacity of 100ms has been preallocated for internal input and output
buffering. Note that the amount of memory used for input buffering may
increase if needed.
|
3910 |
DriftController.cpp |
|
14035 |
DriftController.h |
DriftController calculates the divergence of the source clock from its
nominal (provided) rate compared to that of the target clock, which drives
the calculations.
The DriftController looks at how the current buffering level differs from the
desired buffering level and sets a corrected source rate. A resampler should
be configured to resample from the corrected source rate to the nominal
target rate. It assumes that the resampler is initially configured to
resample from the nominal source rate to the nominal target rate.
The pref `media.clock drift.buffering` can be used to configure the minimum
initial desired internal buffering. Right now it is at 50ms. A larger desired
buffering level will be used if deemed necessary based on input device
latency, reported or observed. It will also be increased as a response to an
underrun, since that indicates the buffer was too small.
|
7132 |
DynamicResampler.cpp |
|
9891 |
DynamicResampler.h |
DynamicResampler allows updating on the fly the output sample rate and the
number of channels. In addition to that, it maintains an internal buffer for
the input data and allows pre-buffering as well. The Resample() method
strives to provide the requested number of output frames by using the input
data including any pre-buffering. If there are fewer frames in the internal
buffer than is requested, the internal buffer is padded with enough silence
to allow the requested to be resampled and returned.
Input data buffering makes use of the AudioRingBuffer. The capacity of the
buffer is initially 100ms of audio and it is pre-allocated during
SetSampleFormat(). Should the input data grow beyond that, the input buffer
is re-allocated on the fly. In addition to that, due to special feature of
AudioRingBuffer, no extra copies take place when the input data is fed to the
resampler.
The sample format must be set before using any method.
The DynamicResampler is not thread-safe, so all the methods appart from the
constructor must be called on the same thread.
|
14071 |
gtest |
|
|
moz.build |
|
673 |
plot.py |
Takes a csv file of DriftControllerGraphs data
(from a single DriftController instance) and plots
them into plot.html in the current working directory.
The easiest way to produce the data is with MOZ_LOG:
MOZ_LOG=raw,sync,DriftControllerGraphs:5 \
MOZ_LOG_FILE=/tmp/driftcontrol.csv \
./mach gtest '*AudioDrift*StepResponse' |
5697 |