mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-24 02:35:41 +00:00
e33037127f
This moves the application of volume and averaging of channels to the main thread, performed when required. It avoids a potential allocation on the graph thread. If doing a full analysis for frequency data, the extra work on the main thread should be negligible. I assume that repeatedly fetching the same time domain data with getFloatFrequencyData() is not something we need to optimize for. If, in rare circumstances, the extra main thread work turns out to be significant, then the main thread work in getters is self-regulating, but too much load on the graph thread leads to catastrophic failure in the audio. This also fixes some bugs: Input and output streams for other consumers are not corrupted by in-place scaling of data intended to be read-only. When there are additional channels and fftSize < WEBAUDIO_BLOCK_SIZE, the channels are not written past the current length of a buffer, so there is no longer a dependency on nsTArray's behavior of never not reducing allocation size on length changes. The most recent fftSize samples are now used even when fftSize < WEBAUDIO_BLOCK_SIZE, instead of the first fftSize samples in the most recent block. Enough time domain data is recorded so that getters will work immediately following a change in fftSize. --HG-- extra : rebase_source : bbd8a3e705d73781bb838a47261bf7d60cd1a9a7
91 lines
2.3 KiB
C++
91 lines
2.3 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 AnalyserNode_h_
|
|
#define AnalyserNode_h_
|
|
|
|
#include "AudioNode.h"
|
|
#include "FFTBlock.h"
|
|
#include "AlignedTArray.h"
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
|
|
class AudioContext;
|
|
|
|
class AnalyserNode final : public AudioNode
|
|
{
|
|
public:
|
|
explicit AnalyserNode(AudioContext* aContext);
|
|
|
|
NS_DECL_ISUPPORTS_INHERITED
|
|
|
|
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
|
|
|
void GetFloatFrequencyData(const Float32Array& aArray);
|
|
void GetByteFrequencyData(const Uint8Array& aArray);
|
|
void GetFloatTimeDomainData(const Float32Array& aArray);
|
|
void GetByteTimeDomainData(const Uint8Array& aArray);
|
|
uint32_t FftSize() const
|
|
{
|
|
return mAnalysisBlock.FFTSize();
|
|
}
|
|
void SetFftSize(uint32_t aValue, ErrorResult& aRv);
|
|
uint32_t FrequencyBinCount() const
|
|
{
|
|
return FftSize() / 2;
|
|
}
|
|
double MinDecibels() const
|
|
{
|
|
return mMinDecibels;
|
|
}
|
|
void SetMinDecibels(double aValue, ErrorResult& aRv);
|
|
double MaxDecibels() const
|
|
{
|
|
return mMaxDecibels;
|
|
}
|
|
void SetMaxDecibels(double aValue, ErrorResult& aRv);
|
|
double SmoothingTimeConstant() const
|
|
{
|
|
return mSmoothingTimeConstant;
|
|
}
|
|
void SetSmoothingTimeConstant(double aValue, ErrorResult& aRv);
|
|
|
|
virtual const char* NodeType() const override
|
|
{
|
|
return "AnalyserNode";
|
|
}
|
|
|
|
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
|
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
|
|
|
|
protected:
|
|
~AnalyserNode() {}
|
|
|
|
private:
|
|
friend class AnalyserNodeEngine;
|
|
void AppendChunk(const AudioChunk& aChunk);
|
|
bool AllocateBuffer();
|
|
bool FFTAnalysis();
|
|
void ApplyBlackmanWindow(float* aBuffer, uint32_t aSize);
|
|
void GetTimeDomainData(float* aData, size_t aLength);
|
|
|
|
private:
|
|
FFTBlock mAnalysisBlock;
|
|
nsTArray<AudioChunk> mChunks;
|
|
double mMinDecibels;
|
|
double mMaxDecibels;
|
|
double mSmoothingTimeConstant;
|
|
size_t mCurrentChunk = 0;
|
|
AlignedTArray<float> mOutputBuffer;
|
|
};
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|
|
|
|
#endif
|
|
|