Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef AAUDIO_AUDIOSTREAM_H
     18 #define AAUDIO_AUDIOSTREAM_H
     19 
     20 #include <atomic>
     21 #include <mutex>
     22 #include <stdint.h>
     23 #include <aaudio/AAudio.h>
     24 #include <binder/IServiceManager.h>
     25 #include <binder/Status.h>
     26 #include <utils/StrongPointer.h>
     27 
     28 #include "media/VolumeShaper.h"
     29 #include "media/PlayerBase.h"
     30 #include "utility/AAudioUtilities.h"
     31 #include "utility/MonotonicCounter.h"
     32 
     33 // Cannot get android::media::VolumeShaper to compile!
     34 #define AAUDIO_USE_VOLUME_SHAPER  0
     35 
     36 namespace aaudio {
     37 
     38 typedef void *(*aaudio_audio_thread_proc_t)(void *);
     39 
     40 class AudioStreamBuilder;
     41 
     42 /**
     43  * AAudio audio stream.
     44  */
     45 class AudioStream {
     46 public:
     47 
     48     AudioStream();
     49 
     50     virtual ~AudioStream();
     51 
     52 
     53     // =========== Begin ABSTRACT methods ===========================
     54 
     55     /* Asynchronous requests.
     56      * Use waitForStateChange() to wait for completion.
     57      */
     58     virtual aaudio_result_t requestStart() = 0;
     59 
     60     virtual aaudio_result_t requestPause()
     61     {
     62         // Only implement this for OUTPUT streams.
     63         return AAUDIO_ERROR_UNIMPLEMENTED;
     64     }
     65 
     66     virtual aaudio_result_t requestFlush() {
     67         // Only implement this for OUTPUT streams.
     68         return AAUDIO_ERROR_UNIMPLEMENTED;
     69     }
     70 
     71     virtual aaudio_result_t requestStop() = 0;
     72 
     73     virtual aaudio_result_t getTimestamp(clockid_t clockId,
     74                                        int64_t *framePosition,
     75                                        int64_t *timeNanoseconds) = 0;
     76 
     77 
     78     /**
     79      * Update state machine.()
     80      * @return
     81      */
     82     virtual aaudio_result_t updateStateMachine() = 0;
     83 
     84 
     85     // =========== End ABSTRACT methods ===========================
     86 
     87     virtual aaudio_result_t waitForStateChange(aaudio_stream_state_t currentState,
     88                                                aaudio_stream_state_t *nextState,
     89                                                int64_t timeoutNanoseconds);
     90 
     91     /**
     92      * Open the stream using the parameters in the builder.
     93      * Allocate the necessary resources.
     94      */
     95     virtual aaudio_result_t open(const AudioStreamBuilder& builder);
     96 
     97     /**
     98      * Close the stream and deallocate any resources from the open() call.
     99      * It is safe to call close() multiple times.
    100      */
    101     virtual aaudio_result_t close() {
    102         return AAUDIO_OK;
    103     }
    104 
    105     virtual aaudio_result_t setBufferSize(int32_t requestedFrames) = 0;
    106 
    107     virtual aaudio_result_t createThread(int64_t periodNanoseconds,
    108                                        aaudio_audio_thread_proc_t threadProc,
    109                                        void *threadArg);
    110 
    111     aaudio_result_t joinThread(void **returnArg, int64_t timeoutNanoseconds);
    112 
    113     virtual aaudio_result_t registerThread() {
    114         return AAUDIO_OK;
    115     }
    116 
    117     virtual aaudio_result_t unregisterThread() {
    118         return AAUDIO_OK;
    119     }
    120 
    121     /**
    122      * Internal function used to call the audio thread passed by the user.
    123      * It is unfortunately public because it needs to be called by a static 'C' function.
    124      */
    125     void* wrapUserThread();
    126 
    127     // ============== Queries ===========================
    128 
    129     aaudio_stream_state_t getState() const {
    130         return mState;
    131     }
    132 
    133     virtual int32_t getBufferSize() const {
    134         return AAUDIO_ERROR_UNIMPLEMENTED;
    135     }
    136 
    137     virtual int32_t getBufferCapacity() const {
    138         return AAUDIO_ERROR_UNIMPLEMENTED;
    139     }
    140 
    141     virtual int32_t getFramesPerBurst() const {
    142         return AAUDIO_ERROR_UNIMPLEMENTED;
    143     }
    144 
    145     virtual int32_t getXRunCount() const {
    146         return AAUDIO_ERROR_UNIMPLEMENTED;
    147     }
    148 
    149     bool isActive() const {
    150         return mState == AAUDIO_STREAM_STATE_STARTING || mState == AAUDIO_STREAM_STATE_STARTED;
    151     }
    152 
    153     virtual bool isMMap() {
    154         return false;
    155     }
    156 
    157     aaudio_result_t getSampleRate() const {
    158         return mSampleRate;
    159     }
    160 
    161     aaudio_format_t getFormat()  const {
    162         return mFormat;
    163     }
    164 
    165     aaudio_result_t getSamplesPerFrame() const {
    166         return mSamplesPerFrame;
    167     }
    168 
    169     virtual int32_t getPerformanceMode() const {
    170         return mPerformanceMode;
    171     }
    172 
    173     void setPerformanceMode(aaudio_performance_mode_t performanceMode) {
    174         mPerformanceMode = performanceMode;
    175     }
    176 
    177     int32_t getDeviceId() const {
    178         return mDeviceId;
    179     }
    180 
    181     aaudio_sharing_mode_t getSharingMode() const {
    182         return mSharingMode;
    183     }
    184 
    185     bool isSharingModeMatchRequired() const {
    186         return mSharingModeMatchRequired;
    187     }
    188 
    189     virtual aaudio_direction_t getDirection() const = 0;
    190 
    191     /**
    192      * This is only valid after setSamplesPerFrame() and setFormat() have been called.
    193      */
    194     int32_t getBytesPerFrame() const {
    195         return mSamplesPerFrame * getBytesPerSample();
    196     }
    197 
    198     /**
    199      * This is only valid after setFormat() has been called.
    200      */
    201     int32_t getBytesPerSample() const {
    202         return AAudioConvert_formatToSizeInBytes(mFormat);
    203     }
    204 
    205     virtual int64_t getFramesWritten() = 0;
    206 
    207     virtual int64_t getFramesRead() = 0;
    208 
    209     AAudioStream_dataCallback getDataCallbackProc() const {
    210         return mDataCallbackProc;
    211     }
    212     AAudioStream_errorCallback getErrorCallbackProc() const {
    213         return mErrorCallbackProc;
    214     }
    215 
    216     void *getDataCallbackUserData() const {
    217         return mDataCallbackUserData;
    218     }
    219     void *getErrorCallbackUserData() const {
    220         return mErrorCallbackUserData;
    221     }
    222 
    223     int32_t getFramesPerDataCallback() const {
    224         return mFramesPerDataCallback;
    225     }
    226 
    227     bool isDataCallbackActive() {
    228         return (mDataCallbackProc != nullptr) && isActive();
    229     }
    230 
    231     // ============== I/O ===========================
    232     // A Stream will only implement read() or write() depending on its direction.
    233     virtual aaudio_result_t write(const void *buffer __unused,
    234                              int32_t numFrames __unused,
    235                              int64_t timeoutNanoseconds __unused) {
    236         return AAUDIO_ERROR_UNIMPLEMENTED;
    237     }
    238 
    239     virtual aaudio_result_t read(void *buffer __unused,
    240                             int32_t numFrames __unused,
    241                             int64_t timeoutNanoseconds __unused) {
    242         return AAUDIO_ERROR_UNIMPLEMENTED;
    243     }
    244 
    245     // This is used by the AudioManager to duck and mute the stream when changing audio focus.
    246     void setDuckAndMuteVolume(float duckAndMuteVolume) {
    247         mDuckAndMuteVolume = duckAndMuteVolume;
    248         doSetVolume(); // apply this change
    249     }
    250 
    251     float getDuckAndMuteVolume() {
    252         return mDuckAndMuteVolume;
    253     }
    254 
    255     // Implement this in the output subclasses.
    256     virtual android::status_t doSetVolume() { return android::NO_ERROR; }
    257 
    258 #if AAUDIO_USE_VOLUME_SHAPER
    259     virtual ::android::binder::Status applyVolumeShaper(
    260             const ::android::media::VolumeShaper::Configuration& configuration __unused,
    261             const ::android::media::VolumeShaper::Operation& operation __unused);
    262 #endif
    263 
    264     /**
    265      * Register this stream's PlayerBase with the AudioManager if needed.
    266      * Only register output streams.
    267      * This should only be called for client streams and not for streams
    268      * that run in the service.
    269      */
    270     void registerPlayerBase() {
    271         if (getDirection() == AAUDIO_DIRECTION_OUTPUT) {
    272             mPlayerBase->registerWithAudioManager();
    273         }
    274     }
    275 
    276     /**
    277      * Unregister this stream's PlayerBase with the AudioManager.
    278      * This will only unregister if already registered.
    279      */
    280     void unregisterPlayerBase() {
    281         mPlayerBase->unregisterWithAudioManager();
    282     }
    283 
    284     // Pass start request through PlayerBase for tracking.
    285     aaudio_result_t systemStart() {
    286         mPlayerBase->start();
    287         // Pass aaudio_result_t around the PlayerBase interface, which uses status__t.
    288         return mPlayerBase->getResult();
    289     }
    290 
    291     aaudio_result_t systemPause() {
    292         mPlayerBase->pause();
    293         return mPlayerBase->getResult();
    294     }
    295 
    296     aaudio_result_t systemStop() {
    297         mPlayerBase->stop();
    298         return mPlayerBase->getResult();
    299     }
    300 
    301 protected:
    302 
    303     // PlayerBase allows the system to control the stream.
    304     // Calling through PlayerBase->start() notifies the AudioManager of the player state.
    305     // The AudioManager also can start/stop a stream by calling mPlayerBase->playerStart().
    306     // systemStart() ==> mPlayerBase->start()   mPlayerBase->playerStart() ==> requestStart()
    307     //                        \                           /
    308     //                         ------ AudioManager -------
    309     class MyPlayerBase : public android::PlayerBase {
    310     public:
    311         explicit MyPlayerBase(AudioStream *parent);
    312 
    313         virtual ~MyPlayerBase();
    314 
    315         /**
    316          * Register for volume changes and remote control.
    317          */
    318         void registerWithAudioManager();
    319 
    320         /**
    321          * UnRegister.
    322          */
    323         void unregisterWithAudioManager();
    324 
    325         /**
    326          * Just calls unregisterWithAudioManager().
    327          */
    328         void destroy() override;
    329 
    330         void clearParentReference() { mParent = nullptr; }
    331 
    332         android::status_t playerStart() override {
    333             // mParent should NOT be null. So go ahead and crash if it is.
    334             mResult = mParent->requestStart();
    335             return AAudioConvert_aaudioToAndroidStatus(mResult);
    336         }
    337 
    338         android::status_t playerPause() override {
    339             mResult = mParent->requestPause();
    340             return AAudioConvert_aaudioToAndroidStatus(mResult);
    341         }
    342 
    343         android::status_t playerStop() override {
    344             mResult = mParent->requestStop();
    345             return AAudioConvert_aaudioToAndroidStatus(mResult);
    346         }
    347 
    348         android::status_t playerSetVolume() override {
    349             // No pan and only left volume is taken into account from IPLayer interface
    350             mParent->setDuckAndMuteVolume(mVolumeMultiplierL  /* * mPanMultiplierL */);
    351             return android::NO_ERROR;
    352         }
    353 
    354 #if AAUDIO_USE_VOLUME_SHAPER
    355         ::android::binder::Status applyVolumeShaper(
    356                 const ::android::media::VolumeShaper::Configuration& configuration,
    357                 const ::android::media::VolumeShaper::Operation& operation) {
    358             return mParent->applyVolumeShaper(configuration, operation);
    359         }
    360 #endif
    361 
    362         aaudio_result_t getResult() {
    363             return mResult;
    364         }
    365 
    366     private:
    367         AudioStream          *mParent;
    368         aaudio_result_t       mResult = AAUDIO_OK;
    369         bool                  mRegistered = false;
    370     };
    371 
    372     /**
    373      * This should not be called after the open() call.
    374      */
    375     void setSampleRate(int32_t sampleRate) {
    376         mSampleRate = sampleRate;
    377     }
    378 
    379     /**
    380      * This should not be called after the open() call.
    381      */
    382     void setSamplesPerFrame(int32_t samplesPerFrame) {
    383         mSamplesPerFrame = samplesPerFrame;
    384     }
    385 
    386     /**
    387      * This should not be called after the open() call.
    388      */
    389     void setSharingMode(aaudio_sharing_mode_t sharingMode) {
    390         mSharingMode = sharingMode;
    391     }
    392 
    393     /**
    394      * This should not be called after the open() call.
    395      */
    396     void setFormat(aaudio_format_t format) {
    397         mFormat = format;
    398     }
    399 
    400     void setState(aaudio_stream_state_t state) {
    401         mState = state;
    402     }
    403 
    404     void setDeviceId(int32_t deviceId) {
    405         mDeviceId = deviceId;
    406     }
    407 
    408     std::mutex           mStreamMutex;
    409 
    410     std::atomic<bool>    mCallbackEnabled{false};
    411 
    412     float                mDuckAndMuteVolume = 1.0f;
    413 
    414 protected:
    415 
    416     void setPeriodNanoseconds(int64_t periodNanoseconds) {
    417         mPeriodNanoseconds.store(periodNanoseconds, std::memory_order_release);
    418     }
    419 
    420     int64_t getPeriodNanoseconds() {
    421         return mPeriodNanoseconds.load(std::memory_order_acquire);
    422     }
    423 
    424 private:
    425     const android::sp<MyPlayerBase>   mPlayerBase;
    426 
    427     // These do not change after open().
    428     int32_t                mSamplesPerFrame = AAUDIO_UNSPECIFIED;
    429     int32_t                mSampleRate = AAUDIO_UNSPECIFIED;
    430     int32_t                mDeviceId = AAUDIO_UNSPECIFIED;
    431     aaudio_sharing_mode_t  mSharingMode = AAUDIO_SHARING_MODE_SHARED;
    432     bool                   mSharingModeMatchRequired = false; // must match sharing mode requested
    433     aaudio_format_t        mFormat = AAUDIO_FORMAT_UNSPECIFIED;
    434     aaudio_stream_state_t  mState = AAUDIO_STREAM_STATE_UNINITIALIZED;
    435 
    436     aaudio_performance_mode_t mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
    437 
    438     // callback ----------------------------------
    439 
    440     AAudioStream_dataCallback   mDataCallbackProc = nullptr;  // external callback functions
    441     void                       *mDataCallbackUserData = nullptr;
    442     int32_t                     mFramesPerDataCallback = AAUDIO_UNSPECIFIED; // frames
    443 
    444     AAudioStream_errorCallback  mErrorCallbackProc = nullptr;
    445     void                       *mErrorCallbackUserData = nullptr;
    446 
    447     // background thread ----------------------------------
    448     bool                   mHasThread = false;
    449     pthread_t              mThread; // initialized in constructor
    450 
    451     // These are set by the application thread and then read by the audio pthread.
    452     std::atomic<int64_t>   mPeriodNanoseconds; // for tuning SCHED_FIFO threads
    453     // TODO make atomic?
    454     aaudio_audio_thread_proc_t mThreadProc = nullptr;
    455     void*                  mThreadArg = nullptr;
    456     aaudio_result_t        mThreadRegistrationResult = AAUDIO_OK;
    457 
    458 
    459 };
    460 
    461 } /* namespace aaudio */
    462 
    463 #endif /* AAUDIO_AUDIOSTREAM_H */
    464