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 "remoting/client/audio_player.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The number of channels in the audio stream (only supporting stereo audio 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for now). 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kChannels = 2; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kSampleSizeBytes = 2; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If queue grows bigger than 150ms we start dropping packets. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxQueueLatencyMs = 150; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioPlayer::AudioPlayer() 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : sampling_rate_(AudioPacket::SAMPLING_RATE_INVALID), 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_failed_(false), 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_bytes_(0), 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_consumed_(0) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AudioPlayer::~AudioPlayer() { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetQueue(); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioPlayer::ProcessAudioPacket(scoped_ptr<AudioPacket> packet) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(1, packet->data_size()); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(AudioPacket::ENCODING_RAW, packet->encoding()); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(AudioPacket::SAMPLING_RATE_INVALID, packet->sampling_rate()); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(kSampleSizeBytes, packet->bytes_per_sample()); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(static_cast<int>(kChannels), packet->channels()); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(packet->data(0).size() % (kChannels * kSampleSizeBytes), 0u); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No-op if the Pepper player won't start. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (start_failed_) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start the Pepper audio player if this is the first packet. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sampling_rate_ != packet->sampling_rate()) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Drop all packets currently in the queue, since they are sampled at the 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // wrong rate. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetQueue(); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sampling_rate_ = packet->sampling_rate(); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = ResetAudioPlayer(sampling_rate_); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!success) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_failed_ = true; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_bytes_ += packet->data(0).size(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) queued_packets_.push_back(packet.release()); 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int max_buffer_size_ = 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kMaxQueueLatencyMs * sampling_rate_ * kSampleSizeBytes * kChannels / 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time::kMillisecondsPerSecond; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (queued_bytes_ > max_buffer_size_) { 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_bytes_ -= queued_packets_.front()->data(0).size() - bytes_consumed_; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(queued_bytes_, 0); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete queued_packets_.front(); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_packets_.pop_front(); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bytes_consumed_ = 0; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioPlayer::AudioPlayerCallback(void* samples, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 buffer_size, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* data) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioPlayer* audio_player = static_cast<AudioPlayer*>(data); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_player->FillWithSamples(samples, buffer_size); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioPlayer::ResetQueue() { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lock_.AssertAcquired(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&queued_packets_); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_bytes_ = 0; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_consumed_ = 0; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AudioPlayer::FillWithSamples(void* samples, uint32 buffer_size) { 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t bytes_needed = kChannels * kSampleSizeBytes * 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetSamplesPerFrame(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure we don't overrun the buffer. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_EQ(buffer_size, bytes_needed); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* next_sample = static_cast<char*>(samples); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t bytes_extracted = 0; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (bytes_extracted < bytes_needed) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if we've run out of samples for this packet. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (queued_packets_.empty()) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(next_sample, 0, bytes_needed - bytes_extracted); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pop off the packet if we've already consumed all its bytes. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (queued_packets_.front()->data(0).size() == bytes_consumed_) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete queued_packets_.front(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) queued_packets_.pop_front(); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_consumed_ = 0; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& packet_data = queued_packets_.front()->data(0); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t bytes_to_copy = std::min( 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet_data.size() - bytes_consumed_, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_needed - bytes_extracted); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(next_sample, packet_data.data() + bytes_consumed_, bytes_to_copy); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_sample += bytes_to_copy; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_consumed_ += bytes_to_copy; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_extracted += bytes_to_copy; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) queued_bytes_ -= bytes_to_copy; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(queued_bytes_, 0); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 138