1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "media/audio/android/audio_record_input.h" 6 7#include "base/logging.h" 8#include "jni/AudioRecordInput_jni.h" 9#include "media/audio/android/audio_manager_android.h" 10#include "media/base/audio_bus.h" 11 12namespace media { 13 14AudioRecordInputStream::AudioRecordInputStream( 15 AudioManagerAndroid* audio_manager, 16 const AudioParameters& params) 17 : audio_manager_(audio_manager), 18 callback_(NULL), 19 direct_buffer_address_(NULL), 20 audio_bus_(media::AudioBus::Create(params)), 21 bytes_per_sample_(params.bits_per_sample() / 8) { 22 DVLOG(2) << __PRETTY_FUNCTION__; 23 DCHECK(params.IsValid()); 24 j_audio_record_.Reset( 25 Java_AudioRecordInput_createAudioRecordInput( 26 base::android::AttachCurrentThread(), 27 reinterpret_cast<intptr_t>(this), 28 params.sample_rate(), 29 params.channels(), 30 params.bits_per_sample(), 31 params.GetBytesPerBuffer(), 32 params.effects() & AudioParameters::ECHO_CANCELLER)); 33} 34 35AudioRecordInputStream::~AudioRecordInputStream() { 36 DVLOG(2) << __PRETTY_FUNCTION__; 37 DCHECK(thread_checker_.CalledOnValidThread()); 38} 39 40void AudioRecordInputStream::CacheDirectBufferAddress(JNIEnv* env, jobject obj, 41 jobject byte_buffer) { 42 DCHECK(thread_checker_.CalledOnValidThread()); 43 direct_buffer_address_ = static_cast<uint8*>( 44 env->GetDirectBufferAddress(byte_buffer)); 45} 46 47// static 48bool AudioRecordInputStream::RegisterAudioRecordInput(JNIEnv* env) { 49 return RegisterNativesImpl(env); 50} 51 52void AudioRecordInputStream::OnData(JNIEnv* env, jobject obj, jint size, 53 jint hardware_delay_bytes) { 54 DCHECK(direct_buffer_address_); 55 DCHECK_EQ(size, 56 audio_bus_->frames() * audio_bus_->channels() * bytes_per_sample_); 57 // Passing zero as the volume parameter indicates there is no access to a 58 // hardware volume slider. 59 audio_bus_->FromInterleaved( 60 direct_buffer_address_, audio_bus_->frames(), bytes_per_sample_); 61 callback_->OnData(this, audio_bus_.get(), hardware_delay_bytes, 0.0); 62} 63 64bool AudioRecordInputStream::Open() { 65 DVLOG(2) << __PRETTY_FUNCTION__; 66 DCHECK(thread_checker_.CalledOnValidThread()); 67 return Java_AudioRecordInput_open( 68 base::android::AttachCurrentThread(), j_audio_record_.obj()); 69} 70 71void AudioRecordInputStream::Start(AudioInputCallback* callback) { 72 DVLOG(2) << __PRETTY_FUNCTION__; 73 DCHECK(thread_checker_.CalledOnValidThread()); 74 DCHECK(callback); 75 76 if (callback_) { 77 // Start() was already called. 78 DCHECK_EQ(callback_, callback); 79 return; 80 } 81 // The Java thread has not yet started, so we are free to set |callback_|. 82 callback_ = callback; 83 84 Java_AudioRecordInput_start( 85 base::android::AttachCurrentThread(), j_audio_record_.obj()); 86} 87 88void AudioRecordInputStream::Stop() { 89 DVLOG(2) << __PRETTY_FUNCTION__; 90 DCHECK(thread_checker_.CalledOnValidThread()); 91 if (!callback_) { 92 // Start() was never called, or Stop() was already called. 93 return; 94 } 95 96 Java_AudioRecordInput_stop( 97 base::android::AttachCurrentThread(), j_audio_record_.obj()); 98 99 // The Java thread must have been stopped at this point, so we are free to 100 // clear |callback_|. 101 callback_ = NULL; 102} 103 104void AudioRecordInputStream::Close() { 105 DVLOG(2) << __PRETTY_FUNCTION__; 106 DCHECK(thread_checker_.CalledOnValidThread()); 107 Stop(); 108 DCHECK(!callback_); 109 Java_AudioRecordInput_close( 110 base::android::AttachCurrentThread(), j_audio_record_.obj()); 111 audio_manager_->ReleaseInputStream(this); 112} 113 114double AudioRecordInputStream::GetMaxVolume() { 115 NOTIMPLEMENTED(); 116 return 0.0; 117} 118 119void AudioRecordInputStream::SetVolume(double volume) { 120 NOTIMPLEMENTED(); 121} 122 123double AudioRecordInputStream::GetVolume() { 124 NOTIMPLEMENTED(); 125 return 0.0; 126} 127 128void AudioRecordInputStream::SetAutomaticGainControl(bool enabled) { 129 NOTIMPLEMENTED(); 130} 131 132bool AudioRecordInputStream::GetAutomaticGainControl() { 133 NOTIMPLEMENTED(); 134 return false; 135} 136 137bool AudioRecordInputStream::IsMuted() { 138 NOTIMPLEMENTED(); 139 return false; 140} 141 142} // namespace media 143