Home | History | Annotate | Download | only in android
      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 
     12 namespace media {
     13 
     14 AudioRecordInputStream::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 
     35 AudioRecordInputStream::~AudioRecordInputStream() {
     36   DVLOG(2) << __PRETTY_FUNCTION__;
     37   DCHECK(thread_checker_.CalledOnValidThread());
     38 }
     39 
     40 void 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
     48 bool AudioRecordInputStream::RegisterAudioRecordInput(JNIEnv* env) {
     49   return RegisterNativesImpl(env);
     50 }
     51 
     52 void 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 
     64 bool 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 
     71 void 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 
     88 void 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 
    104 void 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 
    114 double AudioRecordInputStream::GetMaxVolume() {
    115   NOTIMPLEMENTED();
    116   return 0.0;
    117 }
    118 
    119 void AudioRecordInputStream::SetVolume(double volume) {
    120   NOTIMPLEMENTED();
    121 }
    122 
    123 double AudioRecordInputStream::GetVolume() {
    124   NOTIMPLEMENTED();
    125   return 0.0;
    126 }
    127 
    128 void AudioRecordInputStream::SetAutomaticGainControl(bool enabled) {
    129   NOTIMPLEMENTED();
    130 }
    131 
    132 bool AudioRecordInputStream::GetAutomaticGainControl() {
    133   NOTIMPLEMENTED();
    134   return false;
    135 }
    136 
    137 }  // namespace media
    138