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
AudioRecordInputStream(AudioManagerAndroid * audio_manager,const AudioParameters & params)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
~AudioRecordInputStream()35 AudioRecordInputStream::~AudioRecordInputStream() {
36 DVLOG(2) << __PRETTY_FUNCTION__;
37 DCHECK(thread_checker_.CalledOnValidThread());
38 }
39
CacheDirectBufferAddress(JNIEnv * env,jobject obj,jobject byte_buffer)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
RegisterAudioRecordInput(JNIEnv * env)48 bool AudioRecordInputStream::RegisterAudioRecordInput(JNIEnv* env) {
49 return RegisterNativesImpl(env);
50 }
51
OnData(JNIEnv * env,jobject obj,jint size,jint hardware_delay_bytes)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
Open()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
Start(AudioInputCallback * callback)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
Stop()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
Close()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
GetMaxVolume()114 double AudioRecordInputStream::GetMaxVolume() {
115 NOTIMPLEMENTED();
116 return 0.0;
117 }
118
SetVolume(double volume)119 void AudioRecordInputStream::SetVolume(double volume) {
120 NOTIMPLEMENTED();
121 }
122
GetVolume()123 double AudioRecordInputStream::GetVolume() {
124 NOTIMPLEMENTED();
125 return 0.0;
126 }
127
SetAutomaticGainControl(bool enabled)128 void AudioRecordInputStream::SetAutomaticGainControl(bool enabled) {
129 NOTIMPLEMENTED();
130 }
131
GetAutomaticGainControl()132 bool AudioRecordInputStream::GetAutomaticGainControl() {
133 NOTIMPLEMENTED();
134 return false;
135 }
136
IsMuted()137 bool AudioRecordInputStream::IsMuted() {
138 NOTIMPLEMENTED();
139 return false;
140 }
141
142 } // namespace media
143