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 
     25 #include "utility/AAudioUtilities.h"
     26 #include "utility/MonotonicCounter.h"
     27 
     28 namespace aaudio {
     29 
     30 typedef void *(*aaudio_audio_thread_proc_t)(void *);
     31 
     32 class AudioStreamBuilder;
     33 
     34 /**
     35  * AAudio audio stream.
     36  */
     37 class AudioStream {
     38 public:
     39 
     40     AudioStream();
     41 
     42     virtual ~AudioStream();
     43 
     44 
     45     // =========== Begin ABSTRACT methods ===========================
     46 
     47     /* Asynchronous requests.
     48      * Use waitForStateChange() to wait for completion.
     49      */
     50     virtual aaudio_result_t requestStart() = 0;
     51     virtual aaudio_result_t requestPause() = 0;
     52     virtual aaudio_result_t requestFlush() = 0;
     53     virtual aaudio_result_t requestStop() = 0;
     54 
     55     virtual aaudio_result_t getTimestamp(clockid_t clockId,
     56                                        int64_t *framePosition,
     57                                        int64_t *timeNanoseconds) = 0;
     58 
     59 
     60     /**
     61      * Update state while in the middle of waitForStateChange()
     62      * @return
     63      */
     64     virtual aaudio_result_t updateStateWhileWaiting() = 0;
     65 
     66 
     67     // =========== End ABSTRACT methods ===========================
     68 
     69     virtual aaudio_result_t waitForStateChange(aaudio_stream_state_t currentState,
     70                                                aaudio_stream_state_t *nextState,
     71                                                int64_t timeoutNanoseconds);
     72 
     73     /**
     74      * Open the stream using the parameters in the builder.
     75      * Allocate the necessary resources.
     76      */
     77     virtual aaudio_result_t open(const AudioStreamBuilder& builder);
     78 
     79     /**
     80      * Close the stream and deallocate any resources from the open() call.
     81      * It is safe to call close() multiple times.
     82      */
     83     virtual aaudio_result_t close() {
     84         return AAUDIO_OK;
     85     }
     86 
     87     virtual aaudio_result_t setBufferSize(int32_t requestedFrames) {
     88         return AAUDIO_ERROR_UNIMPLEMENTED;
     89     }
     90 
     91     virtual aaudio_result_t createThread(int64_t periodNanoseconds,
     92                                        aaudio_audio_thread_proc_t threadProc,
     93                                        void *threadArg);
     94 
     95     aaudio_result_t joinThread(void **returnArg, int64_t timeoutNanoseconds);
     96 
     97     virtual aaudio_result_t registerThread() {
     98         return AAUDIO_OK;
     99     }
    100 
    101     virtual aaudio_result_t unregisterThread() {
    102         return AAUDIO_OK;
    103     }
    104 
    105     /**
    106      * Internal function used to call the audio thread passed by the user.
    107      * It is unfortunately public because it needs to be called by a static 'C' function.
    108      */
    109     void* wrapUserThread();
    110 
    111     // ============== Queries ===========================
    112 
    113     aaudio_stream_state_t getState() const {
    114         return mState;
    115     }
    116 
    117     virtual int32_t getBufferSize() const {
    118         return AAUDIO_ERROR_UNIMPLEMENTED;
    119     }
    120 
    121     virtual int32_t getBufferCapacity() const {
    122         return AAUDIO_ERROR_UNIMPLEMENTED;
    123     }
    124 
    125     virtual int32_t getFramesPerBurst() const {
    126         return AAUDIO_ERROR_UNIMPLEMENTED;
    127     }
    128 
    129     virtual int32_t getXRunCount() const {
    130         return AAUDIO_ERROR_UNIMPLEMENTED;
    131     }
    132 
    133     bool isActive() const {
    134         return mState == AAUDIO_STREAM_STATE_STARTING || mState == AAUDIO_STREAM_STATE_STARTED;
    135     }
    136 
    137     virtual bool isMMap() {
    138         return false;
    139     }
    140 
    141     aaudio_result_t getSampleRate() const {
    142         return mSampleRate;
    143     }
    144 
    145     aaudio_format_t getFormat()  const {
    146         return mFormat;
    147     }
    148 
    149     aaudio_result_t getSamplesPerFrame() const {
    150         return mSamplesPerFrame;
    151     }
    152 
    153     virtual int32_t getPerformanceMode() const {
    154         return mPerformanceMode;
    155     }
    156 
    157     void setPerformanceMode(aaudio_performance_mode_t performanceMode) {
    158         mPerformanceMode = performanceMode;
    159     }
    160 
    161     int32_t getDeviceId() const {
    162         return mDeviceId;
    163     }
    164 
    165     aaudio_sharing_mode_t getSharingMode() const {
    166         return mSharingMode;
    167     }
    168 
    169     bool isSharingModeMatchRequired() const {
    170         return mSharingModeMatchRequired;
    171     }
    172 
    173     virtual aaudio_direction_t getDirection() const = 0;
    174 
    175     /**
    176      * This is only valid after setSamplesPerFrame() and setFormat() have been called.
    177      */
    178     int32_t getBytesPerFrame() const {
    179         return mSamplesPerFrame * getBytesPerSample();
    180     }
    181 
    182     /**
    183      * This is only valid after setFormat() has been called.
    184      */
    185     int32_t getBytesPerSample() const {
    186         return AAudioConvert_formatToSizeInBytes(mFormat);
    187     }
    188 
    189     virtual int64_t getFramesWritten() {
    190         return mFramesWritten.get();
    191     }
    192 
    193     virtual int64_t getFramesRead() {
    194         return mFramesRead.get();
    195     }
    196 
    197     AAudioStream_dataCallback getDataCallbackProc() const {
    198         return mDataCallbackProc;
    199     }
    200     AAudioStream_errorCallback getErrorCallbackProc() const {
    201         return mErrorCallbackProc;
    202     }
    203 
    204     void *getDataCallbackUserData() const {
    205         return mDataCallbackUserData;
    206     }
    207     void *getErrorCallbackUserData() const {
    208         return mErrorCallbackUserData;
    209     }
    210 
    211     int32_t getFramesPerDataCallback() const {
    212         return mFramesPerDataCallback;
    213     }
    214 
    215     bool isDataCallbackActive() {
    216         return (mDataCallbackProc != nullptr) && isActive();
    217     }
    218 
    219     // ============== I/O ===========================
    220     // A Stream will only implement read() or write() depending on its direction.
    221     virtual aaudio_result_t write(const void *buffer,
    222                              int32_t numFrames,
    223                              int64_t timeoutNanoseconds) {
    224         return AAUDIO_ERROR_UNIMPLEMENTED;
    225     }
    226 
    227     virtual aaudio_result_t read(void *buffer,
    228                             int32_t numFrames,
    229                             int64_t timeoutNanoseconds) {
    230         return AAUDIO_ERROR_UNIMPLEMENTED;
    231     }
    232 
    233 protected:
    234 
    235     virtual int64_t incrementFramesWritten(int32_t frames) {
    236         return mFramesWritten.increment(frames);
    237     }
    238 
    239     virtual int64_t incrementFramesRead(int32_t frames) {
    240         return mFramesRead.increment(frames);
    241     }
    242 
    243     /**
    244      * This should not be called after the open() call.
    245      */
    246     void setSampleRate(int32_t sampleRate) {
    247         mSampleRate = sampleRate;
    248     }
    249 
    250     /**
    251      * This should not be called after the open() call.
    252      */
    253     void setSamplesPerFrame(int32_t samplesPerFrame) {
    254         mSamplesPerFrame = samplesPerFrame;
    255     }
    256 
    257     /**
    258      * This should not be called after the open() call.
    259      */
    260     void setSharingMode(aaudio_sharing_mode_t sharingMode) {
    261         mSharingMode = sharingMode;
    262     }
    263 
    264     /**
    265      * This should not be called after the open() call.
    266      */
    267     void setFormat(aaudio_format_t format) {
    268         mFormat = format;
    269     }
    270 
    271     void setState(aaudio_stream_state_t state) {
    272         mState = state;
    273     }
    274 
    275     void setDeviceId(int32_t deviceId) {
    276         mDeviceId = deviceId;
    277     }
    278 
    279     std::mutex           mStreamMutex;
    280 
    281     std::atomic<bool>    mCallbackEnabled;
    282 
    283 protected:
    284     MonotonicCounter     mFramesWritten;
    285     MonotonicCounter     mFramesRead;
    286 
    287     void setPeriodNanoseconds(int64_t periodNanoseconds) {
    288         mPeriodNanoseconds.store(periodNanoseconds, std::memory_order_release);
    289     }
    290 
    291     int64_t getPeriodNanoseconds() {
    292         return mPeriodNanoseconds.load(std::memory_order_acquire);
    293     }
    294 
    295 private:
    296     // These do not change after open().
    297     int32_t                mSamplesPerFrame = AAUDIO_UNSPECIFIED;
    298     int32_t                mSampleRate = AAUDIO_UNSPECIFIED;
    299     int32_t                mDeviceId = AAUDIO_UNSPECIFIED;
    300     aaudio_sharing_mode_t  mSharingMode = AAUDIO_SHARING_MODE_SHARED;
    301     bool                   mSharingModeMatchRequired = false; // must match sharing mode requested
    302     aaudio_format_t        mFormat = AAUDIO_FORMAT_UNSPECIFIED;
    303     aaudio_stream_state_t  mState = AAUDIO_STREAM_STATE_UNINITIALIZED;
    304 
    305     aaudio_performance_mode_t mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
    306 
    307     // callback ----------------------------------
    308 
    309     AAudioStream_dataCallback   mDataCallbackProc = nullptr;  // external callback functions
    310     void                       *mDataCallbackUserData = nullptr;
    311     int32_t                     mFramesPerDataCallback = AAUDIO_UNSPECIFIED; // frames
    312 
    313     AAudioStream_errorCallback  mErrorCallbackProc = nullptr;
    314     void                       *mErrorCallbackUserData = nullptr;
    315 
    316     // background thread ----------------------------------
    317     bool                   mHasThread = false;
    318     pthread_t              mThread; // initialized in constructor
    319 
    320     // These are set by the application thread and then read by the audio pthread.
    321     std::atomic<int64_t>   mPeriodNanoseconds; // for tuning SCHED_FIFO threads
    322     // TODO make atomic?
    323     aaudio_audio_thread_proc_t mThreadProc = nullptr;
    324     void*                  mThreadArg = nullptr;
    325     aaudio_result_t        mThreadRegistrationResult = AAUDIO_OK;
    326 
    327 
    328 };
    329 
    330 } /* namespace aaudio */
    331 
    332 #endif /* AAUDIO_AUDIOSTREAM_H */
    333