ReverbAccumulationBuffer often produces unaligned buffers due to the way
it wraps around results. This modifies AudioBufferAddWithScale on SSE2
platforms to handle unaligned buffers by performing scalar operations
until both the input and output buffers are aligned to 16 bytes. It then
does as many vector operations as possible and switches back to scalar
operations for anything that is left over.
This could also be done within the ReverbAccumulationBuffer code but doing
it directly within the AudioNodeEngine code makes it available to other
callers in the future, at the cost of a few extra branches in the case
where everything was aligned anyway.
MozReview-Commit-ID: Ky0uIe5LMVq
--HG--
extra : rebase_source : 0c9970807262c8a13be5ad866e470d78ff6c1bb9
Assuming that Bug 1266405 fixed the underlying cause for the unaligned
buffers we were seeing, the checks in AudioBufferAddWithScale and
AudioBlockCopyWithScale shoudl no longer be necessary.
MozReview-Commit-ID: 4OQ4qQVjEP3
--HG--
extra : rebase_source : fda9b1f7604a2732c9dea4985bfd47ce9293bc0f
It's an annotation that is used a lot, and should be used even more, so a
shorter name is better.
MozReview-Commit-ID: 1VS4Dney4WX
--HG--
extra : rebase_source : b26919c1b0fcb32e5339adeef5be5becae6032cf
This fixes some division by zero errors introduced by Bug 1222405 when the
fundamental frequency is zero.
MozReview-Commit-ID: A7qfJjJOJ3H
--HG--
extra : rebase_source : 02506b547c5f78495c449bba9f476d3f42cf7ed0
Rename StreamBuffer to StreamTracks. We still need a place to keep the track information in every MediaStream, even the StreamBuffer::Track::mSegment is empty.
--HG--
rename : dom/media/StreamBuffer.cpp => StreamTracks.cpp
rename : dom/media/StreamBuffer.h => StreamTracks.h
This adds alignment checks to fallback to scalar operations if the
received buffers are not properly aligned. Bug 1266112 is the follow on
to either fix the alignment problem or add a vector path for the aligned
portion of the buffers.
MozReview-Commit-ID: 5HCXzipXlqD
--HG--
extra : rebase_source : 0dff8258c4cc0d468c18267680f053ff1a240ad5
This updates the original SSE2 implementations to match the current
AudioNodeEngine API and adds them to the build.
MozReview-Commit-ID: KULBD7KTr3n
--HG--
extra : rebase_source : 05adf8a26cb33a4b9d9c9d200d3ed8b1831f6995
To be able to use SSE2 routines, we need to audio buffers to be allocated
on 16 byte boundaries.
MozReview-Commit-ID: 2mjxMWqysFd
--HG--
extra : rebase_source : 8bd7d48b767b7bcfa5874061586b9b41c26a18ae
Otherwise we don't get an accurate nr-of-nonzero-samples measurement as
the sources now lock on to a track (main thread) before attaching a
listener.
MozReview-Commit-ID: Jhsr6kgkdcM
--HG--
extra : rebase_source : d94804a601936f456b6bf1b5abc927e9a0bd0329
This lets us know the track's TrackID in the destination stream before
the input port has been processed.
For sanity we only allow mapping to a destination TrackID if the
destination stream does not have any TRACK_ANY input ports already
assigned to it as that can cause intermittent TrackID collisions.
MozReview-Commit-ID: ClFyQl0nYFC
--HG--
extra : rebase_source : 25fa0f34cb4fa9293a572bff03fe005c33be0195
This lets a MediaStreamTrack communicate with its source/producer on the
main thread. It's for now used for stopping a track at the source and
retrieving some metadata, but it could also be a link between actual
sinks of a track and the source, to for instance let the source optimize
by scaling down the resolution when all sinks want lowres-video.
MozReview-Commit-ID: D4SJLr0aqhJ
--HG--
extra : rebase_source : ea511b5c86ca4836bfa980825f04617fef498261
mDestination is cleared during unlink, which means that after that point the
window can't do much with the AudioContext, nor should need to do so.
MozReview-Commit-ID: E45aCpEfJEu
--HG--
extra : rebase_source : cafd502552b7126bcdddc2544c4c28c1b62a701f
The new routine actually multiplies by two for consistency with the other FFT
routines in use.
MozReview-Commit-ID: Hk2Dg3fR2cQ
--HG--
extra : rebase_source : 08bdbbd65d372a3d0eb69568313cec33ccea6af3
We currently rebuild the BandLimitedTables whenever we encounter a lower
fundamental frequency but it is only necessary to rebuild the tables if we
can fit more partials below the Nyquist frequency. Rebuilding the tables
unnecessarily can cause performance problems, particularly in the case where
the frequency is continually lowered.
--HG--
extra : rebase_source : e53c773d53f723d5b34270d6214a5812ec1eb7f0
This builds the band limited tables for each range index individually as
required.
--HG--
extra : rebase_source : 022665e3b83b82bcdcec3cabf3ddda9c2dce2ebf
If we build the band limited tables after the fundamental frequency is known,
we can exclude partials that are above the nyquist frequency for the sampling
frequency being used.
We rebuild the band limited tables each time we see a request for data for a
lower fundamental frequency so we have the required partials.
--HG--
extra : rebase_source : 067075c7c8a90580650bf850c50ca7d8fc1eb6ff
We need to store the components used to create the PeriodicWave for later use
if we want to be able to build the band limited tables lazily.
--HG--
extra : rebase_source : d760433e6fe5490a60da761be7e2148a6504d20d
The patch changes all uses of SizeOfIncludingThisMustBeUnshared() to
SizeOfIncludingThisIfUnshared(). This incurs the (tiny) cost of an unnecessary
IsReadonly() check for guaranteed-unshared strings, but avoids the possible
assertion failures that would occur when MustBeUnshared() was used incorrectly
on shared strings, which is an easy mistake to make.
--HG--
extra : rebase_source : b1e91f1c19bcbe0521b0ce461d6c90512ca938ef
The zeroth component is not removed from the BufferComplexMultiply() call so
as not to disrupt alignment.
The mOutputBuffer[halfSize].i assertions are removed because the code no
longer uses these components, and so their values are irrelevant.
--HG--
extra : rebase_source : 96014bdb66a86e1d764979f7b1a313c24196a60b
extra : histedit_source : 59ef41301d48a7f80798d8dbecc43aa85703c26f
This increases the maximum PeriodicWave size to 8192 and adds an optimization
to use 8192 elements only in the case where we receive more than 4096
components. In accordance with the spec, a maximum number of components is no
longer enforced.
--HG--
extra : rebase_source : ecb9a401fabdb14f23f690c44944ece434599055
Efficiency is proportional to stage size, so start with the largest size
possible.
--HG--
extra : rebase_source : 34915efce1eb94e18f53adf35dc939301242467a
Now, the most FFT work that happens during one realtime processing block is
when one 2048-size stage and the 256-size stage are performed at the same
phase-offset. Before FFT timing was controlled by initial input buffer offset
(bug 1221831), two 1024-size stages as well as the 512- and 256-size stages
performed FFTs at one offset. Thus, the maximum work in one block is reduced
by a ratio of about 11 to 9.
Measurements also indicate a similar reduction in total rendering thread
CPU usage.
Previously the alignment of the eleven 1024-size realtime stages was such
that, in three consecutive blocks, two 1024-size stages would peform their
FFTs. Now, the 2048-size stages is aligned so that none of these perform
their FFTs in consecutive blocks.
--HG--
extra : rebase_source : 7265374c1642661db1d4f4d630ddc8294be689c7
as with the main thread.
The comment was incomplete as ReverbConvolverStage also supports multiples of
the FFT halfsize, but only values up to WEBAUDIO_BLOCK_SIZE.
--HG--
extra : rebase_source : 34f11834dd425075e8948f47dcc5283dcb50fc42
This modifies the special case code for pan == 0.0f to apply the input gain.
--HG--
extra : commitid : LAEwrqMnjQi
extra : rebase_source : 735cabd0f9bc7a857a8382c712329e8353b88ad0
This is in the mochitest suite so that Android and B2G tests can run it, but
designed so that it can be moved to web-platform-tests when they run on all
platforms.
--HG--
extra : rebase_source : 775f1d9e4122d52cd58c0d6893681d31268cb715
BufferComplexMultiply knows nothing about this format and so ends up
corrupting the DC coefficient if packed Nyquists are multiplied.
--HG--
extra : rebase_source : feccac4be8d278dc0be020185065a1a9fa596d9c
https://github.com/WebAudio/web-audio-api/issues/304
NotSupportedError is chosen for more sensible meaning and consistency with
other nodes.
--HG--
extra : rebase_source : a5b8b8af0aeb3751d299b5fe785afb9a99fe5dea
(Doing the extra ProcessBlock for the sake of downstream nodes was unnecessary
even before the inactive check was delayed until after their processing, because
downstream nodes would have only had null chunks to process anyway.)
--HG--
extra : rebase_source : d1dd8a228a23520a23e77e29ae3d5040e6505eb8
Since changes for bug 1217625, the node and downstream nodes won't be made
inactive until after downstream nodes have done their processing, and so there
is no need to wait for the first silent output block.
This essentially reverts 5c607f3f39d55544838f3111ede9e11a00d3c25e.
--HG--
extra : rebase_source : f449c427b580239f9072cc7c580585f10b69608f
Sometimes we'll need an initial suspended count of 2, which is not supported
by this API, but this is not necessary anyway.
--HG--
extra : rebase_source : 56ecca7c14025ea7e18ba9a20e0b7725a610b429
This will allow streams to be suspended when they are discovered inactive.
Suspending is not possible while iterating over stream lists for processing.
The approach of delaying the transition to inactive state may result in a
couple of extra processing iterations, but can save on the number of messages
that need to be created when compared to the approach of traversing downstream
nodes during stream processing.
--HG--
extra : rebase_source : b6707da5afa9323058b3f70b7743c13380618dad
because base class methods will not be safe with different Elements() and
Length() methods.
--HG--
extra : rebase_source : 7616f0eb12e1d8098620682f6eb9b4c5f40f873f
ratioDen can be large when playbackRate is low.
Subsample skipping is limited to uint32_t values supported by speex resampler.
--HG--
extra : rebase_source : 26a14f212b5fd3fdd62820f458db3a7cf3673e93
extra : histedit_source : 733829a4b2ba6aab7c651f362dbc47553f9dfc59
"The behavior of an expression of the form E1 op = E2 is equivalent to E1 = E1
op E2 except that E1 is evaluated only once", which means that the subtraction
of -= was happening before conversion from double to unsigned int.
The "+ 0.5" was subtracted before the truncation toward zero, causing rounding
to nearest minus one, except when nearest was zero.
--HG--
extra : rebase_source : 3b2335da7a244245ea2fcf5c80760dc1645e6dae
The bulk of this commit was generated with a script, executed at the top
level of a typical source code checkout. The only non-machine-generated
part was modifying MFBT's moz.build to reflect the new naming.
CLOSED TREE makes big refactorings like this a piece of cake.
# The main substitution.
find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \
xargs perl -p -i -e '
s/nsRefPtr\.h/RefPtr\.h/g; # handle includes
s/nsRefPtr ?</RefPtr</g; # handle declarations and variables
'
# Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h.
perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h
# Handle nsRefPtr.h itself, a couple places that define constructors
# from nsRefPtr, and code generators specially. We do this here, rather
# than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename
# things like nsRefPtrHashtable.
perl -p -i -e 's/nsRefPtr/RefPtr/g' \
mfbt/nsRefPtr.h \
xpcom/glue/nsCOMPtr.h \
xpcom/base/OwningNonNull.h \
ipc/ipdl/ipdl/lower.py \
ipc/ipdl/ipdl/builtin.py \
dom/bindings/Codegen.py \
python/lldbutils/lldbutils/utils.py
# In our indiscriminate substitution above, we renamed
# nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up.
find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \
xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g'
if [ -d .git ]; then
git mv mfbt/nsRefPtr.h mfbt/RefPtr.h
else
hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h
fi
--HG--
rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
This commit was generated using the following script, executed at the
top level of a typical source code checkout.
# Don't modify select files in mfbt/ because it's not worth trying to
# tease out the dependencies currently.
#
# Don't modify anything in media/gmp-clearkey/0.1/ because those files
# use their own RefPtr, defined in their own RefCounted.h.
find . -name '*.cpp' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \
grep -v 'mfbt/RefPtr.h' | \
grep -v 'mfbt/nsRefPtr.h' | \
grep -v 'mfbt/RefCounted.h' | \
grep -v 'media/gmp-clearkey/0.1/' | \
xargs perl -p -i -e '
s/mozilla::RefPtr/nsRefPtr/g; # handle declarations in headers
s/\bRefPtr</nsRefPtr</g; # handle local variables in functions
s#mozilla/RefPtr.h#mozilla/nsRefPtr.h#; # handle #includes
s#mfbt/RefPtr.h#mfbt/nsRefPtr.h#; # handle strange #includes
'
# |using mozilla::RefPtr;| is OK; |using nsRefPtr;| is invalid syntax.
find . -name '*.cpp' -o -name '*.mm' | xargs sed -i -e '/using nsRefPtr/d'
# RefPtr.h used |byRef| for dealing with COM-style outparams.
# nsRefPtr.h uses |getter_AddRefs|.
# Fixup that mismatch.
find . -name '*.cpp' -o -name '*.h'| \
xargs perl -p -i -e 's/byRef/getter_AddRefs/g'
AudioParam has no derived type (and DisconnectFromGraphAndDestroyStream calls
no virtual functions) so no need for special release.
--HG--
extra : rebase_source : 1192d8e02d9545a310f175378468c856ef8f5f99
AudioNode already has NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE,
which performs mRefCnt.incr/decr for LastRelease(), so the kungFuDeathGrip
virtual AddRef/Release in DisconnectFromGraph() is additional noise when
debugging/tracing ownership.
Unlink() already assumes that the caller holds a reference (and it does).
--HG--
extra : rebase_source : 2ecfb16a89524588979365cfe3078df91724dad3
This lets us separate tracks by ownership like so:
* Input - Owned by the producer of the DOMMediaStream (gUM etc.)
* Owned - Contains Input tracks (per above) or tracks cloned tracks
if this DOMMediaStream is a clone.
* Playback - Contains Owned tracks plus tracks addTrack()ed to this
DOMMediaStream minus tracks removeTrack()ed from this
DOMMediaStream.
--HG--
extra : commitid : GPSNwBVyD4j
extra : rebase_source : fba22e96c6c65a74e012509f3da67a4d7df7a244
Locking to specific tracks lets us dynamically remove and add single
tracks to a ProcessedMediaStream.
--HG--
extra : commitid : GPSNwBVyD4j
extra : rebase_source : 0b1b79077f95bbefc8c71de551c5e3483a7d6ac0
This lets us separate tracks by ownership like so:
* Input - Owned by the producer of the DOMMediaStream (gUM etc.)
* Owned - Contains Input tracks (per above) or tracks cloned tracks
if this DOMMediaStream is a clone.
* Playback - Contains Owned tracks plus tracks addTrack()ed to this
DOMMediaStream minus tracks removeTrack()ed from this
DOMMediaStream.
--HG--
extra : commitid : Kvj9RrN9MgP
This is immediately useful for making the track unnecessary, but will also be
required when switching to the destination node stream for tracking time (bug
1205558) because using GetCurrentPosition() on the destination node stream
would give different results depending on the stream processing order (when
called during processing of streams not strictly upstream from the destination
node).
--HG--
extra : rebase_source : 7a3432b2e6a20fa3f42be05776c178dfda64d166
AppendAndConsumeChunk() will always append a new chunk, but AppendNullData()
will use an existing null chunk if possible.
--HG--
extra : rebase_source : b00a131433e5548d2d5bb90303cf4d2e9568419b
This makes an AudioBlock valid for code testing mBufferFormat without IsNull(),
without the need for explicit SetNull().
This is useful so that setting AudioNodeStream::mLastChunks each iteration is
not required for inactive nodes.
--HG--
extra : rebase_source : 171b7339bfe91e15b070f03bd5e0b784b58a217a
This allows simpler processing of the finished state to mark the node as an
inactive input of any downstream nodes. Otherwise the input could not be
considered inactive until after downstream nodes have finished processing,
but ProcessInput() may not be called again on finished streams.
AudioBufferSourceNode now behaves the same as OscillatorNode and similarly
to nodes that release a playing ref.
--HG--
extra : rebase_source : 1268ca8f561fee2a43ba17f5fe3abc804486a50c
This allows simpler processing of the finished state to mark the node as an
inactive input of any downstream nodes. Otherwise the input could not be
considered inactive until after downstream nodes have finished processing,
but ProcessInput() may not be called again on finished streams.
AudioBufferSourceNode now behaves the same as OscillatorNode and similarly
to nodes that release a playing ref.
--HG--
extra : rebase_source : 0b3c7123f916fce36f852785c1e0b2a7c7013600
That's nothing stopping someone passing an AudioContext time of (e.g.)
zero to AudioBufferSourceNode::Stop and OscillatorNode::Start/Stop, which
can get turned into a negative time here. Those nodes can handle negative
start/stop times just fine.
--HG--
extra : commitid : I6TtkZTlLRg
extra : rebase_source : 64e73f9ff30572f789cf4887acad97116aba33f3
This simplifies MediaStreamGraph by removing the need for it to be aware
of which AudioContext a stream belongs to.
This also makes it easier to reuse stream suspending for purposes other than
AudioContext suspend/resume.
--HG--
extra : commitid : 9EmNxlrjVFO
extra : rebase_source : fee4b35d09c8f5dec76e41840d81423cde619886
They were both "truncation from 'double' to 'float'" warnings.
This also allows the COMPILER_ALLOW_WARNINGS=True flag to be removed.
--HG--
extra : rebase_source : 4b57cba0d994671d5218be94d8f838582496ac1c
Making the conversion constructor explicit means that it will be obvious if
a temporary is created to pass an AudioChunk as an AudioBlock parameter.
--HG--
extra : rebase_source : 54bf8acdb42499a0e0d66cfc138ff6fb6f1ef4da
This saves an allocation and zeroing for buffers generated by AudioNodes and
avoids allocation altogether for empty buffers.
Incidentally, RestoreJSChannelData() now avoids unnecessary recreation of
Float32Arrays if they already exist after a previous call failed.
--HG--
extra : transplant_source : %DAn7%D1J%C3%04%23%2B%A1%15%9F%95%E2%21%18%21%D2W%1F
The array buffers are no longer available and mJSChannels will be overwritten
in RestoreJSChannelData() before it is used again. This is consistent with
"Attach ArrayBuffers containing copies of the data to the AudioBuffer, to be
returned by the next call to getChannelData."
--HG--
extra : transplant_source : x%C9%7C%D0%D9%08%CD%17%3F%D6o%BE3%BD%DCQE%DD%E5%9E
This makes it clearer that the algorithm is intentionally aborted when any of
the buffers have been neutered and that the stolen data has the correct
length.
It also makes mJSChannels available for clearing in a subsequent changeset.
--HG--
extra : transplant_source : %9A%AA%D2Rs5%C9%BA%F9%26%9E%3C%9C%2C%40%D3%EA%23%BE%CA
The ThreadSharedFloatArrayBufferList may be null even when there is a buffer
if one of its arrays has been neutered.
SAMPLE_RATE is used instead of BUFFEREND to detect whether start() and buffer
have been received because buffers can have zero length when acquiring the
contents returns "zero-length channel data buffers", although this zero-length
is not yet implemented.
LOOP and BUFFEREND are reset when the buffer is set to null to end playback.
--HG--
extra : rebase_source : f247ca61e045ff548180da5c8c6e521e944620be
I think the limits on sample rates already ensure that mBufferPosition will
not overflow, but this makes sure that there are no out of bounds reads.
The node checks the parameters are > 0 before sending to the engine.
--HG--
extra : rebase_source : 3547c7a6ed8bd1e30a34c8c402a1c339ecb89ac2
At this point AudioBlockBuffer is just like SharedBuffer but always with float
channels of length 128.
--HG--
extra : rebase_source : 61159da1577fb9607d5a766ba4288db3a7be2aff
In a subsequent patch, AllocateAudioBlock will become part of an AudioBlock
class derived from AudioChunk and used for AudioNodeStream members.
--HG--
extra : rebase_source : a3bfde8345995865c6f8e46abed24f008c112702
We don't need AudioNodes to block each other anymore.
--HG--
extra : commitid : 9rtWh5A3YY2
extra : rebase_source : cdd5c28b11602e53aaee178d3978b3e983ba5195
To make this work, we have to iterate over suspended MediaStreams in a few
more places. We don't need START_TIME_DELAYED anymore since blocking takes
care of that. I think it's good to allow suspended MediaStreams to notify
the main thread that they're finished; we might need that later when
we have non-AudioNode streams being suspended.
--HG--
extra : commitid : AZKt73Eg3rQ
extra : rebase_source : a662e9c85453212299f30085c1228ec959355440
There's no reason why WebAudio should block an incoming MediaStream.
--HG--
extra : commitid : IjUoo3OFdq9
extra : rebase_source : 5df1530c9d927e30194931c15f97389b7b74b524