summaryrefslogtreecommitdiffstats
path: root/media/base/audio_pull_fifo.cc
blob: 4943591b7c2cdd30c1b499b17250a083eb3654f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/base/audio_pull_fifo.h"

#include <algorithm>

#include "base/logging.h"

namespace media {

AudioPullFifo::AudioPullFifo(int channels, int frames, const ReadCB& read_cb)
    : read_cb_(read_cb) {
  fifo_.reset(new AudioFifo(channels, frames));
  bus_ = AudioBus::Create(channels, frames);
}

AudioPullFifo::~AudioPullFifo() {
  read_cb_.Reset();
}

void AudioPullFifo::Consume(AudioBus* destination, int frames_to_consume) {
  DCHECK(destination);
  DCHECK_LE(frames_to_consume, destination->frames());

  int write_pos = 0;
  int remaining_frames_to_provide = frames_to_consume;

  // Try to fulfill the request using what's available in the FIFO.
  ReadFromFifo(destination, &remaining_frames_to_provide, &write_pos);

  // Get the remaining audio frames from the producer using the callback.
  while (remaining_frames_to_provide > 0) {
    // Fill up the FIFO by acquiring audio data from the producer.
    read_cb_.Run(write_pos, bus_.get());
    fifo_->Push(bus_.get());

    // Try to fulfill the request using what's available in the FIFO.
    ReadFromFifo(destination, &remaining_frames_to_provide, &write_pos);
  }
}

void AudioPullFifo::Clear() {
  fifo_->Clear();
}

void AudioPullFifo::ReadFromFifo(AudioBus* destination,
                                 int* frames_to_provide,
                                 int* write_pos) {
  DCHECK(frames_to_provide);
  DCHECK(write_pos);
  int frames = std::min(fifo_->frames(), *frames_to_provide);
  fifo_->Consume(destination, *write_pos, frames);
  *write_pos += frames;
  *frames_to_provide -= frames;
}

}  // namespace media