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_OUTPUT_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MEDIA_AUDIO_ANDROID_OPENSLES_OUTPUT_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <SLES/OpenSLES.h>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <SLES/OpenSLES_Android.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
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"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (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)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AudioManagerAndroid;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implements PCM audio output support for Android using the OpenSLES API.
23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// This class is created and lives on the Audio Manager thread but recorded
24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// audio buffers are given to us from an internal OpenSLES audio thread.
25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// All public methods should be called on the Audio Manager thread.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class OpenSLESOutputStream : public AudioOutputStream {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  static const int kMaxNumOfBuffersInQueue = 2;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OpenSLESOutputStream(AudioManagerAndroid* manager,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const AudioParameters& params);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OpenSLESOutputStream();
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Implementation of AudioOutputStream.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Open() OVERRIDE;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Close() OVERRIDE;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Start(AudioSourceCallback* callback) OVERRIDE;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Stop() OVERRIDE;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetVolume(double volume) OVERRIDE;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetVolume(double* volume) OVERRIDE;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Set the value of |muted_|. It does not affect |volume_| which can be
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // got by calling GetVolume(). See comments for |muted_| below.
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void SetMute(bool muted);
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool CreatePlayer();
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)  // Fills up one buffer by asking the registered source for data.
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Called from OpenSLES specific audio worker thread.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FillBufferQueue();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Called from the audio manager thread.
60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void FillBufferQueueNoLock();
61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called in Open();
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetupAudioBuffer();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called in Close();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ReleaseAudioBuffer();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If OpenSLES reports an error this function handles it and passes it to
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the attached AudioOutputCallback::OnError().
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleError(SLresult error);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::ThreadChecker thread_checker_;
73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Protects |callback_|, |active_buffer_index_|, |audio_data_|,
75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // |buffer_size_bytes_| and |simple_buffer_queue_|.
76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::Lock lock_;
77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AudioManagerAndroid* audio_manager_;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AudioSourceCallback* callback_;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shared engine interfaces for the app.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  media::ScopedSLObjectItf engine_object_;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  media::ScopedSLObjectItf player_object_;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  media::ScopedSLObjectItf output_mixer_;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SLPlayItf player_;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Buffer queue recorder interface.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SLAndroidSimpleBufferQueueItf simple_buffer_queue_;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SLDataFormat_PCM format_;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Audio buffers that are allocated in the constructor based on
95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // info from audio parameters.
96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  uint8* audio_data_[kMaxNumOfBuffersInQueue];
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int active_buffer_index_;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t buffer_size_bytes_;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool started_;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Volume control coming from hardware. It overrides |volume_| when it's
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // true. Otherwise, use |volume_| for scaling.
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This is needed because platform voice volume never goes to zero in
106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // COMMUNICATION mode on Android.
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool muted_;
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Volume level from 0 to 1.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float volume_;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Container for retrieving data from AudioSourceCallback::OnMoreData().
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AudioBus> audio_bus_;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OpenSLESOutputStream);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif  // MEDIA_AUDIO_ANDROID_OPENSLES_OUTPUT_H_
121