LCOV - code coverage report
Current view: top level - dom/media - AudioMixer.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 54 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 11 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       4             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef MOZILLA_AUDIOMIXER_H_
       7             : #define MOZILLA_AUDIOMIXER_H_
       8             : 
       9             : #include "AudioSampleFormat.h"
      10             : #include "nsTArray.h"
      11             : #include "mozilla/PodOperations.h"
      12             : #include "mozilla/LinkedList.h"
      13             : #include "AudioStream.h"
      14             : 
      15             : namespace mozilla {
      16             : 
      17           0 : struct MixerCallbackReceiver {
      18             :   virtual void MixerCallback(AudioDataValue* aMixedBuffer,
      19             :                              AudioSampleFormat aFormat,
      20             :                              uint32_t aChannels,
      21             :                              uint32_t aFrames,
      22             :                              uint32_t aSampleRate) = 0;
      23             : };
      24             : /**
      25             :  * This class mixes multiple streams of audio together to output a single audio
      26             :  * stream.
      27             :  *
      28             :  * AudioMixer::Mix is to be called repeatedly with buffers that have the same
      29             :  * length, sample rate, sample format and channel count. This class works with
      30             :  * interleaved and plannar buffers, but the buffer mixed must be of the same
      31             :  * type during a mixing cycle.
      32             :  *
      33             :  * When all the tracks have been mixed, calling FinishMixing will call back with
      34             :  * a buffer containing the mixed audio data.
      35             :  *
      36             :  * This class is not thread safe.
      37             :  */
      38             : class AudioMixer
      39             : {
      40             : public:
      41           0 :   AudioMixer()
      42           0 :     : mFrames(0),
      43             :       mChannels(0),
      44           0 :       mSampleRate(0)
      45           0 :   { }
      46             : 
      47           0 :   ~AudioMixer()
      48           0 :   {
      49             :     MixerCallback* cb;
      50           0 :     while ((cb = mCallbacks.popFirst())) {
      51           0 :       delete cb;
      52             :     }
      53           0 :   }
      54             : 
      55           0 :   void StartMixing()
      56             :   {
      57           0 :     mSampleRate = mChannels = mFrames = 0;
      58           0 :   }
      59             : 
      60             :   /* Get the data from the mixer. This is supposed to be called when all the
      61             :    * tracks have been mixed in. The caller should not hold onto the data. */
      62           0 :   void FinishMixing() {
      63           0 :     MOZ_ASSERT(mChannels && mFrames && mSampleRate, "Mix not called for this cycle?");
      64           0 :     for (MixerCallback* cb = mCallbacks.getFirst();
      65           0 :          cb != nullptr; cb = cb->getNext()) {
      66           0 :       cb->mReceiver->MixerCallback(mMixedAudio.Elements(),
      67             :                                    AudioSampleTypeToFormat<AudioDataValue>::Format,
      68             :                                    mChannels,
      69             :                                    mFrames,
      70           0 :                                    mSampleRate);
      71             :     }
      72           0 :     PodZero(mMixedAudio.Elements(), mMixedAudio.Length());
      73           0 :     mSampleRate = mChannels = mFrames = 0;
      74           0 :   }
      75             : 
      76             :   /* Add a buffer to the mix. */
      77           0 :   void Mix(AudioDataValue* aSamples,
      78             :            uint32_t aChannels,
      79             :            uint32_t aFrames,
      80             :            uint32_t aSampleRate) {
      81           0 :     if (!mFrames && !mChannels) {
      82           0 :       mFrames = aFrames;
      83           0 :       mChannels = aChannels;
      84           0 :       mSampleRate = aSampleRate;
      85           0 :       EnsureCapacityAndSilence();
      86             :     }
      87             : 
      88           0 :     MOZ_ASSERT(aFrames == mFrames);
      89           0 :     MOZ_ASSERT(aChannels == mChannels);
      90           0 :     MOZ_ASSERT(aSampleRate == mSampleRate);
      91             : 
      92           0 :     for (uint32_t i = 0; i < aFrames * aChannels; i++) {
      93           0 :       mMixedAudio[i] += aSamples[i];
      94             :     }
      95           0 :   }
      96             : 
      97           0 :   void AddCallback(MixerCallbackReceiver* aReceiver) {
      98           0 :     mCallbacks.insertBack(new MixerCallback(aReceiver));
      99           0 :   }
     100             : 
     101             :   bool FindCallback(MixerCallbackReceiver* aReceiver) {
     102             :     for (MixerCallback* cb = mCallbacks.getFirst();
     103             :          cb != nullptr; cb = cb->getNext()) {
     104             :       if (cb->mReceiver == aReceiver) {
     105             :         return true;
     106             :       }
     107             :     }
     108             :     return false;
     109             :   }
     110             : 
     111           0 :   bool RemoveCallback(MixerCallbackReceiver* aReceiver) {
     112           0 :     for (MixerCallback* cb = mCallbacks.getFirst();
     113           0 :          cb != nullptr; cb = cb->getNext()) {
     114           0 :       if (cb->mReceiver == aReceiver) {
     115           0 :         cb->remove();
     116           0 :         delete cb;
     117           0 :         return true;
     118             :       }
     119             :     }
     120           0 :     return false;
     121             :   }
     122             : private:
     123           0 :   void EnsureCapacityAndSilence() {
     124           0 :     if (mFrames * mChannels > mMixedAudio.Length()) {
     125           0 :       mMixedAudio.SetLength(mFrames* mChannels);
     126             :     }
     127           0 :     PodZero(mMixedAudio.Elements(), mMixedAudio.Length());
     128           0 :   }
     129             : 
     130           0 :   class MixerCallback : public LinkedListElement<MixerCallback>
     131             :   {
     132             :   public:
     133           0 :     explicit MixerCallback(MixerCallbackReceiver* aReceiver)
     134           0 :       : mReceiver(aReceiver)
     135           0 :     { }
     136             :     MixerCallbackReceiver* mReceiver;
     137             :   };
     138             : 
     139             :   /* Function that is called when the mixing is done. */
     140             :   LinkedList<MixerCallback> mCallbacks;
     141             :   /* Number of frames for this mixing block. */
     142             :   uint32_t mFrames;
     143             :   /* Number of channels for this mixing block. */
     144             :   uint32_t mChannels;
     145             :   /* Sample rate the of the mixed data. */
     146             :   uint32_t mSampleRate;
     147             :   /* Buffer containing the mixed audio data. */
     148             :   nsTArray<AudioDataValue> mMixedAudio;
     149             : };
     150             : 
     151             : } // namespace mozilla
     152             : 
     153             : #endif // MOZILLA_AUDIOMIXER_H_

Generated by: LCOV version 1.13