Backed out changeset 8dd41701dd92 (bug 989921) on a CLOSED TREE

This commit is contained in:
Paul Adenot 2014-05-22 14:49:10 +02:00
parent 1a157a4f4c
commit fdf46bf905
6 changed files with 53 additions and 101 deletions

View File

@ -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. */

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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,