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" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "media/base/audio_bus.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioPullFifo::AudioPullFifo(int channels, int frames, const ReadCB& read_cb) 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : read_cb_(read_cb), 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) fifo_(AudioBus::Create(channels, frames)), 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) fifo_index_(frames) {} 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)AudioPullFifo::~AudioPullFifo() {} 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioPullFifo::Consume(AudioBus* destination, int frames_to_consume) { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(frames_to_consume, destination->frames()); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int remaining_frames_to_provide = frames_to_consume; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to fulfill the request using what's available in the FIFO. 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int frames_read = ReadFromFifo(destination, remaining_frames_to_provide, 0); 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int write_pos = frames_read; 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) remaining_frames_to_provide -= frames_read; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the remaining audio frames from the producer using the callback. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (remaining_frames_to_provide > 0) { 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK_EQ(fifo_index_, fifo_->frames()); 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) fifo_index_ = 0; 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fill up the FIFO by acquiring audio data from the producer. 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) read_cb_.Run(write_pos, fifo_.get()); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try to fulfill the request using what's available in the FIFO. 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) frames_read = 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ReadFromFifo(destination, remaining_frames_to_provide, write_pos); 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) write_pos += frames_read; 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) remaining_frames_to_provide -= frames_read; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AudioPullFifo::Clear() { fifo_index_ = fifo_->frames(); } 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int AudioPullFifo::ReadFromFifo(AudioBus* destination, 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int frames_to_provide, 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int write_pos) { 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int frames = std::min(frames_to_provide, fifo_->frames() - fifo_index_); 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (frames <= 0) 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return 0; 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (int ch = 0; ch < fifo_->channels(); ++ch) { 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const float* src = fifo_->channel(ch) + fifo_index_; 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) float* dest = destination->channel(ch) + write_pos; 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) memcpy(dest, src, frames * sizeof(*src)); 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) fifo_index_ += frames; 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return frames; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 67