gecko-dev/dom/media/webaudio/AudioNodeEngine.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

438 строки
13 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/. */
#include "AudioNodeEngine.h"
#include "mozilla/AbstractThread.h"
#ifdef USE_NEON
# include "mozilla/arm.h"
# include "AudioNodeEngineGeneric.h"
#endif
#ifdef USE_SSE2
# include "mozilla/SSE.h"
# include "AudioNodeEngineGeneric.h"
#endif
#if defined(USE_SSE42) && defined(USE_FMA3)
# include "mozilla/SSE.h"
# include "AudioNodeEngineGeneric.h"
#endif
#include "AudioBlock.h"
#include "Tracing.h"
namespace mozilla {
already_AddRefed<ThreadSharedFloatArrayBufferList>
ThreadSharedFloatArrayBufferList::Create(uint32_t aChannelCount, size_t aLength,
const mozilla::fallible_t&) {
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat 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
2015-10-18 08:24:48 +03:00
RefPtr<ThreadSharedFloatArrayBufferList> buffer =
new ThreadSharedFloatArrayBufferList(aChannelCount);
for (uint32_t i = 0; i < aChannelCount; ++i) {
float* channelData = js_pod_malloc<float>(aLength);
if (!channelData) {
return nullptr;
}
buffer->SetData(i, channelData, js_free, channelData);
}
return buffer.forget();
}
void WriteZeroesToAudioBlock(AudioBlock* aChunk, uint32_t aStart,
uint32_t aLength) {
MOZ_ASSERT(aStart + aLength <= WEBAUDIO_BLOCK_SIZE);
MOZ_ASSERT(!aChunk->IsNull(), "You should pass a non-null chunk");
if (aLength == 0) {
return;
}
for (uint32_t i = 0; i < aChunk->ChannelCount(); ++i) {
PodZero(aChunk->ChannelFloatsForWrite(i) + aStart, aLength);
}
}
void AudioBufferCopyWithScale(const float* aInput, float aScale, float* aOutput,
uint32_t aSize) {
if (aScale == 1.0f) {
PodCopy(aOutput, aInput, aSize);
} else {
for (uint32_t i = 0; i < aSize; ++i) {
aOutput[i] = aInput[i] * aScale;
}
}
}
void AudioBufferAddWithScale(const float* aInput, float aScale, float* aOutput,
uint32_t aSize) {
#ifdef USE_NEON
if (mozilla::supports_neon()) {
Engine<xsimd::neon>::AudioBufferAddWithScale(aInput, aScale, aOutput,
aSize);
return;
}
#endif
#ifdef USE_SSE2
if (mozilla::supports_sse2()) {
# if defined(USE_SSE42) && defined(USE_FMA3)
if (mozilla::supports_fma3() && mozilla::supports_sse4_2()) {
Engine<xsimd::fma3<xsimd::sse4_2>>::AudioBufferAddWithScale(
aInput, aScale, aOutput, aSize);
} else
# endif
{
Engine<xsimd::sse2>::AudioBufferAddWithScale(aInput, aScale, aOutput,
aSize);
}
return;
}
#endif
if (aScale == 1.0f) {
for (uint32_t i = 0; i < aSize; ++i) {
aOutput[i] += aInput[i];
}
} else {
for (uint32_t i = 0; i < aSize; ++i) {
aOutput[i] += aInput[i] * aScale;
}
}
}
void AudioBlockAddChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
float aScale,
float aOutput[WEBAUDIO_BLOCK_SIZE]) {
AudioBufferAddWithScale(aInput, aScale, aOutput, WEBAUDIO_BLOCK_SIZE);
}
void AudioBlockCopyChannelWithScale(const float* aInput, float aScale,
float* aOutput) {
if (aScale == 1.0f) {
memcpy(aOutput, aInput, WEBAUDIO_BLOCK_SIZE * sizeof(float));
} else {
#ifdef USE_NEON
if (mozilla::supports_neon()) {
Engine<xsimd::neon>::AudioBlockCopyChannelWithScale(aInput, aScale,
aOutput);
return;
}
#endif
#ifdef USE_SSE2
if (mozilla::supports_sse2()) {
Engine<xsimd::sse2>::AudioBlockCopyChannelWithScale(aInput, aScale,
aOutput);
return;
}
#endif
for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
aOutput[i] = aInput[i] * aScale;
}
}
}
void BufferComplexMultiply(const float* aInput, const float* aScale,
float* aOutput, uint32_t aSize) {
#ifdef USE_NEON
if (mozilla::supports_neon()) {
Engine<xsimd::neon>::BufferComplexMultiply(aInput, aScale, aOutput, aSize);
return;
}
#endif
#ifdef USE_SSE2
if (mozilla::supports_sse()) {
# if defined(USE_SSE42) && defined(USE_FMA3)
if (mozilla::supports_fma3() && mozilla::supports_sse4_2()) {
Engine<xsimd::fma3<xsimd::sse4_2>>::BufferComplexMultiply(aInput, aScale,
aOutput, aSize);
} else
# endif
{
Engine<xsimd::sse2>::BufferComplexMultiply(aInput, aScale, aOutput,
aSize);
}
return;
}
#endif
for (uint32_t i = 0; i < aSize * 2; i += 2) {
float real1 = aInput[i];
float imag1 = aInput[i + 1];
float real2 = aScale[i];
float imag2 = aScale[i + 1];
float realResult = real1 * real2 - imag1 * imag2;
float imagResult = real1 * imag2 + imag1 * real2;
aOutput[i] = realResult;
aOutput[i + 1] = imagResult;
}
}
float AudioBufferPeakValue(const float* aInput, uint32_t aSize) {
float max = 0.0f;
for (uint32_t i = 0; i < aSize; i++) {
float mag = fabs(aInput[i]);
if (mag > max) {
max = mag;
}
}
return max;
}
void AudioBlockCopyChannelWithScale(const float aInput[WEBAUDIO_BLOCK_SIZE],
const float aScale[WEBAUDIO_BLOCK_SIZE],
float aOutput[WEBAUDIO_BLOCK_SIZE]) {
#ifdef USE_NEON
if (mozilla::supports_neon()) {
Engine<xsimd::neon>::AudioBlockCopyChannelWithScale(aInput, aScale,
aOutput);
return;
}
#endif
#ifdef USE_SSE2
if (mozilla::supports_sse2()) {
Engine<xsimd::sse2>::AudioBlockCopyChannelWithScale(aInput, aScale,
aOutput);
return;
}
#endif
for (uint32_t i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
aOutput[i] = aInput[i] * aScale[i];
}
}
void AudioBlockInPlaceScale(float aBlock[WEBAUDIO_BLOCK_SIZE], float aScale) {
AudioBufferInPlaceScale(aBlock, aScale, WEBAUDIO_BLOCK_SIZE);
}
void AudioBlockInPlaceScale(float aBlock[WEBAUDIO_BLOCK_SIZE],
float aScale[WEBAUDIO_BLOCK_SIZE]) {
AudioBufferInPlaceScale(aBlock, aScale, WEBAUDIO_BLOCK_SIZE);
}
void AudioBufferInPlaceScale(float* aBlock, float aScale, uint32_t aSize) {
if (aScale == 1.0f) {
return;
}
#ifdef USE_NEON
if (mozilla::supports_neon()) {
Engine<xsimd::neon>::AudioBufferInPlaceScale(aBlock, aScale, aSize);
return;
}
#endif
#ifdef USE_SSE2
if (mozilla::supports_sse2()) {
Engine<xsimd::sse2>::AudioBufferInPlaceScale(aBlock, aScale, aSize);
return;
}
#endif
for (uint32_t i = 0; i < aSize; ++i) {
*aBlock++ *= aScale;
}
}
void AudioBufferInPlaceScale(float* aBlock, float* aScale, uint32_t aSize) {
#ifdef USE_NEON
if (mozilla::supports_neon()) {
Engine<xsimd::neon>::AudioBufferInPlaceScale(aBlock, aScale, aSize);
return;
}
#endif
#ifdef USE_SSE2
if (mozilla::supports_sse2()) {
Engine<xsimd::sse2>::AudioBufferInPlaceScale(aBlock, aScale, aSize);
return;
}
#endif
for (uint32_t i = 0; i < aSize; ++i) {
*aBlock++ *= *aScale++;
}
}
void AudioBlockPanMonoToStereo(const float aInput[WEBAUDIO_BLOCK_SIZE],
float aGainL[WEBAUDIO_BLOCK_SIZE],
float aGainR[WEBAUDIO_BLOCK_SIZE],
float aOutputL[WEBAUDIO_BLOCK_SIZE],
float aOutputR[WEBAUDIO_BLOCK_SIZE]) {
AudioBlockCopyChannelWithScale(aInput, aGainL, aOutputL);
AudioBlockCopyChannelWithScale(aInput, aGainR, aOutputR);
}
void AudioBlockPanMonoToStereo(const float aInput[WEBAUDIO_BLOCK_SIZE],
float aGainL, float aGainR,
float aOutputL[WEBAUDIO_BLOCK_SIZE],
float aOutputR[WEBAUDIO_BLOCK_SIZE]) {
AudioBlockCopyChannelWithScale(aInput, aGainL, aOutputL);
AudioBlockCopyChannelWithScale(aInput, aGainR, aOutputR);
}
void AudioBlockPanStereoToStereo(const float aInputL[WEBAUDIO_BLOCK_SIZE],
const float aInputR[WEBAUDIO_BLOCK_SIZE],
float aGainL, float aGainR, bool aIsOnTheLeft,
float aOutputL[WEBAUDIO_BLOCK_SIZE],
float aOutputR[WEBAUDIO_BLOCK_SIZE]) {
#ifdef USE_NEON
if (mozilla::supports_neon()) {
Engine<xsimd::neon>::AudioBlockPanStereoToStereo(
aInputL, aInputR, aGainL, aGainR, aIsOnTheLeft, aOutputL, aOutputR);
return;
}
#endif
#ifdef USE_SSE2
if (mozilla::supports_sse2()) {
# if defined(USE_SSE42) && defined(USE_FMA3)
if (mozilla::supports_fma3() && mozilla::supports_sse4_2()) {
Engine<xsimd::fma3<xsimd::sse4_2>>::AudioBlockPanStereoToStereo(
aInputL, aInputR, aGainL, aGainR, aIsOnTheLeft, aOutputL, aOutputR);
} else
# endif
{
Engine<xsimd::sse2>::AudioBlockPanStereoToStereo(
aInputL, aInputR, aGainL, aGainR, aIsOnTheLeft, aOutputL, aOutputR);
}
return;
}
#endif
uint32_t i;
if (aIsOnTheLeft) {
for (i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
aOutputL[i] = aInputL[i] + aInputR[i] * aGainL;
aOutputR[i] = aInputR[i] * aGainR;
}
} else {
for (i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) {
aOutputL[i] = aInputL[i] * aGainL;
aOutputR[i] = aInputR[i] + aInputL[i] * aGainR;
}
}
}
void AudioBlockPanStereoToStereo(const float aInputL[WEBAUDIO_BLOCK_SIZE],
const float aInputR[WEBAUDIO_BLOCK_SIZE],
const float aGainL[WEBAUDIO_BLOCK_SIZE],
const float aGainR[WEBAUDIO_BLOCK_SIZE],
const bool aIsOnTheLeft[WEBAUDIO_BLOCK_SIZE],
float aOutputL[WEBAUDIO_BLOCK_SIZE],
float aOutputR[WEBAUDIO_BLOCK_SIZE]) {
#ifdef USE_NEON
if (mozilla::supports_neon()) {
Engine<xsimd::neon>::AudioBlockPanStereoToStereo(
aInputL, aInputR, aGainL, aGainR, aIsOnTheLeft, aOutputL, aOutputR);
return;
}
#endif
#ifdef USE_SSE2
if (mozilla::supports_sse2()) {
# if defined(USE_SSE42) && defined(USE_FMA3)
if (mozilla::supports_fma3() && mozilla::supports_sse4_2()) {
Engine<xsimd::fma3<xsimd::sse2>>::AudioBlockPanStereoToStereo(
aInputL, aInputR, aGainL, aGainR, aIsOnTheLeft, aOutputL, aOutputR);
} else
# endif
{
Engine<xsimd::sse2>::AudioBlockPanStereoToStereo(
aInputL, aInputR, aGainL, aGainR, aIsOnTheLeft, aOutputL, aOutputR);
}
return;
}
#endif
uint32_t i;
for (i = 0; i < WEBAUDIO_BLOCK_SIZE; i++) {
if (aIsOnTheLeft[i]) {
aOutputL[i] = aInputL[i] + aInputR[i] * aGainL[i];
aOutputR[i] = aInputR[i] * aGainR[i];
} else {
aOutputL[i] = aInputL[i] * aGainL[i];
aOutputR[i] = aInputR[i] + aInputL[i] * aGainR[i];
}
}
}
float AudioBufferSumOfSquares(const float* aInput, uint32_t aLength) {
#ifdef USE_NEON
if (mozilla::supports_neon()) {
return Engine<xsimd::neon>::AudioBufferSumOfSquares(aInput, aLength);
}
#endif
#ifdef USE_SSE2
if (mozilla::supports_sse()) {
# if defined(USE_SSE42) && defined(USE_FMA3)
if (mozilla::supports_fma3() && mozilla::supports_sse4_2()) {
return Engine<xsimd::fma3<xsimd::sse4_2>>::AudioBufferSumOfSquares(
aInput, aLength);
} else
# endif
{
return Engine<xsimd::sse2>::AudioBufferSumOfSquares(aInput, aLength);
}
}
#endif
float sum = 0.f;
while (aLength--) {
sum += *aInput * *aInput;
++aInput;
}
return sum;
}
void NaNToZeroInPlace(float* aSamples, size_t aCount) {
#ifdef USE_SSE2
if (mozilla::supports_sse2()) {
Engine<xsimd::sse2>::NaNToZeroInPlace(aSamples, aCount);
return;
}
#endif
for (size_t i = 0; i < aCount; i++) {
if (aSamples[i] != aSamples[i]) {
aSamples[i] = 0.0;
}
}
}
AudioNodeEngine::AudioNodeEngine(dom::AudioNode* aNode)
: mNode(aNode),
mNodeType(aNode ? aNode->NodeType() : nullptr),
mInputCount(aNode ? aNode->NumberOfInputs() : 1),
mOutputCount(aNode ? aNode->NumberOfOutputs() : 0) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_COUNT_CTOR(AudioNodeEngine);
}
Bug 1454998 - Rename streams to tracks. r=padenot,karlt,smaug This renames the following (in alphabetical order, non-exhaustive): AudioCaptureStream -> AudioCaptureTrack AudioNodeStream -> AudioNodeTrack AudioNodeExternalInputStream -> AudioNodeExternalInputTrack DirectMediaStreamTrackListener -> DirectMediaTrackListener MediaStream -> MediaTrack - Note that there's also dom::MediaTrack. Namespaces differentiate them. MediaStreamGraph -> MediaTrackGraph MediaStreamTrackListener -> MediaTrackListener MSG -> MTG (in comments) ProcessedMediaStream -> ProcessedMediaTrack SharedDummyStream -> SharedDummyTrack SourceMediaStream -> SourceMediaTrack StreamTime -> TrackTime TrackUnionStream -> ForwardedInputTrack - Because this no longer takes a union of anything, but only a single track as input. Other minor classes, members and comments have been updated to reflect these name changes. Differential Revision: https://phabricator.services.mozilla.com/D46146 --HG-- rename : dom/media/AudioCaptureStream.cpp => dom/media/AudioCaptureTrack.cpp rename : dom/media/AudioCaptureStream.h => dom/media/AudioCaptureTrack.h rename : dom/media/TrackUnionStream.cpp => dom/media/ForwardedInputTrack.cpp rename : dom/media/TrackUnionStream.h => dom/media/ForwardedInputTrack.h rename : dom/media/MediaStreamGraph.cpp => dom/media/MediaTrackGraph.cpp rename : dom/media/MediaStreamGraph.h => dom/media/MediaTrackGraph.h rename : dom/media/MediaStreamGraphImpl.h => dom/media/MediaTrackGraphImpl.h rename : dom/media/MediaStreamListener.cpp => dom/media/MediaTrackListener.cpp rename : dom/media/MediaStreamListener.h => dom/media/MediaTrackListener.h rename : dom/media/webaudio/AudioNodeExternalInputStream.cpp => dom/media/webaudio/AudioNodeExternalInputTrack.cpp rename : dom/media/webaudio/AudioNodeExternalInputStream.h => dom/media/webaudio/AudioNodeExternalInputTrack.h rename : dom/media/webaudio/AudioNodeStream.cpp => dom/media/webaudio/AudioNodeTrack.cpp rename : dom/media/webaudio/AudioNodeStream.h => dom/media/webaudio/AudioNodeTrack.h extra : moz-landing-system : lando
2019-10-02 13:23:02 +03:00
void AudioNodeEngine::ProcessBlock(AudioNodeTrack* aTrack, GraphTime aFrom,
const AudioBlock& aInput,
AudioBlock* aOutput, bool* aFinished) {
MOZ_ASSERT(mInputCount <= 1 && mOutputCount <= 1);
TRACE("AudioNodeEngine::ProcessBlock");
*aOutput = aInput;
}
Bug 1454998 - Rename streams to tracks. r=padenot,karlt,smaug This renames the following (in alphabetical order, non-exhaustive): AudioCaptureStream -> AudioCaptureTrack AudioNodeStream -> AudioNodeTrack AudioNodeExternalInputStream -> AudioNodeExternalInputTrack DirectMediaStreamTrackListener -> DirectMediaTrackListener MediaStream -> MediaTrack - Note that there's also dom::MediaTrack. Namespaces differentiate them. MediaStreamGraph -> MediaTrackGraph MediaStreamTrackListener -> MediaTrackListener MSG -> MTG (in comments) ProcessedMediaStream -> ProcessedMediaTrack SharedDummyStream -> SharedDummyTrack SourceMediaStream -> SourceMediaTrack StreamTime -> TrackTime TrackUnionStream -> ForwardedInputTrack - Because this no longer takes a union of anything, but only a single track as input. Other minor classes, members and comments have been updated to reflect these name changes. Differential Revision: https://phabricator.services.mozilla.com/D46146 --HG-- rename : dom/media/AudioCaptureStream.cpp => dom/media/AudioCaptureTrack.cpp rename : dom/media/AudioCaptureStream.h => dom/media/AudioCaptureTrack.h rename : dom/media/TrackUnionStream.cpp => dom/media/ForwardedInputTrack.cpp rename : dom/media/TrackUnionStream.h => dom/media/ForwardedInputTrack.h rename : dom/media/MediaStreamGraph.cpp => dom/media/MediaTrackGraph.cpp rename : dom/media/MediaStreamGraph.h => dom/media/MediaTrackGraph.h rename : dom/media/MediaStreamGraphImpl.h => dom/media/MediaTrackGraphImpl.h rename : dom/media/MediaStreamListener.cpp => dom/media/MediaTrackListener.cpp rename : dom/media/MediaStreamListener.h => dom/media/MediaTrackListener.h rename : dom/media/webaudio/AudioNodeExternalInputStream.cpp => dom/media/webaudio/AudioNodeExternalInputTrack.cpp rename : dom/media/webaudio/AudioNodeExternalInputStream.h => dom/media/webaudio/AudioNodeExternalInputTrack.h rename : dom/media/webaudio/AudioNodeStream.cpp => dom/media/webaudio/AudioNodeTrack.cpp rename : dom/media/webaudio/AudioNodeStream.h => dom/media/webaudio/AudioNodeTrack.h extra : moz-landing-system : lando
2019-10-02 13:23:02 +03:00
void AudioNodeEngine::ProcessBlocksOnPorts(AudioNodeTrack* aTrack,
GraphTime aFrom,
Span<const AudioBlock> aInput,
Span<AudioBlock> aOutput,
bool* aFinished) {
MOZ_ASSERT(mInputCount > 1 || mOutputCount > 1);
TRACE("AudioNodeEngine::ProcessBlocksOnPorts");
// Only produce one output port, and drop all other input ports.
aOutput[0] = aInput[0];
}
} // namespace mozilla