audio_pull_fifo.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/audio_pull_fifo.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioPullFifo::AudioPullFifo(int channels, int frames, const ReadCB& read_cb) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : read_cb_(read_cb) { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fifo_.reset(new AudioFifo(channels, frames)); 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus_ = AudioBus::Create(channels, frames); 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioPullFifo::~AudioPullFifo() { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_cb_.Reset(); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioPullFifo::Consume(AudioBus* destination, int frames_to_consume) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(destination); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(frames_to_consume, destination->frames()); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int write_pos = 0; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int remaining_frames_to_provide = frames_to_consume; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to fulfill the request using what's available in the FIFO. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadFromFifo(destination, &remaining_frames_to_provide, &write_pos); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the remaining audio frames from the producer using the callback. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (remaining_frames_to_provide > 0) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fill up the FIFO by acquiring audio data from the producer. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_cb_.Run(bus_.get()); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fifo_->Push(bus_.get()); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to fulfill the request using what's available in the FIFO. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadFromFifo(destination, &remaining_frames_to_provide, &write_pos); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioPullFifo::Clear() { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fifo_->Clear(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioPullFifo::ReadFromFifo(AudioBus* destination, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* frames_to_provide, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* write_pos) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(frames_to_provide); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(write_pos); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames = std::min(fifo_->frames(), *frames_to_provide); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fifo_->Consume(destination, *write_pos, frames); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *write_pos += frames; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *frames_to_provide -= frames; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 60