content/media/AudioMixer.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/content/media/AudioMixer.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,95 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.7 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef MOZILLA_AUDIOMIXER_H_
    1.10 +#define MOZILLA_AUDIOMIXER_H_
    1.11 +
    1.12 +#include "AudioSampleFormat.h"
    1.13 +#include "nsTArray.h"
    1.14 +#include "mozilla/PodOperations.h"
    1.15 +
    1.16 +namespace mozilla {
    1.17 +typedef void(*MixerFunc)(AudioDataValue* aMixedBuffer,
    1.18 +                         AudioSampleFormat aFormat,
    1.19 +                         uint32_t aChannels,
    1.20 +                         uint32_t aFrames,
    1.21 +                         uint32_t aSampleRate);
    1.22 +
    1.23 +/**
    1.24 + * This class mixes multiple streams of audio together to output a single audio
    1.25 + * stream.
    1.26 + *
    1.27 + * AudioMixer::Mix is to be called repeatedly with buffers that have the same
    1.28 + * length, sample rate, sample format and channel count.
    1.29 + *
    1.30 + * When all the tracks have been mixed, calling FinishMixing will call back with
    1.31 + * a buffer containing the mixed audio data.
    1.32 + *
    1.33 + * This class is not thread safe.
    1.34 + */
    1.35 +class AudioMixer
    1.36 +{
    1.37 +public:
    1.38 +  AudioMixer(MixerFunc aCallback)
    1.39 +    : mCallback(aCallback),
    1.40 +      mFrames(0),
    1.41 +      mChannels(0),
    1.42 +      mSampleRate(0)
    1.43 +  { }
    1.44 +
    1.45 +  /* Get the data from the mixer. This is supposed to be called when all the
    1.46 +   * tracks have been mixed in. The caller should not hold onto the data. */
    1.47 +  void FinishMixing() {
    1.48 +    mCallback(mMixedAudio.Elements(),
    1.49 +              AudioSampleTypeToFormat<AudioDataValue>::Format,
    1.50 +              mChannels,
    1.51 +              mFrames,
    1.52 +              mSampleRate);
    1.53 +    PodZero(mMixedAudio.Elements(), mMixedAudio.Length());
    1.54 +    mSampleRate = mChannels = mFrames = 0;
    1.55 +  }
    1.56 +
    1.57 +  /* Add a buffer to the mix. aSamples is interleaved. */
    1.58 +  void Mix(AudioDataValue* aSamples,
    1.59 +           uint32_t aChannels,
    1.60 +           uint32_t aFrames,
    1.61 +           uint32_t aSampleRate) {
    1.62 +    if (!mFrames && !mChannels) {
    1.63 +      mFrames = aFrames;
    1.64 +      mChannels = aChannels;
    1.65 +      mSampleRate = aSampleRate;
    1.66 +      EnsureCapacityAndSilence();
    1.67 +    }
    1.68 +
    1.69 +    MOZ_ASSERT(aFrames == mFrames);
    1.70 +    MOZ_ASSERT(aChannels == mChannels);
    1.71 +    MOZ_ASSERT(aSampleRate == mSampleRate);
    1.72 +
    1.73 +    for (uint32_t i = 0; i < aFrames * aChannels; i++) {
    1.74 +      mMixedAudio[i] += aSamples[i];
    1.75 +    }
    1.76 +  }
    1.77 +private:
    1.78 +  void EnsureCapacityAndSilence() {
    1.79 +    if (mFrames * mChannels > mMixedAudio.Length()) {
    1.80 +      mMixedAudio.SetLength(mFrames* mChannels);
    1.81 +    }
    1.82 +    PodZero(mMixedAudio.Elements(), mMixedAudio.Length());
    1.83 +  }
    1.84 +
    1.85 +  /* Function that is called when the mixing is done. */
    1.86 +  MixerFunc mCallback;
    1.87 +  /* Number of frames for this mixing block. */
    1.88 +  uint32_t mFrames;
    1.89 +  /* Number of channels for this mixing block. */
    1.90 +  uint32_t mChannels;
    1.91 +  /* Sample rate the of the mixed data. */
    1.92 +  uint32_t mSampleRate;
    1.93 +  /* Buffer containing the mixed audio data. */
    1.94 +  nsTArray<AudioDataValue> mMixedAudio;
    1.95 +};
    1.96 +}
    1.97 +
    1.98 +#endif // MOZILLA_AUDIOMIXER_H_

mercurial