
scoped_array is deprecated. This was done using a Chromium clang tool: http://src.chromium.org/viewvc/chrome/trunk/src/tools/clang/rewrite_scoped_ar... except for the few not-built-on-Linux files which were updated manually. TESTED=trybots BUG=2515 R=niklas.enbom@webrtc.org Review URL: https://webrtc-codereview.appspot.com/12429004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5985 4adac7df-926f-26a2-2b94-8c16560cd09d
225 lines
8.1 KiB
C++
225 lines
8.1 KiB
C++
/*
|
|
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#ifndef WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_INPUT_H_
|
|
#define WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_INPUT_H_
|
|
|
|
#include <SLES/OpenSLES.h>
|
|
#include <SLES/OpenSLES_Android.h>
|
|
#include <SLES/OpenSLES_AndroidConfiguration.h>
|
|
|
|
#include "webrtc/modules/audio_device/android/audio_manager_jni.h"
|
|
#include "webrtc/modules/audio_device/android/low_latency_event.h"
|
|
#include "webrtc/modules/audio_device/include/audio_device.h"
|
|
#include "webrtc/modules/audio_device/include/audio_device_defines.h"
|
|
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
|
|
|
namespace webrtc {
|
|
|
|
class AudioDeviceBuffer;
|
|
class CriticalSectionWrapper;
|
|
class PlayoutDelayProvider;
|
|
class SingleRwFifo;
|
|
class ThreadWrapper;
|
|
|
|
// OpenSL implementation that facilitate capturing PCM data from an android
|
|
// device's microphone.
|
|
// This class is Thread-compatible. I.e. Given an instance of this class, calls
|
|
// to non-const methods require exclusive access to the object.
|
|
class OpenSlesInput {
|
|
public:
|
|
OpenSlesInput(const int32_t id, PlayoutDelayProvider* delay_provider);
|
|
~OpenSlesInput();
|
|
|
|
static int32_t SetAndroidAudioDeviceObjects(void* javaVM,
|
|
void* env,
|
|
void* context);
|
|
static void ClearAndroidAudioDeviceObjects();
|
|
|
|
// Main initializaton and termination
|
|
int32_t Init();
|
|
int32_t Terminate();
|
|
bool Initialized() const { return initialized_; }
|
|
|
|
// Device enumeration
|
|
int16_t RecordingDevices() { return 1; }
|
|
int32_t RecordingDeviceName(uint16_t index,
|
|
char name[kAdmMaxDeviceNameSize],
|
|
char guid[kAdmMaxGuidSize]);
|
|
|
|
// Device selection
|
|
int32_t SetRecordingDevice(uint16_t index);
|
|
int32_t SetRecordingDevice(
|
|
AudioDeviceModule::WindowsDeviceType device) { return -1; }
|
|
|
|
// No-op
|
|
int32_t SetRecordingSampleRate(uint32_t sample_rate_hz) { return 0; }
|
|
|
|
// Audio transport initialization
|
|
int32_t RecordingIsAvailable(bool& available); // NOLINT
|
|
int32_t InitRecording();
|
|
bool RecordingIsInitialized() const { return rec_initialized_; }
|
|
|
|
// Audio transport control
|
|
int32_t StartRecording();
|
|
int32_t StopRecording();
|
|
bool Recording() const { return recording_; }
|
|
|
|
// Microphone Automatic Gain Control (AGC)
|
|
int32_t SetAGC(bool enable);
|
|
bool AGC() const { return agc_enabled_; }
|
|
|
|
// Audio mixer initialization
|
|
int32_t InitMicrophone();
|
|
bool MicrophoneIsInitialized() const { return mic_initialized_; }
|
|
|
|
// Microphone volume controls
|
|
int32_t MicrophoneVolumeIsAvailable(bool& available); // NOLINT
|
|
// TODO(leozwang): Add microphone volume control when OpenSL APIs
|
|
// are available.
|
|
int32_t SetMicrophoneVolume(uint32_t volume) { return 0; }
|
|
int32_t MicrophoneVolume(uint32_t& volume) const { return -1; } // NOLINT
|
|
int32_t MaxMicrophoneVolume(
|
|
uint32_t& maxVolume) const { return 0; } // NOLINT
|
|
int32_t MinMicrophoneVolume(uint32_t& minVolume) const; // NOLINT
|
|
int32_t MicrophoneVolumeStepSize(
|
|
uint16_t& stepSize) const; // NOLINT
|
|
|
|
// Microphone mute control
|
|
int32_t MicrophoneMuteIsAvailable(bool& available); // NOLINT
|
|
int32_t SetMicrophoneMute(bool enable) { return -1; }
|
|
int32_t MicrophoneMute(bool& enabled) const { return -1; } // NOLINT
|
|
|
|
// Microphone boost control
|
|
int32_t MicrophoneBoostIsAvailable(bool& available); // NOLINT
|
|
int32_t SetMicrophoneBoost(bool enable);
|
|
int32_t MicrophoneBoost(bool& enabled) const; // NOLINT
|
|
|
|
// Stereo support
|
|
int32_t StereoRecordingIsAvailable(bool& available); // NOLINT
|
|
int32_t SetStereoRecording(bool enable) { return -1; }
|
|
int32_t StereoRecording(bool& enabled) const; // NOLINT
|
|
|
|
// Delay information and control
|
|
int32_t RecordingDelay(uint16_t& delayMS) const; // NOLINT
|
|
|
|
bool RecordingWarning() const { return false; }
|
|
bool RecordingError() const { return false; }
|
|
void ClearRecordingWarning() {}
|
|
void ClearRecordingError() {}
|
|
|
|
// Attach audio buffer
|
|
void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer);
|
|
|
|
private:
|
|
enum {
|
|
kNumInterfaces = 2,
|
|
// Keep as few OpenSL buffers as possible to avoid wasting memory. 2 is
|
|
// minimum for playout. Keep 2 for recording as well.
|
|
kNumOpenSlBuffers = 2,
|
|
kNum10MsToBuffer = 3,
|
|
};
|
|
|
|
int InitSampleRate();
|
|
int buffer_size_samples() const;
|
|
int buffer_size_bytes() const;
|
|
void UpdateRecordingDelay();
|
|
void UpdateSampleRate();
|
|
void CalculateNumFifoBuffersNeeded();
|
|
void AllocateBuffers();
|
|
int TotalBuffersUsed() const;
|
|
bool EnqueueAllBuffers();
|
|
// This function also configures the audio recorder, e.g. sample rate to use
|
|
// etc, so it should be called when starting recording.
|
|
bool CreateAudioRecorder();
|
|
void DestroyAudioRecorder();
|
|
|
|
// When overrun happens there will be more frames received from OpenSL than
|
|
// the desired number of buffers. It is possible to expand the number of
|
|
// buffers as you go but that would greatly increase the complexity of this
|
|
// code. HandleOverrun gracefully handles the scenario by restarting playout,
|
|
// throwing away all pending audio data. This will sound like a click. This
|
|
// is also logged to identify these types of clicks.
|
|
// This function returns true if there has been overrun. Further processing
|
|
// of audio data should be avoided until this function returns false again.
|
|
// The function needs to be protected by |crit_sect_|.
|
|
bool HandleOverrun(int event_id, int event_msg);
|
|
|
|
static void RecorderSimpleBufferQueueCallback(
|
|
SLAndroidSimpleBufferQueueItf queueItf,
|
|
void* pContext);
|
|
// This function must not take any locks or do any heavy work. It is a
|
|
// requirement for the OpenSL implementation to work as intended. The reason
|
|
// for this is that taking locks exposes the OpenSL thread to the risk of
|
|
// priority inversion.
|
|
void RecorderSimpleBufferQueueCallbackHandler(
|
|
SLAndroidSimpleBufferQueueItf queueItf);
|
|
|
|
bool StartCbThreads();
|
|
void StopCbThreads();
|
|
static bool CbThread(void* context);
|
|
// This function must be protected against data race with threads calling this
|
|
// class' public functions. It is a requirement for this class to be
|
|
// Thread-compatible.
|
|
bool CbThreadImpl();
|
|
|
|
// Java API handle
|
|
AudioManagerJni audio_manager_;
|
|
|
|
int id_;
|
|
PlayoutDelayProvider* delay_provider_;
|
|
bool initialized_;
|
|
bool mic_initialized_;
|
|
bool rec_initialized_;
|
|
|
|
// Members that are read/write accessed concurrently by the process thread and
|
|
// threads calling public functions of this class.
|
|
scoped_ptr<ThreadWrapper> rec_thread_; // Processing thread
|
|
scoped_ptr<CriticalSectionWrapper> crit_sect_;
|
|
// This member controls the starting and stopping of recording audio to the
|
|
// the device.
|
|
bool recording_;
|
|
|
|
// Only one thread, T1, may push and only one thread, T2, may pull. T1 may or
|
|
// may not be the same thread as T2. T2 is the process thread and T1 is the
|
|
// OpenSL thread.
|
|
scoped_ptr<SingleRwFifo> fifo_;
|
|
int num_fifo_buffers_needed_;
|
|
LowLatencyEvent event_;
|
|
int number_overruns_;
|
|
|
|
// OpenSL handles
|
|
SLObjectItf sles_engine_;
|
|
SLEngineItf sles_engine_itf_;
|
|
SLObjectItf sles_recorder_;
|
|
SLRecordItf sles_recorder_itf_;
|
|
SLAndroidSimpleBufferQueueItf sles_recorder_sbq_itf_;
|
|
|
|
// Audio buffers
|
|
AudioDeviceBuffer* audio_buffer_;
|
|
// Holds all allocated memory such that it is deallocated properly.
|
|
scoped_ptr<scoped_ptr<int8_t[]>[]> rec_buf_;
|
|
// Index in |rec_buf_| pointing to the audio buffer that will be ready the
|
|
// next time RecorderSimpleBufferQueueCallbackHandler is invoked.
|
|
// Ready means buffer contains audio data from the device.
|
|
int active_queue_;
|
|
|
|
// Audio settings
|
|
uint32_t rec_sampling_rate_;
|
|
bool agc_enabled_;
|
|
|
|
// Audio status
|
|
uint16_t recording_delay_;
|
|
};
|
|
|
|
} // namespace webrtc
|
|
|
|
#endif // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_OPENSLES_INPUT_H_
|