зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1659244 - Allow processing planar audio in the AudibilityMonitor. r=pehrsons
This is essentially the same code as the interleaved version, but backwards, since the memory layout is the opposite, we want to take advantage of memory locality, and only touch audio samples once each. The `ProcessAudioData` method has been renamed, because of the similarity between the `AudioData` type and `ProcessAudioData`, since it can now process `AudioBlock`s. Differential Revision: https://phabricator.services.mozilla.com/D90431
This commit is contained in:
Родитель
1144faec40
Коммит
d1415f98f6
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "AudioSampleFormat.h"
|
||||
#include "WebAudioUtils.h"
|
||||
#include "AudioBlock.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -25,10 +26,38 @@ class AudibilityMonitor {
|
|||
mSilentFramesInARow(0),
|
||||
mEverAudible(false) {}
|
||||
|
||||
void ProcessAudioData(const AudioData* aData) {
|
||||
void Process(const AudioData* aData) {
|
||||
ProcessInterleaved(aData->Data(), aData->mChannels);
|
||||
}
|
||||
|
||||
void Process(const AudioBlock& aData) {
|
||||
if (aData.IsNull() || aData.IsMuted()) {
|
||||
mSilentFramesInARow += aData.GetDuration();
|
||||
return;
|
||||
}
|
||||
ProcessPlanar(aData.ChannelData<AudioDataValue>(), aData.GetDuration());
|
||||
}
|
||||
|
||||
void ProcessPlanar(const nsTArray<const AudioDataValue*>& aPlanar,
|
||||
TrackTime aFrames) {
|
||||
uint32_t lastFrameAudibleAccrossChannels = 0;
|
||||
for (uint32_t channel = 0; channel < aPlanar.Length(); channel++) {
|
||||
uint32_t lastSampleAudible = 0;
|
||||
for (uint32_t frame = 0; frame < aFrames; frame++) {
|
||||
float dbfs = dom::WebAudioUtils::ConvertLinearToDecibels(
|
||||
abs(AudioSampleToFloat(aPlanar[channel][frame])), -100.f);
|
||||
if (dbfs > AUDIBILITY_THREHSOLD) {
|
||||
mEverAudible = true;
|
||||
mSilentFramesInARow = 0;
|
||||
lastSampleAudible = frame;
|
||||
}
|
||||
}
|
||||
lastFrameAudibleAccrossChannels =
|
||||
std::max(lastFrameAudibleAccrossChannels, lastSampleAudible);
|
||||
}
|
||||
mSilentFramesInARow += aFrames - lastFrameAudibleAccrossChannels - 1;
|
||||
}
|
||||
|
||||
void ProcessInterleaved(const Span<AudioDataValue>& aInterleaved,
|
||||
size_t aChannels) {
|
||||
MOZ_ASSERT(aInterleaved.Length() % aChannels == 0);
|
||||
|
|
|
@ -320,7 +320,7 @@ void AudioSink::Errored() {
|
|||
void AudioSink::CheckIsAudible(const AudioData* aData) {
|
||||
MOZ_ASSERT(aData);
|
||||
|
||||
mAudibilityMonitor.ProcessAudioData(aData);
|
||||
mAudibilityMonitor.Process(aData);
|
||||
bool isAudible = mAudibilityMonitor.RecentlyAudible();
|
||||
|
||||
if (isAudible != mIsAudioDataAudible) {
|
||||
|
|
|
@ -679,7 +679,7 @@ void DecodedStream::SendAudio(double aVolume,
|
|||
void DecodedStream::CheckIsDataAudible(const AudioData* aData) {
|
||||
MOZ_ASSERT(aData);
|
||||
|
||||
mAudibilityMonitor->ProcessAudioData(aData);
|
||||
mAudibilityMonitor->Process(aData);
|
||||
bool isAudible = mAudibilityMonitor->RecentlyAudible();
|
||||
|
||||
if (isAudible != mIsAudioDataAudible) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче