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)#ifndef MEDIA_AUDIO_ANDROID_OPENSLES_INPUT_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MEDIA_AUDIO_ANDROID_OPENSLES_INPUT_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <SLES/OpenSLES.h> 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <SLES/OpenSLES_Android.h> 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/synchronization/lock.h" 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/threading/thread_checker.h" 14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "media/audio/android/opensles_util.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/audio/audio_io.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/audio/audio_parameters.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)class AudioBus; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AudioManagerAndroid; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implements PCM audio input support for Android using the OpenSLES API. 24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// This class is created and lives on the Audio Manager thread but recorded 25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// audio buffers are delivered on an internal OpenSLES audio thread. All public 26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// methods should be called on the Audio Manager thread. 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OpenSLESInputStream : public AudioInputStream { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) static const int kMaxNumOfBuffersInQueue = 2; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenSLESInputStream(AudioManagerAndroid* manager, 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AudioParameters& params); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~OpenSLESInputStream(); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Implementation of AudioInputStream. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Open() OVERRIDE; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Start(AudioInputCallback* callback) OVERRIDE; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Stop() OVERRIDE; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Close() OVERRIDE; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual double GetMaxVolume() OVERRIDE; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetVolume(double volume) OVERRIDE; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual double GetVolume() OVERRIDE; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetAutomaticGainControl(bool enabled) OVERRIDE; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetAutomaticGainControl() OVERRIDE; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CreateRecorder(); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Called from OpenSLES specific audio worker thread. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void SimpleBufferQueueCallback( 52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SLAndroidSimpleBufferQueueItf buffer_queue, 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void* instance); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Called from OpenSLES specific audio worker thread. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReadBufferQueue(); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called in Open(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetupAudioBuffer(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called in Close(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReleaseAudioBuffer(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If OpenSLES reports an error this function handles it and passes it to 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the attached AudioInputCallback::OnError(). 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void HandleError(SLresult error); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::ThreadChecker thread_checker_; 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Protects |callback_|, |active_buffer_index_|, |audio_data_|, 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // |buffer_size_bytes_| and |simple_buffer_queue_|. 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::Lock lock_; 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioManagerAndroid* audio_manager_; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioInputCallback* callback_; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shared engine interfaces for the app. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::ScopedSLObjectItf recorder_object_; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media::ScopedSLObjectItf engine_object_; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SLRecordItf recorder_; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Buffer queue recorder interface. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SLAndroidSimpleBufferQueueItf simple_buffer_queue_; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SLDataFormat_PCM format_; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Audio buffers that are allocated in the constructor based on 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // info from audio parameters. 91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) uint8* audio_data_[kMaxNumOfBuffersInQueue]; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int active_buffer_index_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buffer_size_bytes_; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool started_; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) scoped_ptr<media::AudioBus> audio_bus_; 996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(OpenSLESInputStream); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // MEDIA_AUDIO_ANDROID_OPENSLES_INPUT_H_ 106