Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/media/webaudio/DelayBuffer.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim:set ts=2 sw=2 sts=2 et cindent: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef DelayBuffer_h_
8
#define DelayBuffer_h_
9
10
#include "nsTArray.h"
11
#include "AudioBlock.h"
12
#include "AudioSegment.h"
13
#include "mozilla/dom/AudioNodeBinding.h" // for ChannelInterpretation
14
15
namespace mozilla {
16
17
class DelayBuffer final
18
{
19
  typedef dom::ChannelInterpretation ChannelInterpretation;
20
21
public:
22
  explicit DelayBuffer(float aMaxDelayTicks)
23
    // Round the maximum delay up to the next tick.
24
    : mMaxDelayTicks(std::ceil(aMaxDelayTicks))
25
    , mCurrentChunk(0)
26
    // mLastReadChunk is initialized in EnsureBuffer
27
#ifdef DEBUG
28
    , mHaveWrittenBlock(false)
29
#endif
30
0
  {
31
0
    // The 180 second limit in AudioContext::CreateDelay() and the
32
0
    // 1 << MEDIA_TIME_FRAC_BITS limit on sample rate provide a limit on the
33
0
    // maximum delay.
34
0
    MOZ_ASSERT(aMaxDelayTicks <=
35
0
               std::numeric_limits<decltype(mMaxDelayTicks)>::max());
36
0
  }
37
38
  // Write a WEBAUDIO_BLOCK_SIZE block for aChannelCount channels.
39
  void Write(const AudioBlock& aInputChunk);
40
41
  // Read a block with an array of delays, in ticks, for each sample frame.
42
  // Each delay should be >= 0 and <= MaxDelayTicks().
43
  void Read(const float aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
44
            AudioBlock* aOutputChunk,
45
            ChannelInterpretation aChannelInterpretation);
46
  // Read a block with a constant delay. The delay should be >= 0 and
47
  // <= MaxDelayTicks().
48
  void Read(float aDelayTicks, AudioBlock* aOutputChunk,
49
            ChannelInterpretation aChannelInterpretation);
50
51
  // Read into one of the channels of aOutputChunk, given an array of
52
  // delays in ticks.  This is useful when delays are different on different
53
  // channels.  aOutputChunk must have already been allocated with at least as
54
  // many channels as were in any of the blocks passed to Write().
55
  void ReadChannel(const float aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
56
                   AudioBlock* aOutputChunk, uint32_t aChannel,
57
                   ChannelInterpretation aChannelInterpretation);
58
59
  // Advance the buffer pointer
60
  void NextBlock()
61
0
  {
62
0
    mCurrentChunk = (mCurrentChunk + 1) % mChunks.Length();
63
#ifdef DEBUG
64
    MOZ_ASSERT(mHaveWrittenBlock);
65
    mHaveWrittenBlock = false;
66
#endif
67
  }
68
69
0
  void Reset() {
70
0
    mChunks.Clear();
71
0
  };
72
73
0
  int MaxDelayTicks() const { return mMaxDelayTicks; }
74
75
  size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
76
77
private:
78
  void ReadChannels(const float aPerFrameDelays[WEBAUDIO_BLOCK_SIZE],
79
                    AudioBlock* aOutputChunk,
80
                    uint32_t aFirstChannel, uint32_t aNumChannelsToRead,
81
                    ChannelInterpretation aChannelInterpretation);
82
  bool EnsureBuffer();
83
  int PositionForDelay(int aDelay);
84
  int ChunkForPosition(int aPosition);
85
  int OffsetForPosition(int aPosition);
86
  int ChunkForDelay(int aDelay);
87
  void UpdateUpmixChannels(int aNewReadChunk, uint32_t channelCount,
88
                           ChannelInterpretation aChannelInterpretation);
89
90
  // Circular buffer for capturing delayed samples.
91
  FallibleTArray<AudioChunk> mChunks;
92
  // Cache upmixed channel arrays.
93
  AutoTArray<const float*,GUESS_AUDIO_CHANNELS> mUpmixChannels;
94
  // Maximum delay, in ticks
95
  int mMaxDelayTicks;
96
  // The current position in the circular buffer.  The next write will be to
97
  // this chunk, and the next read may begin before this chunk.
98
  int mCurrentChunk;
99
  // The chunk owning the pointers in mUpmixChannels
100
  int mLastReadChunk;
101
#ifdef DEBUG
102
  bool mHaveWrittenBlock;
103
#endif
104
};
105
106
} // namespace mozilla
107
108
#endif // DelayBuffer_h_