mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changeset 8dd41701dd92 (bug 989921) on a CLOSED TREE
This commit is contained in:
parent
1a157a4f4c
commit
fdf46bf905
@ -9,17 +9,13 @@
|
||||
#include "AudioSampleFormat.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
struct MixerCallbackReceiver {
|
||||
virtual void MixerCallback(AudioDataValue* aMixedBuffer,
|
||||
AudioSampleFormat aFormat,
|
||||
uint32_t aChannels,
|
||||
uint32_t aFrames,
|
||||
uint32_t aSampleRate) = 0;
|
||||
};
|
||||
typedef void(*MixerFunc)(AudioDataValue* aMixedBuffer,
|
||||
AudioSampleFormat aFormat,
|
||||
uint32_t aChannels,
|
||||
uint32_t aFrames,
|
||||
uint32_t aSampleRate);
|
||||
|
||||
/**
|
||||
* This class mixes multiple streams of audio together to output a single audio
|
||||
@ -36,29 +32,21 @@ struct MixerCallbackReceiver {
|
||||
class AudioMixer
|
||||
{
|
||||
public:
|
||||
AudioMixer()
|
||||
: mFrames(0),
|
||||
AudioMixer(MixerFunc aCallback)
|
||||
: mCallback(aCallback),
|
||||
mFrames(0),
|
||||
mChannels(0),
|
||||
mSampleRate(0)
|
||||
{ }
|
||||
|
||||
~AudioMixer()
|
||||
{
|
||||
mCallbacks.clear();
|
||||
}
|
||||
|
||||
/* Get the data from the mixer. This is supposed to be called when all the
|
||||
* tracks have been mixed in. The caller should not hold onto the data. */
|
||||
void FinishMixing() {
|
||||
MOZ_ASSERT(mChannels && mFrames && mSampleRate, "Mix not called for this cycle?");
|
||||
for (MixerCallback* cb = mCallbacks.getFirst();
|
||||
cb != nullptr; cb = cb->getNext()) {
|
||||
cb->mReceiver->MixerCallback(mMixedAudio.Elements(),
|
||||
AudioSampleTypeToFormat<AudioDataValue>::Format,
|
||||
mChannels,
|
||||
mFrames,
|
||||
mSampleRate);
|
||||
}
|
||||
mCallback(mMixedAudio.Elements(),
|
||||
AudioSampleTypeToFormat<AudioDataValue>::Format,
|
||||
mChannels,
|
||||
mFrames,
|
||||
mSampleRate);
|
||||
PodZero(mMixedAudio.Elements(), mMixedAudio.Length());
|
||||
mSampleRate = mChannels = mFrames = 0;
|
||||
}
|
||||
@ -83,21 +71,6 @@ public:
|
||||
mMixedAudio[i] += aSamples[i];
|
||||
}
|
||||
}
|
||||
|
||||
void AddCallback(MixerCallbackReceiver* aReceiver) {
|
||||
mCallbacks.insertBack(new MixerCallback(aReceiver));
|
||||
}
|
||||
|
||||
bool RemoveCallback(MixerCallbackReceiver* aReceiver) {
|
||||
for (MixerCallback* cb = mCallbacks.getFirst();
|
||||
cb != nullptr; cb = cb->getNext()) {
|
||||
if (cb->mReceiver == aReceiver) {
|
||||
cb->remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private:
|
||||
void EnsureCapacityAndSilence() {
|
||||
if (mFrames * mChannels > mMixedAudio.Length()) {
|
||||
@ -106,17 +79,8 @@ private:
|
||||
PodZero(mMixedAudio.Elements(), mMixedAudio.Length());
|
||||
}
|
||||
|
||||
class MixerCallback : public LinkedListElement<MixerCallback>
|
||||
{
|
||||
public:
|
||||
MixerCallback(MixerCallbackReceiver* aReceiver)
|
||||
: mReceiver(aReceiver)
|
||||
{ }
|
||||
MixerCallbackReceiver* mReceiver;
|
||||
};
|
||||
|
||||
/* Function that is called when the mixing is done. */
|
||||
LinkedList<MixerCallback> mCallbacks;
|
||||
MixerFunc mCallback;
|
||||
/* Number of frames for this mixing block. */
|
||||
uint32_t mFrames;
|
||||
/* Number of channels for this mixing block. */
|
||||
|
@ -586,6 +586,24 @@ MediaStreamGraphImpl::UpdateStreamOrderForStream(mozilla::LinkedList<MediaStream
|
||||
*mStreams.AppendElement() = stream.forget();
|
||||
}
|
||||
|
||||
static void AudioMixerCallback(AudioDataValue* aMixedBuffer,
|
||||
AudioSampleFormat aFormat,
|
||||
uint32_t aChannels,
|
||||
uint32_t aFrames,
|
||||
uint32_t aSampleRate)
|
||||
{
|
||||
// Need an api to register mixer callbacks, bug 989921
|
||||
#ifdef MOZ_WEBRTC
|
||||
if (aFrames > 0 && aChannels > 0) {
|
||||
// XXX need Observer base class and registration API
|
||||
if (gFarendObserver) {
|
||||
gFarendObserver->InsertFarEnd(aMixedBuffer, aFrames, false,
|
||||
aSampleRate, aChannels, aFormat);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
MediaStreamGraphImpl::UpdateStreamOrder()
|
||||
{
|
||||
@ -613,12 +631,8 @@ MediaStreamGraphImpl::UpdateStreamOrder()
|
||||
}
|
||||
|
||||
if (!mMixer && shouldMix) {
|
||||
mMixer = new AudioMixer();
|
||||
if (gFarendObserver) {
|
||||
mMixer->AddCallback(gFarendObserver);
|
||||
}
|
||||
mMixer = new AudioMixer(AudioMixerCallback);
|
||||
} else if (mMixer && !shouldMix) {
|
||||
mMixer->RemoveCallback(gFarendObserver);
|
||||
mMixer = nullptr;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsAutoRef.h"
|
||||
#include "speex/speex_resampler.h"
|
||||
#include "AudioMixer.h"
|
||||
#include "mozilla/dom/AudioChannelBinding.h"
|
||||
|
||||
class nsIRunnable;
|
||||
|
@ -9,28 +9,25 @@
|
||||
using mozilla::AudioDataValue;
|
||||
using mozilla::AudioSampleFormat;
|
||||
|
||||
struct MixerConsumer : public mozilla::MixerCallbackReceiver
|
||||
{
|
||||
/* In this test, the different audio stream and channels are always created to
|
||||
* cancel each other. */
|
||||
void MixerCallback(AudioDataValue* aData, AudioSampleFormat aFormat, uint32_t aChannels, uint32_t aFrames, uint32_t aSampleRate)
|
||||
{
|
||||
bool silent = true;
|
||||
for (uint32_t i = 0; i < aChannels * aFrames; i++) {
|
||||
if (aData[i] != 0.0) {
|
||||
if (aFormat == mozilla::AUDIO_FORMAT_S16) {
|
||||
fprintf(stderr, "Sample at %d is not silent: %d\n", i, (short)aData[i]);
|
||||
} else {
|
||||
fprintf(stderr, "Sample at %d is not silent: %f\n", i, (float)aData[i]);
|
||||
}
|
||||
silent = false;
|
||||
void MixingDone(AudioDataValue* aData, AudioSampleFormat aFormat, uint32_t aChannels, uint32_t aFrames, uint32_t aSampleRate)
|
||||
{
|
||||
bool silent = true;
|
||||
for (uint32_t i = 0; i < aChannels * aFrames; i++) {
|
||||
if (aData[i] != 0.0) {
|
||||
if (aFormat == mozilla::AUDIO_FORMAT_S16) {
|
||||
fprintf(stderr, "Sample at %d is not silent: %d\n", i, (short)aData[i]);
|
||||
} else {
|
||||
fprintf(stderr, "Sample at %d is not silent: %f\n", i, (float)aData[i]);
|
||||
}
|
||||
}
|
||||
if (!silent) {
|
||||
MOZ_CRASH();
|
||||
silent = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
if (!silent) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper function to give us the maximum and minimum value that don't clip,
|
||||
* for a given sample format (integer or floating-point). */
|
||||
@ -71,7 +68,6 @@ void FillBuffer(AudioDataValue* aBuffer, uint32_t aLength, AudioDataValue aValue
|
||||
int main(int argc, char* argv[]) {
|
||||
const uint32_t CHANNEL_LENGTH = 256;
|
||||
const uint32_t AUDIO_RATE = 44100;
|
||||
MixerConsumer consumer;
|
||||
AudioDataValue a[CHANNEL_LENGTH * 2];
|
||||
AudioDataValue b[CHANNEL_LENGTH * 2];
|
||||
FillBuffer(a, CHANNEL_LENGTH, GetLowValue<AudioDataValue>());
|
||||
@ -81,8 +77,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
{
|
||||
int iterations = 2;
|
||||
mozilla::AudioMixer mixer;
|
||||
mixer.AddCallback(&consumer);
|
||||
mozilla::AudioMixer mixer(MixingDone);
|
||||
|
||||
fprintf(stderr, "Test AudioMixer constant buffer length.\n");
|
||||
|
||||
@ -94,8 +89,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
{
|
||||
mozilla::AudioMixer mixer;
|
||||
mixer.AddCallback(&consumer);
|
||||
mozilla::AudioMixer mixer(MixingDone);
|
||||
|
||||
fprintf(stderr, "Test AudioMixer variable buffer length.\n");
|
||||
|
||||
@ -126,9 +120,7 @@ int main(int argc, char* argv[]) {
|
||||
FillBuffer(b, CHANNEL_LENGTH, GetHighValue<AudioDataValue>());
|
||||
|
||||
{
|
||||
mozilla::AudioMixer mixer;
|
||||
mixer.AddCallback(&consumer);
|
||||
|
||||
mozilla::AudioMixer mixer(MixingDone);
|
||||
fprintf(stderr, "Test AudioMixer variable channel count.\n");
|
||||
|
||||
mixer.Mix(a, 1, CHANNEL_LENGTH, AUDIO_RATE);
|
||||
@ -143,8 +135,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
{
|
||||
mozilla::AudioMixer mixer;
|
||||
mixer.AddCallback(&consumer);
|
||||
mozilla::AudioMixer mixer(MixingDone);
|
||||
fprintf(stderr, "Test AudioMixer variable stream count.\n");
|
||||
|
||||
mixer.Mix(a, 2, CHANNEL_LENGTH, AUDIO_RATE);
|
||||
|
@ -6,7 +6,6 @@
|
||||
#define AUDIOOUTPUTOBSERVER_H_
|
||||
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "AudioMixer.h"
|
||||
|
||||
namespace webrtc {
|
||||
class SingleRwFifo;
|
||||
@ -21,18 +20,12 @@ typedef struct FarEndAudioChunk_ {
|
||||
} FarEndAudioChunk;
|
||||
|
||||
// XXX Really a singleton currently
|
||||
class AudioOutputObserver : public MixerCallbackReceiver
|
||||
class AudioOutputObserver // : public MSGOutputObserver
|
||||
{
|
||||
public:
|
||||
AudioOutputObserver();
|
||||
virtual ~AudioOutputObserver();
|
||||
|
||||
void MixerCallback(AudioDataValue* aMixedBuffer,
|
||||
AudioSampleFormat aFormat,
|
||||
uint32_t aChannels,
|
||||
uint32_t aFrames,
|
||||
uint32_t aSampleRate) MOZ_OVERRIDE;
|
||||
|
||||
void Clear();
|
||||
void InsertFarEnd(const AudioDataValue *aBuffer, uint32_t aSamples, bool aOverran,
|
||||
int aFreq, int aChannels, AudioSampleFormat aFormat);
|
||||
|
@ -86,17 +86,6 @@ AudioOutputObserver::Size()
|
||||
return mPlayoutFifo->size();
|
||||
}
|
||||
|
||||
void
|
||||
AudioOutputObserver::MixerCallback(AudioDataValue* aMixedBuffer,
|
||||
AudioSampleFormat aFormat,
|
||||
uint32_t aChannels,
|
||||
uint32_t aFrames,
|
||||
uint32_t aSampleRate)
|
||||
{
|
||||
gFarendObserver->InsertFarEnd(aMixedBuffer, aFrames, false,
|
||||
aSampleRate, aChannels, aFormat);
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
AudioOutputObserver::InsertFarEnd(const AudioDataValue *aBuffer, uint32_t aSamples, bool aOverran,
|
||||
|
Loading…
Reference in New Issue
Block a user