• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
requestPause()60     virtual aaudio_result_t requestPause()
61     {
62         // Only implement this for OUTPUT streams.
63         return AAUDIO_ERROR_UNIMPLEMENTED;
64     }
65 
requestFlush()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      */
close()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 
registerThread()113     virtual aaudio_result_t registerThread() {
114         return AAUDIO_OK;
115     }
116 
unregisterThread()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 
getState()129     aaudio_stream_state_t getState() const {
130         return mState;
131     }
132 
getBufferSize()133     virtual int32_t getBufferSize() const {
134         return AAUDIO_ERROR_UNIMPLEMENTED;
135     }
136 
getBufferCapacity()137     virtual int32_t getBufferCapacity() const {
138         return AAUDIO_ERROR_UNIMPLEMENTED;
139     }
140 
getFramesPerBurst()141     virtual int32_t getFramesPerBurst() const {
142         return AAUDIO_ERROR_UNIMPLEMENTED;
143     }
144 
getXRunCount()145     virtual int32_t getXRunCount() const {
146         return AAUDIO_ERROR_UNIMPLEMENTED;
147     }
148 
isActive()149     bool isActive() const {
150         return mState == AAUDIO_STREAM_STATE_STARTING || mState == AAUDIO_STREAM_STATE_STARTED;
151     }
152 
isMMap()153     virtual bool isMMap() {
154         return false;
155     }
156 
getSampleRate()157     aaudio_result_t getSampleRate() const {
158         return mSampleRate;
159     }
160 
getFormat()161     aaudio_format_t getFormat()  const {
162         return mFormat;
163     }
164 
getSamplesPerFrame()165     aaudio_result_t getSamplesPerFrame() const {
166         return mSamplesPerFrame;
167     }
168 
getPerformanceMode()169     virtual int32_t getPerformanceMode() const {
170         return mPerformanceMode;
171     }
172 
setPerformanceMode(aaudio_performance_mode_t performanceMode)173     void setPerformanceMode(aaudio_performance_mode_t performanceMode) {
174         mPerformanceMode = performanceMode;
175     }
176 
getDeviceId()177     int32_t getDeviceId() const {
178         return mDeviceId;
179     }
180 
getSharingMode()181     aaudio_sharing_mode_t getSharingMode() const {
182         return mSharingMode;
183     }
184 
isSharingModeMatchRequired()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      */
getBytesPerFrame()194     int32_t getBytesPerFrame() const {
195         return mSamplesPerFrame * getBytesPerSample();
196     }
197 
198     /**
199      * This is only valid after setFormat() has been called.
200      */
getBytesPerSample()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 
getDataCallbackProc()209     AAudioStream_dataCallback getDataCallbackProc() const {
210         return mDataCallbackProc;
211     }
getErrorCallbackProc()212     AAudioStream_errorCallback getErrorCallbackProc() const {
213         return mErrorCallbackProc;
214     }
215 
getDataCallbackUserData()216     void *getDataCallbackUserData() const {
217         return mDataCallbackUserData;
218     }
getErrorCallbackUserData()219     void *getErrorCallbackUserData() const {
220         return mErrorCallbackUserData;
221     }
222 
getFramesPerDataCallback()223     int32_t getFramesPerDataCallback() const {
224         return mFramesPerDataCallback;
225     }
226 
isDataCallbackActive()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.
write(const void * buffer __unused,int32_t numFrames __unused,int64_t timeoutNanoseconds __unused)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 
read(void * buffer __unused,int32_t numFrames __unused,int64_t timeoutNanoseconds __unused)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.
setDuckAndMuteVolume(float duckAndMuteVolume)246     void setDuckAndMuteVolume(float duckAndMuteVolume) {
247         mDuckAndMuteVolume = duckAndMuteVolume;
248         doSetVolume(); // apply this change
249     }
250 
getDuckAndMuteVolume()251     float getDuckAndMuteVolume() {
252         return mDuckAndMuteVolume;
253     }
254 
255     // Implement this in the output subclasses.
doSetVolume()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      */
registerPlayerBase()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      */
unregisterPlayerBase()280     void unregisterPlayerBase() {
281         mPlayerBase->unregisterWithAudioManager();
282     }
283 
284     // Pass start request through PlayerBase for tracking.
systemStart()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 
systemPause()291     aaudio_result_t systemPause() {
292         mPlayerBase->pause();
293         return mPlayerBase->getResult();
294     }
295 
systemStop()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 
clearParentReference()330         void clearParentReference() { mParent = nullptr; }
331 
playerStart()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 
playerPause()338         android::status_t playerPause() override {
339             mResult = mParent->requestPause();
340             return AAudioConvert_aaudioToAndroidStatus(mResult);
341         }
342 
playerStop()343         android::status_t playerStop() override {
344             mResult = mParent->requestStop();
345             return AAudioConvert_aaudioToAndroidStatus(mResult);
346         }
347 
playerSetVolume()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
applyVolumeShaper(const::android::media::VolumeShaper::Configuration & configuration,const::android::media::VolumeShaper::Operation & operation)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 
getResult()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      */
setSampleRate(int32_t sampleRate)375     void setSampleRate(int32_t sampleRate) {
376         mSampleRate = sampleRate;
377     }
378 
379     /**
380      * This should not be called after the open() call.
381      */
setSamplesPerFrame(int32_t samplesPerFrame)382     void setSamplesPerFrame(int32_t samplesPerFrame) {
383         mSamplesPerFrame = samplesPerFrame;
384     }
385 
386     /**
387      * This should not be called after the open() call.
388      */
setSharingMode(aaudio_sharing_mode_t sharingMode)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      */
setFormat(aaudio_format_t format)396     void setFormat(aaudio_format_t format) {
397         mFormat = format;
398     }
399 
setState(aaudio_stream_state_t state)400     void setState(aaudio_stream_state_t state) {
401         mState = state;
402     }
403 
setDeviceId(int32_t deviceId)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 
setPeriodNanoseconds(int64_t periodNanoseconds)416     void setPeriodNanoseconds(int64_t periodNanoseconds) {
417         mPeriodNanoseconds.store(periodNanoseconds, std::memory_order_release);
418     }
419 
getPeriodNanoseconds()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