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,
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       const AudioParameters& params,
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                       SLint32 stream_type);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~OpenSLESOutputStream();
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Implementation of AudioOutputStream.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Open() OVERRIDE;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Close() OVERRIDE;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Start(AudioSourceCallback* callback) OVERRIDE;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Stop() OVERRIDE;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetVolume(double volume) OVERRIDE;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void GetVolume(double* volume) OVERRIDE;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Set the value of |muted_|. It does not affect |volume_| which can be
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // got by calling GetVolume(). See comments for |muted_| below.
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void SetMute(bool muted);
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool CreatePlayer();
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Called from OpenSLES specific audio worker thread.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void SimpleBufferQueueCallback(
53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      SLAndroidSimpleBufferQueueItf buffer_queue,
54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      void* instance);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Fills up one buffer by asking the registered source for data.
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Called from OpenSLES specific audio worker thread.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FillBufferQueue();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Called from the audio manager thread.
61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void FillBufferQueueNoLock();
62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called in Open();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetupAudioBuffer();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called in Close();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ReleaseAudioBuffer();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If OpenSLES reports an error this function handles it and passes it to
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the attached AudioOutputCallback::OnError().
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleError(SLresult error);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::ThreadChecker thread_checker_;
74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Protects |callback_|, |active_buffer_index_|, |audio_data_|,
76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // |buffer_size_bytes_| and |simple_buffer_queue_|.
77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::Lock lock_;
78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AudioManagerAndroid* audio_manager_;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Audio playback stream type.
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // See SLES/OpenSLES_Android.h for details.
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SLint32 stream_type_;
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AudioSourceCallback* callback_;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shared engine interfaces for the app.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  media::ScopedSLObjectItf engine_object_;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  media::ScopedSLObjectItf player_object_;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  media::ScopedSLObjectItf output_mixer_;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SLPlayItf player_;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Buffer queue recorder interface.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SLAndroidSimpleBufferQueueItf simple_buffer_queue_;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SLDataFormat_PCM format_;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Audio buffers that are allocated in the constructor based on
100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // info from audio parameters.
101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  uint8* audio_data_[kMaxNumOfBuffersInQueue];
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int active_buffer_index_;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t buffer_size_bytes_;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool started_;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Volume control coming from hardware. It overrides |volume_| when it's
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // true. Otherwise, use |volume_| for scaling.
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This is needed because platform voice volume never goes to zero in
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // COMMUNICATION mode on Android.
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bool muted_;
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Volume level from 0 to 1.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float volume_;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Container for retrieving data from AudioSourceCallback::OnMoreData().
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AudioBus> audio_bus_;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OpenSLESOutputStream);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif  // MEDIA_AUDIO_ANDROID_OPENSLES_OUTPUT_H_
126