Home | History | Annotate | Download | only in android
      1 /*
      2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #ifndef WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_AUDIO_TRACK_JNI_H_
     12 #define WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_AUDIO_TRACK_JNI_H_
     13 
     14 #include <jni.h>
     15 
     16 #include "webrtc/base/thread_checker.h"
     17 #include "webrtc/modules/audio_device/android/audio_common.h"
     18 #include "webrtc/modules/audio_device/android/audio_manager.h"
     19 #include "webrtc/modules/audio_device/include/audio_device_defines.h"
     20 #include "webrtc/modules/audio_device/audio_device_generic.h"
     21 #include "webrtc/modules/utility/include/helpers_android.h"
     22 #include "webrtc/modules/utility/include/jvm_android.h"
     23 
     24 namespace webrtc {
     25 
     26 // Implements 16-bit mono PCM audio output support for Android using the Java
     27 // AudioTrack interface. Most of the work is done by its Java counterpart in
     28 // WebRtcAudioTrack.java. This class is created and lives on a thread in
     29 // C++-land, but decoded audio buffers are requested on a high-priority
     30 // thread managed by the Java class.
     31 //
     32 // An instance must be created and destroyed on one and the same thread.
     33 // All public methods must also be called on the same thread. A thread checker
     34 // will RTC_DCHECK if any method is called on an invalid thread.
     35 //
     36 // This class uses AttachCurrentThreadIfNeeded to attach to a Java VM if needed
     37 // and detach when the object goes out of scope. Additional thread checking
     38 // guarantees that no other (possibly non attached) thread is used.
     39 class AudioTrackJni {
     40  public:
     41   // Wraps the Java specific parts of the AudioTrackJni into one helper class.
     42   class JavaAudioTrack {
     43    public:
     44     JavaAudioTrack(NativeRegistration* native_registration,
     45                    rtc::scoped_ptr<GlobalRef> audio_track);
     46     ~JavaAudioTrack();
     47 
     48     void InitPlayout(int sample_rate, int channels);
     49     bool StartPlayout();
     50     bool StopPlayout();
     51     bool SetStreamVolume(int volume);
     52     int GetStreamMaxVolume();
     53     int GetStreamVolume();
     54 
     55    private:
     56     rtc::scoped_ptr<GlobalRef> audio_track_;
     57     jmethodID init_playout_;
     58     jmethodID start_playout_;
     59     jmethodID stop_playout_;
     60     jmethodID set_stream_volume_;
     61     jmethodID get_stream_max_volume_;
     62     jmethodID get_stream_volume_;
     63   };
     64 
     65   explicit AudioTrackJni(AudioManager* audio_manager);
     66   ~AudioTrackJni();
     67 
     68   int32_t Init();
     69   int32_t Terminate();
     70 
     71   int32_t InitPlayout();
     72   bool PlayoutIsInitialized() const { return initialized_; }
     73 
     74   int32_t StartPlayout();
     75   int32_t StopPlayout();
     76   bool Playing() const { return playing_; }
     77 
     78   int SpeakerVolumeIsAvailable(bool& available);
     79   int SetSpeakerVolume(uint32_t volume);
     80   int SpeakerVolume(uint32_t& volume) const;
     81   int MaxSpeakerVolume(uint32_t& max_volume) const;
     82   int MinSpeakerVolume(uint32_t& min_volume) const;
     83 
     84   void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer);
     85 
     86  private:
     87   // Called from Java side so we can cache the address of the Java-manged
     88   // |byte_buffer| in |direct_buffer_address_|. The size of the buffer
     89   // is also stored in |direct_buffer_capacity_in_bytes_|.
     90   // Called on the same thread as the creating thread.
     91   static void JNICALL CacheDirectBufferAddress(
     92     JNIEnv* env, jobject obj, jobject byte_buffer, jlong nativeAudioTrack);
     93   void OnCacheDirectBufferAddress(JNIEnv* env, jobject byte_buffer);
     94 
     95   // Called periodically by the Java based WebRtcAudioTrack object when
     96   // playout has started. Each call indicates that |length| new bytes should
     97   // be written to the memory area |direct_buffer_address_| for playout.
     98   // This method is called on a high-priority thread from Java. The name of
     99   // the thread is 'AudioTrackThread'.
    100   static void JNICALL GetPlayoutData(
    101     JNIEnv* env, jobject obj, jint length, jlong nativeAudioTrack);
    102   void OnGetPlayoutData(size_t length);
    103 
    104   // Stores thread ID in constructor.
    105   rtc::ThreadChecker thread_checker_;
    106 
    107   // Stores thread ID in first call to OnGetPlayoutData() from high-priority
    108   // thread in Java. Detached during construction of this object.
    109   rtc::ThreadChecker thread_checker_java_;
    110 
    111   // Calls AttachCurrentThread() if this thread is not attached at construction.
    112   // Also ensures that DetachCurrentThread() is called at destruction.
    113   AttachCurrentThreadIfNeeded attach_thread_if_needed_;
    114 
    115   // Wraps the JNI interface pointer and methods associated with it.
    116   rtc::scoped_ptr<JNIEnvironment> j_environment_;
    117 
    118   // Contains factory method for creating the Java object.
    119   rtc::scoped_ptr<NativeRegistration> j_native_registration_;
    120 
    121   // Wraps the Java specific parts of the AudioTrackJni class.
    122   rtc::scoped_ptr<AudioTrackJni::JavaAudioTrack> j_audio_track_;
    123 
    124   // Contains audio parameters provided to this class at construction by the
    125   // AudioManager.
    126   const AudioParameters audio_parameters_;
    127 
    128   // Cached copy of address to direct audio buffer owned by |j_audio_track_|.
    129   void* direct_buffer_address_;
    130 
    131   // Number of bytes in the direct audio buffer owned by |j_audio_track_|.
    132   size_t direct_buffer_capacity_in_bytes_;
    133 
    134   // Number of audio frames per audio buffer. Each audio frame corresponds to
    135   // one sample of PCM mono data at 16 bits per sample. Hence, each audio
    136   // frame contains 2 bytes (given that the Java layer only supports mono).
    137   // Example: 480 for 48000 Hz or 441 for 44100 Hz.
    138   size_t frames_per_buffer_;
    139 
    140   bool initialized_;
    141 
    142   bool playing_;
    143 
    144   // Raw pointer handle provided to us in AttachAudioBuffer(). Owned by the
    145   // AudioDeviceModuleImpl class and called by AudioDeviceModuleImpl::Create().
    146   // The AudioDeviceBuffer is a member of the AudioDeviceModuleImpl instance
    147   // and therefore outlives this object.
    148   AudioDeviceBuffer* audio_device_buffer_;
    149 };
    150 
    151 }  // namespace webrtc
    152 
    153 #endif  // WEBRTC_MODULES_AUDIO_DEVICE_ANDROID_AUDIO_TRACK_JNI_H_
    154