• 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 typedef uint32_t aaudio_stream_id_t;
40 
41 class AudioStreamBuilder;
42 
43 constexpr pid_t        CALLBACK_THREAD_NONE = 0;
44 
45 /**
46  * AAudio audio stream.
47  */
48 class AudioStream {
49 public:
50 
51     AudioStream();
52 
53     virtual ~AudioStream();
54 
55 protected:
56 
57     /* Asynchronous requests.
58      * Use waitForStateChange() to wait for completion.
59      */
60     virtual aaudio_result_t requestStart() = 0;
61 
62     /**
63      * Check the state to see if Pause is currently legal.
64      *
65      * @param result pointer to return code
66      * @return true if OK to continue, if false then return result
67      */
68     bool checkPauseStateTransition(aaudio_result_t *result);
69 
isFlushSupported()70     virtual bool isFlushSupported() const {
71         // Only implement FLUSH for OUTPUT streams.
72         return false;
73     }
74 
isPauseSupported()75     virtual bool isPauseSupported() const {
76         // Only implement PAUSE for OUTPUT streams.
77         return false;
78     }
79 
requestPause()80     virtual aaudio_result_t requestPause()
81     {
82         // Only implement this for OUTPUT streams.
83         return AAUDIO_ERROR_UNIMPLEMENTED;
84     }
85 
requestFlush()86     virtual aaudio_result_t requestFlush() {
87         // Only implement this for OUTPUT streams.
88         return AAUDIO_ERROR_UNIMPLEMENTED;
89     }
90 
91     virtual aaudio_result_t requestStop() = 0;
92 
93 public:
94     virtual aaudio_result_t getTimestamp(clockid_t clockId,
95                                        int64_t *framePosition,
96                                        int64_t *timeNanoseconds) = 0;
97 
98 
99     /**
100      * Update state machine.()
101      * @return
102      */
103     virtual aaudio_result_t updateStateMachine() = 0;
104 
105     // =========== End ABSTRACT methods ===========================
106 
107     virtual aaudio_result_t waitForStateChange(aaudio_stream_state_t currentState,
108                                                aaudio_stream_state_t *nextState,
109                                                int64_t timeoutNanoseconds);
110 
111     /**
112      * Open the stream using the parameters in the builder.
113      * Allocate the necessary resources.
114      */
115     virtual aaudio_result_t open(const AudioStreamBuilder& builder);
116 
117     /**
118      * Close the stream and deallocate any resources from the open() call.
119      * It is safe to call close() multiple times.
120      */
close()121     virtual aaudio_result_t close() {
122         return AAUDIO_OK;
123     }
124 
125     // This is only used to identify a stream in the logs without
126     // revealing any pointers.
getId()127     aaudio_stream_id_t getId() {
128         return mStreamId;
129     }
130 
131     virtual aaudio_result_t setBufferSize(int32_t requestedFrames) = 0;
132 
133     virtual aaudio_result_t createThread(int64_t periodNanoseconds,
134                                        aaudio_audio_thread_proc_t threadProc,
135                                        void *threadArg);
136 
137     aaudio_result_t joinThread(void **returnArg, int64_t timeoutNanoseconds);
138 
registerThread()139     virtual aaudio_result_t registerThread() {
140         return AAUDIO_OK;
141     }
142 
unregisterThread()143     virtual aaudio_result_t unregisterThread() {
144         return AAUDIO_OK;
145     }
146 
147     /**
148      * Internal function used to call the audio thread passed by the user.
149      * It is unfortunately public because it needs to be called by a static 'C' function.
150      */
151     void* wrapUserThread();
152 
153     // ============== Queries ===========================
154 
getState()155     aaudio_stream_state_t getState() const {
156         return mState;
157     }
158 
getBufferSize()159     virtual int32_t getBufferSize() const {
160         return AAUDIO_ERROR_UNIMPLEMENTED;
161     }
162 
getBufferCapacity()163     virtual int32_t getBufferCapacity() const {
164         return AAUDIO_ERROR_UNIMPLEMENTED;
165     }
166 
getFramesPerBurst()167     virtual int32_t getFramesPerBurst() const {
168         return AAUDIO_ERROR_UNIMPLEMENTED;
169     }
170 
getXRunCount()171     virtual int32_t getXRunCount() const {
172         return AAUDIO_ERROR_UNIMPLEMENTED;
173     }
174 
isActive()175     bool isActive() const {
176         return mState == AAUDIO_STREAM_STATE_STARTING || mState == AAUDIO_STREAM_STATE_STARTED;
177     }
178 
isMMap()179     virtual bool isMMap() {
180         return false;
181     }
182 
getSampleRate()183     aaudio_result_t getSampleRate() const {
184         return mSampleRate;
185     }
186 
getFormat()187     audio_format_t getFormat()  const {
188         return mFormat;
189     }
190 
getSamplesPerFrame()191     aaudio_result_t getSamplesPerFrame() const {
192         return mSamplesPerFrame;
193     }
194 
getPerformanceMode()195     virtual int32_t getPerformanceMode() const {
196         return mPerformanceMode;
197     }
198 
setPerformanceMode(aaudio_performance_mode_t performanceMode)199     void setPerformanceMode(aaudio_performance_mode_t performanceMode) {
200         mPerformanceMode = performanceMode;
201     }
202 
getDeviceId()203     int32_t getDeviceId() const {
204         return mDeviceId;
205     }
206 
getSharingMode()207     aaudio_sharing_mode_t getSharingMode() const {
208         return mSharingMode;
209     }
210 
isSharingModeMatchRequired()211     bool isSharingModeMatchRequired() const {
212         return mSharingModeMatchRequired;
213     }
214 
215     virtual aaudio_direction_t getDirection() const = 0;
216 
getUsage()217     aaudio_usage_t getUsage() const {
218         return mUsage;
219     }
220 
getContentType()221     aaudio_content_type_t getContentType() const {
222         return mContentType;
223     }
224 
getInputPreset()225     aaudio_input_preset_t getInputPreset() const {
226         return mInputPreset;
227     }
228 
getAllowedCapturePolicy()229     aaudio_allowed_capture_policy_t getAllowedCapturePolicy() const {
230         return mAllowedCapturePolicy;
231     }
232 
getSessionId()233     int32_t getSessionId() const {
234         return mSessionId;
235     }
236 
237     /**
238      * This is only valid after setSamplesPerFrame() and setFormat() have been called.
239      */
getBytesPerFrame()240     int32_t getBytesPerFrame() const {
241         return mSamplesPerFrame * getBytesPerSample();
242     }
243 
244     /**
245      * This is only valid after setFormat() has been called.
246      */
getBytesPerSample()247     int32_t getBytesPerSample() const {
248         return audio_bytes_per_sample(mFormat);
249     }
250 
251     /**
252      * This is only valid after setSamplesPerFrame() and setDeviceFormat() have been called.
253      */
getBytesPerDeviceFrame()254     int32_t getBytesPerDeviceFrame() const {
255         return getSamplesPerFrame() * audio_bytes_per_sample(getDeviceFormat());
256     }
257 
258     virtual int64_t getFramesWritten() = 0;
259 
260     virtual int64_t getFramesRead() = 0;
261 
getDataCallbackProc()262     AAudioStream_dataCallback getDataCallbackProc() const {
263         return mDataCallbackProc;
264     }
265 
getErrorCallbackProc()266     AAudioStream_errorCallback getErrorCallbackProc() const {
267         return mErrorCallbackProc;
268     }
269 
270     aaudio_data_callback_result_t maybeCallDataCallback(void *audioData, int32_t numFrames);
271 
272     void maybeCallErrorCallback(aaudio_result_t result);
273 
getDataCallbackUserData()274     void *getDataCallbackUserData() const {
275         return mDataCallbackUserData;
276     }
277 
getErrorCallbackUserData()278     void *getErrorCallbackUserData() const {
279         return mErrorCallbackUserData;
280     }
281 
getFramesPerDataCallback()282     int32_t getFramesPerDataCallback() const {
283         return mFramesPerDataCallback;
284     }
285 
286     /**
287      * @return true if data callback has been specified
288      */
isDataCallbackSet()289     bool isDataCallbackSet() const {
290         return mDataCallbackProc != nullptr;
291     }
292 
293     /**
294      * @return true if data callback has been specified and stream is running
295      */
isDataCallbackActive()296     bool isDataCallbackActive() const {
297         return isDataCallbackSet() && isActive();
298     }
299 
300     /**
301      * @return true if called from the same thread as the callback
302      */
303     bool collidesWithCallback() const;
304 
305     // ============== I/O ===========================
306     // 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)307     virtual aaudio_result_t write(const void *buffer __unused,
308                              int32_t numFrames __unused,
309                              int64_t timeoutNanoseconds __unused) {
310         return AAUDIO_ERROR_UNIMPLEMENTED;
311     }
312 
read(void * buffer __unused,int32_t numFrames __unused,int64_t timeoutNanoseconds __unused)313     virtual aaudio_result_t read(void *buffer __unused,
314                             int32_t numFrames __unused,
315                             int64_t timeoutNanoseconds __unused) {
316         return AAUDIO_ERROR_UNIMPLEMENTED;
317     }
318 
319     // This is used by the AudioManager to duck and mute the stream when changing audio focus.
320     void setDuckAndMuteVolume(float duckAndMuteVolume);
321 
getDuckAndMuteVolume()322     float getDuckAndMuteVolume() const {
323         return mDuckAndMuteVolume;
324     }
325 
326     // Implement this in the output subclasses.
doSetVolume()327     virtual android::status_t doSetVolume() { return android::NO_ERROR; }
328 
329 #if AAUDIO_USE_VOLUME_SHAPER
330     virtual ::android::binder::Status applyVolumeShaper(
331             const ::android::media::VolumeShaper::Configuration& configuration __unused,
332             const ::android::media::VolumeShaper::Operation& operation __unused);
333 #endif
334 
335     /**
336      * Register this stream's PlayerBase with the AudioManager if needed.
337      * Only register output streams.
338      * This should only be called for client streams and not for streams
339      * that run in the service.
340      */
registerPlayerBase()341     void registerPlayerBase() {
342         if (getDirection() == AAUDIO_DIRECTION_OUTPUT) {
343             mPlayerBase->registerWithAudioManager();
344         }
345     }
346 
347     /**
348      * Unregister this stream's PlayerBase with the AudioManager.
349      * This will only unregister if already registered.
350      */
unregisterPlayerBase()351     void unregisterPlayerBase() {
352         mPlayerBase->unregisterWithAudioManager();
353     }
354 
355     aaudio_result_t systemStart();
356 
357     aaudio_result_t systemPause();
358 
359     aaudio_result_t safeFlush();
360 
361     /**
362      * This is called when an app calls AAudioStream_requestStop();
363      * It prevents calls from a callback.
364      */
365     aaudio_result_t systemStopFromApp();
366 
367     /**
368      * This is called internally when an app callback returns AAUDIO_CALLBACK_RESULT_STOP.
369      */
370     aaudio_result_t systemStopFromCallback();
371 
372     aaudio_result_t safeClose();
373 
374 protected:
375 
376     // PlayerBase allows the system to control the stream volume.
377     class MyPlayerBase : public android::PlayerBase {
378     public:
379         explicit MyPlayerBase(AudioStream *parent);
380 
381         virtual ~MyPlayerBase();
382 
383         /**
384          * Register for volume changes and remote control.
385          */
386         void registerWithAudioManager();
387 
388         /**
389          * UnRegister.
390          */
391         void unregisterWithAudioManager();
392 
393         /**
394          * Just calls unregisterWithAudioManager().
395          */
396         void destroy() override;
397 
clearParentReference()398         void clearParentReference() { mParent = nullptr; }
399 
400         // Just a stub. The ability to start audio through PlayerBase is being deprecated.
playerStart()401         android::status_t playerStart() override {
402             return android::NO_ERROR;
403         }
404 
405         // Just a stub. The ability to pause audio through PlayerBase is being deprecated.
playerPause()406         android::status_t playerPause() override {
407             return android::NO_ERROR;
408         }
409 
410         // Just a stub. The ability to stop audio through PlayerBase is being deprecated.
playerStop()411         android::status_t playerStop() override {
412             return android::NO_ERROR;
413         }
414 
playerSetVolume()415         android::status_t playerSetVolume() override {
416             // No pan and only left volume is taken into account from IPLayer interface
417             mParent->setDuckAndMuteVolume(mVolumeMultiplierL  /* * mPanMultiplierL */);
418             return android::NO_ERROR;
419         }
420 
421 #if AAUDIO_USE_VOLUME_SHAPER
applyVolumeShaper(const::android::media::VolumeShaper::Configuration & configuration,const::android::media::VolumeShaper::Operation & operation)422         ::android::binder::Status applyVolumeShaper(
423                 const ::android::media::VolumeShaper::Configuration& configuration,
424                 const ::android::media::VolumeShaper::Operation& operation) {
425             return mParent->applyVolumeShaper(configuration, operation);
426         }
427 #endif
428 
getResult()429         aaudio_result_t getResult() {
430             return mResult;
431         }
432 
433     private:
434         AudioStream          *mParent;
435         aaudio_result_t       mResult = AAUDIO_OK;
436         bool                  mRegistered = false;
437     };
438 
439     /**
440      * This should not be called after the open() call.
441      * TODO for multiple setters: assert(mState == AAUDIO_STREAM_STATE_UNINITIALIZED)
442      */
setSampleRate(int32_t sampleRate)443     void setSampleRate(int32_t sampleRate) {
444         mSampleRate = sampleRate;
445     }
446 
447     /**
448      * This should not be called after the open() call.
449      */
setSamplesPerFrame(int32_t samplesPerFrame)450     void setSamplesPerFrame(int32_t samplesPerFrame) {
451         mSamplesPerFrame = samplesPerFrame;
452     }
453 
454     /**
455      * This should not be called after the open() call.
456      */
setSharingMode(aaudio_sharing_mode_t sharingMode)457     void setSharingMode(aaudio_sharing_mode_t sharingMode) {
458         mSharingMode = sharingMode;
459     }
460 
461     /**
462      * This should not be called after the open() call.
463      */
setFormat(audio_format_t format)464     void setFormat(audio_format_t format) {
465         mFormat = format;
466     }
467 
468     /**
469      * This should not be called after the open() call.
470      */
setDeviceFormat(audio_format_t format)471     void setDeviceFormat(audio_format_t format) {
472         mDeviceFormat = format;
473     }
474 
getDeviceFormat()475     audio_format_t getDeviceFormat() const {
476         return mDeviceFormat;
477     }
478 
479     void setState(aaudio_stream_state_t state);
480 
setDeviceId(int32_t deviceId)481     void setDeviceId(int32_t deviceId) {
482         mDeviceId = deviceId;
483     }
484 
setSessionId(int32_t sessionId)485     void setSessionId(int32_t sessionId) {
486         mSessionId = sessionId;
487     }
488 
489     std::atomic<bool>    mCallbackEnabled{false};
490 
491     float                mDuckAndMuteVolume = 1.0f;
492 
493 protected:
494 
495     /**
496      * Either convert the data from device format to app format and return a pointer
497      * to the conversion buffer,
498      * OR just pass back the original pointer.
499      *
500      * Note that this is only used for the INPUT path.
501      *
502      * @param audioData
503      * @param numFrames
504      * @return original pointer or the conversion buffer
505      */
maybeConvertDeviceData(const void * audioData,int32_t numFrames)506     virtual const void * maybeConvertDeviceData(const void *audioData, int32_t numFrames) {
507         return audioData;
508     }
509 
setPeriodNanoseconds(int64_t periodNanoseconds)510     void setPeriodNanoseconds(int64_t periodNanoseconds) {
511         mPeriodNanoseconds.store(periodNanoseconds, std::memory_order_release);
512     }
513 
getPeriodNanoseconds()514     int64_t getPeriodNanoseconds() {
515         return mPeriodNanoseconds.load(std::memory_order_acquire);
516     }
517 
518     /**
519      * This should not be called after the open() call.
520      */
setUsage(aaudio_usage_t usage)521     void setUsage(aaudio_usage_t usage) {
522         mUsage = usage;
523     }
524 
525     /**
526      * This should not be called after the open() call.
527      */
setContentType(aaudio_content_type_t contentType)528     void setContentType(aaudio_content_type_t contentType) {
529         mContentType = contentType;
530     }
531 
532     /**
533      * This should not be called after the open() call.
534      */
setInputPreset(aaudio_input_preset_t inputPreset)535     void setInputPreset(aaudio_input_preset_t inputPreset) {
536         mInputPreset = inputPreset;
537     }
538 
539     /**
540      * This should not be called after the open() call.
541      */
setAllowedCapturePolicy(aaudio_allowed_capture_policy_t policy)542     void setAllowedCapturePolicy(aaudio_allowed_capture_policy_t policy) {
543         mAllowedCapturePolicy = policy;
544     }
545 
546 private:
547 
548     aaudio_result_t safeStop();
549 
550     std::mutex                 mStreamLock;
551 
552     const android::sp<MyPlayerBase>   mPlayerBase;
553 
554     // These do not change after open().
555     int32_t                     mSamplesPerFrame = AAUDIO_UNSPECIFIED;
556     int32_t                     mSampleRate = AAUDIO_UNSPECIFIED;
557     int32_t                     mDeviceId = AAUDIO_UNSPECIFIED;
558     aaudio_sharing_mode_t       mSharingMode = AAUDIO_SHARING_MODE_SHARED;
559     bool                        mSharingModeMatchRequired = false; // must match sharing mode requested
560     audio_format_t              mFormat = AUDIO_FORMAT_DEFAULT;
561     aaudio_stream_state_t       mState = AAUDIO_STREAM_STATE_UNINITIALIZED;
562     aaudio_performance_mode_t   mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
563 
564     aaudio_usage_t              mUsage           = AAUDIO_UNSPECIFIED;
565     aaudio_content_type_t       mContentType     = AAUDIO_UNSPECIFIED;
566     aaudio_input_preset_t       mInputPreset     = AAUDIO_UNSPECIFIED;
567     aaudio_allowed_capture_policy_t mAllowedCapturePolicy = AAUDIO_ALLOW_CAPTURE_BY_ALL;
568 
569     int32_t                     mSessionId = AAUDIO_UNSPECIFIED;
570 
571     // Sometimes the hardware is operating with a different format from the app.
572     // Then we require conversion in AAudio.
573     audio_format_t              mDeviceFormat = AUDIO_FORMAT_INVALID;
574 
575     // callback ----------------------------------
576 
577     AAudioStream_dataCallback   mDataCallbackProc = nullptr;  // external callback functions
578     void                       *mDataCallbackUserData = nullptr;
579     int32_t                     mFramesPerDataCallback = AAUDIO_UNSPECIFIED; // frames
580     std::atomic<pid_t>          mDataCallbackThread{CALLBACK_THREAD_NONE};
581 
582     AAudioStream_errorCallback  mErrorCallbackProc = nullptr;
583     void                       *mErrorCallbackUserData = nullptr;
584     std::atomic<pid_t>          mErrorCallbackThread{CALLBACK_THREAD_NONE};
585 
586     // background thread ----------------------------------
587     bool                        mHasThread = false;
588     pthread_t                   mThread; // initialized in constructor
589 
590     // These are set by the application thread and then read by the audio pthread.
591     std::atomic<int64_t>        mPeriodNanoseconds; // for tuning SCHED_FIFO threads
592     // TODO make atomic?
593     aaudio_audio_thread_proc_t  mThreadProc = nullptr;
594     void                       *mThreadArg = nullptr;
595     aaudio_result_t             mThreadRegistrationResult = AAUDIO_OK;
596 
597     const aaudio_stream_id_t    mStreamId;
598 
599 };
600 
601 } /* namespace aaudio */
602 
603 #endif /* AAUDIO_AUDIOSTREAM_H */
604