• 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 
24 #include <android-base/thread_annotations.h>
25 #include <binder/IServiceManager.h>
26 #include <binder/Status.h>
27 #include <utils/StrongPointer.h>
28 
29 #include <aaudio/AAudio.h>
30 #include <media/AudioSystem.h>
31 #include <media/PlayerBase.h>
32 #include <media/VolumeShaper.h>
33 
34 #include "utility/AAudioUtilities.h"
35 #include "utility/MonotonicCounter.h"
36 
37 // Cannot get android::media::VolumeShaper to compile!
38 #define AAUDIO_USE_VOLUME_SHAPER  0
39 
40 namespace aaudio {
41 
42 typedef void *(*aaudio_audio_thread_proc_t)(void *);
43 typedef uint32_t aaudio_stream_id_t;
44 
45 class AudioStreamBuilder;
46 
47 constexpr pid_t        CALLBACK_THREAD_NONE = 0;
48 
49 /**
50  * AAudio audio stream.
51  */
52 // By extending AudioDeviceCallback, we also inherit from RefBase.
53 class AudioStream : public android::AudioSystem::AudioDeviceCallback {
54 public:
55 
56     AudioStream();
57 
58     virtual ~AudioStream();
59 
60 protected:
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 
80     /* Asynchronous requests.
81      * Use waitForStateChange() to wait for completion.
82      */
83     virtual aaudio_result_t requestStart_l() REQUIRES(mStreamLock) = 0;
84 
requestPause_l()85     virtual aaudio_result_t requestPause_l() REQUIRES(mStreamLock) {
86         // Only implement this for OUTPUT streams.
87         return AAUDIO_ERROR_UNIMPLEMENTED;
88     }
89 
requestFlush_l()90     virtual aaudio_result_t requestFlush_l() REQUIRES(mStreamLock) {
91         // Only implement this for OUTPUT streams.
92         return AAUDIO_ERROR_UNIMPLEMENTED;
93     }
94 
95     virtual aaudio_result_t requestStop_l() REQUIRES(mStreamLock) = 0;
96 
97 public:
98     virtual aaudio_result_t getTimestamp(clockid_t clockId,
99                                        int64_t *framePosition,
100                                        int64_t *timeNanoseconds) = 0;
101 
102     /**
103      * Update state machine.
104      * @return result of the operation.
105      */
updateStateMachine()106     aaudio_result_t updateStateMachine() {
107         if (isDataCallbackActive()) {
108             return AAUDIO_OK; // state is getting updated by the callback thread read/write call
109         }
110         return processCommands();
111     };
112 
113     virtual aaudio_result_t processCommands() = 0;
114 
115     // =========== End ABSTRACT methods ===========================
116 
117     virtual aaudio_result_t waitForStateChange(aaudio_stream_state_t currentState,
118                                                aaudio_stream_state_t *nextState,
119                                                int64_t timeoutNanoseconds);
120 
121     /**
122      * Open the stream using the parameters in the builder.
123      * Allocate the necessary resources.
124      */
125     virtual aaudio_result_t open(const AudioStreamBuilder& builder);
126 
127     // log to MediaMetrics
128     virtual void logOpenActual();
129     void logReleaseBufferState();
130 
131     /* Note about naming for "release"  and "close" related methods.
132      *
133      * These names are intended to match the public AAudio API.
134      * The original AAudio API had an AAudioStream_close() function that
135      * released the hardware and deleted the stream. That made it difficult
136      * because apps want to release the HW ASAP but are not in a rush to delete
137      * the stream object. So in R we added an AAudioStream_release() function
138      * that just released the hardware.
139      * The AAudioStream_close() method releases if needed and then closes.
140      */
141 
142 protected:
143     /**
144      * Free any hardware or system resources from the open() call.
145      * It is safe to call release_l() multiple times.
146      */
release_l()147     virtual aaudio_result_t release_l() REQUIRES(mStreamLock) {
148         setState(AAUDIO_STREAM_STATE_CLOSING);
149         return AAUDIO_OK;
150     }
151 
152     /**
153      * Free any resources not already freed by release_l().
154      * Assume release_l() already called.
155      */
156     virtual void close_l() REQUIRES(mStreamLock);
157 
158 public:
159     // This is only used to identify a stream in the logs without
160     // revealing any pointers.
getId()161     aaudio_stream_id_t getId() {
162         return mStreamId;
163     }
164 
165     virtual aaudio_result_t setBufferSize(int32_t requestedFrames) = 0;
166 
createThread(int64_t periodNanoseconds,aaudio_audio_thread_proc_t threadProc,void * threadArg)167     aaudio_result_t createThread(int64_t periodNanoseconds,
168                                  aaudio_audio_thread_proc_t threadProc,
169                                  void *threadArg)
170                                  EXCLUDES(mStreamLock) {
171         std::lock_guard<std::mutex> lock(mStreamLock);
172         return createThread_l(periodNanoseconds, threadProc, threadArg);
173     }
174 
175     aaudio_result_t joinThread(void **returnArg);
176 
registerThread()177     virtual aaudio_result_t registerThread() {
178         return AAUDIO_OK;
179     }
180 
unregisterThread()181     virtual aaudio_result_t unregisterThread() {
182         return AAUDIO_OK;
183     }
184 
185     /**
186      * Internal function used to call the audio thread passed by the user.
187      * It is unfortunately public because it needs to be called by a static 'C' function.
188      */
189     void* wrapUserThread();
190 
191     // ============== Queries ===========================
192 
getState()193     aaudio_stream_state_t getState() const {
194         return mState.load();
195     }
196 
197     aaudio_stream_state_t getStateExternal() const;
198 
getBufferSize()199     virtual int32_t getBufferSize() const {
200         return AAUDIO_ERROR_UNIMPLEMENTED;
201     }
202 
getBufferCapacity()203     virtual int32_t getBufferCapacity() const {
204         return mBufferCapacity;
205     }
206 
getFramesPerBurst()207     virtual int32_t getFramesPerBurst() const {
208         return mFramesPerBurst;
209     }
210 
getXRunCount()211     virtual int32_t getXRunCount() const {
212         return AAUDIO_ERROR_UNIMPLEMENTED;
213     }
214 
isActive()215     bool isActive() const {
216         return mState == AAUDIO_STREAM_STATE_STARTING || mState == AAUDIO_STREAM_STATE_STARTED;
217     }
218 
isMMap()219     virtual bool isMMap() {
220         return false;
221     }
222 
getSampleRate()223     aaudio_result_t getSampleRate() const {
224         return mSampleRate;
225     }
226 
getHardwareSampleRate()227     aaudio_result_t getHardwareSampleRate() const {
228         return mHardwareSampleRate;
229     }
230 
getFormat()231     audio_format_t getFormat()  const {
232         return mFormat;
233     }
234 
getHardwareFormat()235     audio_format_t getHardwareFormat()  const {
236         return mHardwareFormat;
237     }
238 
getSamplesPerFrame()239     aaudio_result_t getSamplesPerFrame() const {
240         return mSamplesPerFrame;
241     }
242 
getHardwareSamplesPerFrame()243     aaudio_result_t getHardwareSamplesPerFrame() const {
244         return mHardwareSamplesPerFrame;
245     }
246 
getPerformanceMode()247     virtual int32_t getPerformanceMode() const {
248         return mPerformanceMode;
249     }
250 
setPerformanceMode(aaudio_performance_mode_t performanceMode)251     void setPerformanceMode(aaudio_performance_mode_t performanceMode) {
252         mPerformanceMode = performanceMode;
253     }
254 
getDeviceId()255     int32_t getDeviceId() const {
256         return mDeviceId;
257     }
258 
getSharingMode()259     aaudio_sharing_mode_t getSharingMode() const {
260         return mSharingMode;
261     }
262 
isSharingModeMatchRequired()263     bool isSharingModeMatchRequired() const {
264         return mSharingModeMatchRequired;
265     }
266 
267     virtual aaudio_direction_t getDirection() const = 0;
268 
getUsage()269     aaudio_usage_t getUsage() const {
270         return mUsage;
271     }
272 
getContentType()273     aaudio_content_type_t getContentType() const {
274         return mContentType;
275     }
276 
getSpatializationBehavior()277     aaudio_spatialization_behavior_t getSpatializationBehavior() const {
278         return mSpatializationBehavior;
279     }
280 
isContentSpatialized()281     bool isContentSpatialized() const {
282         return mIsContentSpatialized;
283     }
284 
getInputPreset()285     aaudio_input_preset_t getInputPreset() const {
286         return mInputPreset;
287     }
288 
getAllowedCapturePolicy()289     aaudio_allowed_capture_policy_t getAllowedCapturePolicy() const {
290         return mAllowedCapturePolicy;
291     }
292 
getSessionId()293     int32_t getSessionId() const {
294         return mSessionId;
295     }
296 
isPrivacySensitive()297     bool isPrivacySensitive() const {
298         return mIsPrivacySensitive;
299     }
300 
getRequireMonoBlend()301     bool getRequireMonoBlend() const {
302         return mRequireMonoBlend;
303     }
304 
getAudioBalance()305     float getAudioBalance() const {
306         return mAudioBalance;
307     }
308 
309     /**
310      * This is only valid after setChannelMask() and setFormat()
311      * have been called.
312      */
getBytesPerFrame()313     int32_t getBytesPerFrame() const {
314         return mSamplesPerFrame * getBytesPerSample();
315     }
316 
317     /**
318      * This is only valid after setFormat() has been called.
319      */
getBytesPerSample()320     int32_t getBytesPerSample() const {
321         return audio_bytes_per_sample(mFormat);
322     }
323 
324     /**
325      * This is only valid after setChannelMask() and setDeviceFormat() have been called.
326      */
getBytesPerDeviceFrame()327     int32_t getBytesPerDeviceFrame() const {
328         return getSamplesPerFrame() * audio_bytes_per_sample(getDeviceFormat());
329     }
330 
331     virtual int64_t getFramesWritten() = 0;
332 
333     virtual int64_t getFramesRead() = 0;
334 
getDataCallbackProc()335     AAudioStream_dataCallback getDataCallbackProc() const {
336         return mDataCallbackProc;
337     }
338 
getErrorCallbackProc()339     AAudioStream_errorCallback getErrorCallbackProc() const {
340         return mErrorCallbackProc;
341     }
342 
343     aaudio_data_callback_result_t maybeCallDataCallback(void *audioData, int32_t numFrames);
344 
345     void maybeCallErrorCallback(aaudio_result_t result);
346 
getDataCallbackUserData()347     void *getDataCallbackUserData() const {
348         return mDataCallbackUserData;
349     }
350 
getErrorCallbackUserData()351     void *getErrorCallbackUserData() const {
352         return mErrorCallbackUserData;
353     }
354 
getFramesPerDataCallback()355     int32_t getFramesPerDataCallback() const {
356         return mFramesPerDataCallback;
357     }
358 
getChannelMask()359     aaudio_channel_mask_t getChannelMask() const {
360         return mChannelMask;
361     }
362 
setChannelMask(aaudio_channel_mask_t channelMask)363     void setChannelMask(aaudio_channel_mask_t channelMask) {
364         mChannelMask = channelMask;
365         mSamplesPerFrame = AAudioConvert_channelMaskToCount(channelMask);
366     }
367 
368     /**
369      * @return true if data callback has been specified
370      */
isDataCallbackSet()371     bool isDataCallbackSet() const {
372         return mDataCallbackProc != nullptr;
373     }
374 
375     /**
376      * @return true if data callback has been specified and stream is running
377      */
isDataCallbackActive()378     bool isDataCallbackActive() const {
379         return isDataCallbackSet() && isActive();
380     }
381 
382     /**
383      * @return true if called from the same thread as the callback
384      */
385     bool collidesWithCallback() const;
386 
387     // Implement AudioDeviceCallback
onAudioDeviceUpdate(audio_io_handle_t audioIo,audio_port_handle_t deviceId)388     void onAudioDeviceUpdate(audio_io_handle_t audioIo,
389             audio_port_handle_t deviceId) override {};
390 
391     // ============== I/O ===========================
392     // 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)393     virtual aaudio_result_t write(const void *buffer __unused,
394                              int32_t numFrames __unused,
395                              int64_t timeoutNanoseconds __unused) {
396         return AAUDIO_ERROR_UNIMPLEMENTED;
397     }
398 
read(void * buffer __unused,int32_t numFrames __unused,int64_t timeoutNanoseconds __unused)399     virtual aaudio_result_t read(void *buffer __unused,
400                             int32_t numFrames __unused,
401                             int64_t timeoutNanoseconds __unused) {
402         return AAUDIO_ERROR_UNIMPLEMENTED;
403     }
404 
405     // This is used by the AudioManager to duck and mute the stream when changing audio focus.
406     void setDuckAndMuteVolume(float duckAndMuteVolume);
407 
getDuckAndMuteVolume()408     float getDuckAndMuteVolume() const {
409         return mDuckAndMuteVolume;
410     }
411 
412     // Implement this in the output subclasses.
doSetVolume()413     virtual android::status_t doSetVolume() { return android::NO_ERROR; }
414 
415 #if AAUDIO_USE_VOLUME_SHAPER
416     virtual ::android::binder::Status applyVolumeShaper(
417             const ::android::media::VolumeShaper::Configuration& configuration __unused,
418             const ::android::media::VolumeShaper::Operation& operation __unused);
419 #endif
420 
421     /**
422      * Register this stream's PlayerBase with the AudioManager if needed.
423      * Only register output streams.
424      * This should only be called for client streams and not for streams
425      * that run in the service.
426      */
registerPlayerBase()427     virtual void registerPlayerBase() {
428         if (getDirection() == AAUDIO_DIRECTION_OUTPUT) {
429             mPlayerBase->registerWithAudioManager(this);
430         }
431     }
432 
433     /**
434      * Unregister this stream's PlayerBase with the AudioManager.
435      * This will only unregister if already registered.
436      */
unregisterPlayerBase()437     void unregisterPlayerBase() {
438         mPlayerBase->unregisterWithAudioManager();
439     }
440 
441     aaudio_result_t systemStart();
442 
443     aaudio_result_t systemPause();
444 
445     aaudio_result_t safeFlush();
446 
447     /**
448      * This is called when an app calls AAudioStream_requestStop();
449      * It prevents calls from a callback.
450      */
451     aaudio_result_t systemStopFromApp();
452 
453     /**
454      * This is called internally when an app callback returns AAUDIO_CALLBACK_RESULT_STOP.
455      */
456     aaudio_result_t systemStopInternal();
457 
458     /**
459      * Safely RELEASE a stream after taking mStreamLock and checking
460      * to make sure we are not being called from a callback.
461      * @return AAUDIO_OK or a negative error
462      */
463     aaudio_result_t safeRelease();
464 
465     /**
466      * Safely RELEASE and CLOSE a stream after taking mStreamLock and checking
467      * to make sure we are not being called from a callback.
468      * @return AAUDIO_OK or a negative error
469      */
470     aaudio_result_t safeReleaseClose();
471 
472     aaudio_result_t safeReleaseCloseInternal();
473 
474 protected:
475 
476     // PlayerBase allows the system to control the stream volume.
477     class MyPlayerBase : public android::PlayerBase {
478     public:
479         MyPlayerBase() = default;
480 
481         virtual ~MyPlayerBase() = default;
482 
483         /**
484          * Register for volume changes and remote control.
485          */
486         void registerWithAudioManager(const android::sp<AudioStream>& parent);
487 
488         /**
489          * UnRegister.
490          */
491         void unregisterWithAudioManager();
492 
493         /**
494          * Just calls unregisterWithAudioManager().
495          */
496         void destroy() override;
497 
498         // Just a stub. The ability to start audio through PlayerBase is being deprecated.
playerStart()499         android::status_t playerStart() override {
500             return android::NO_ERROR;
501         }
502 
503         // Just a stub. The ability to pause audio through PlayerBase is being deprecated.
playerPause()504         android::status_t playerPause() override {
505             return android::NO_ERROR;
506         }
507 
508         // Just a stub. The ability to stop audio through PlayerBase is being deprecated.
playerStop()509         android::status_t playerStop() override {
510             return android::NO_ERROR;
511         }
512 
513         android::status_t playerSetVolume() override;
514 
515 #if AAUDIO_USE_VOLUME_SHAPER
516         ::android::binder::Status applyVolumeShaper();
517 #endif
518 
getResult()519         aaudio_result_t getResult() {
520             return mResult;
521         }
522 
523         // Returns the playerIId if registered, -1 otherwise.
getPlayerIId()524         int32_t getPlayerIId() const {
525             return mPIId;
526         }
527 
528     private:
529         // Use a weak pointer so the AudioStream can be deleted.
530         std::mutex               mParentLock;
531         android::wp<AudioStream> mParent GUARDED_BY(mParentLock);
532         aaudio_result_t          mResult = AAUDIO_OK;
533         bool                     mRegistered = false;
534     };
535 
536     /**
537      * This should not be called after the open() call.
538      * TODO for multiple setters: assert(mState == AAUDIO_STREAM_STATE_UNINITIALIZED)
539      */
setSampleRate(int32_t sampleRate)540     void setSampleRate(int32_t sampleRate) {
541         mSampleRate = sampleRate;
542     }
543 
544     // This should not be called after the open() call.
setHardwareSampleRate(int32_t hardwareSampleRate)545     void setHardwareSampleRate(int32_t hardwareSampleRate) {
546         mHardwareSampleRate = hardwareSampleRate;
547     }
548 
549     // This should not be called after the open() call.
setFramesPerBurst(int32_t framesPerBurst)550     void setFramesPerBurst(int32_t framesPerBurst) {
551         mFramesPerBurst = framesPerBurst;
552     }
553 
554     // This should not be called after the open() call.
setBufferCapacity(int32_t bufferCapacity)555     void setBufferCapacity(int32_t bufferCapacity) {
556         mBufferCapacity = bufferCapacity;
557     }
558 
559     // This should not be called after the open() call.
setSharingMode(aaudio_sharing_mode_t sharingMode)560     void setSharingMode(aaudio_sharing_mode_t sharingMode) {
561         mSharingMode = sharingMode;
562     }
563 
564     // This should not be called after the open() call.
setFormat(audio_format_t format)565     void setFormat(audio_format_t format) {
566         mFormat = format;
567     }
568 
569     // This should not be called after the open() call.
setHardwareFormat(audio_format_t format)570     void setHardwareFormat(audio_format_t format) {
571         mHardwareFormat = format;
572     }
573 
574     // This should not be called after the open() call.
setHardwareSamplesPerFrame(int32_t hardwareSamplesPerFrame)575     void setHardwareSamplesPerFrame(int32_t hardwareSamplesPerFrame) {
576         mHardwareSamplesPerFrame = hardwareSamplesPerFrame;
577     }
578 
579     // This should not be called after the open() call.
setDeviceFormat(audio_format_t format)580     void setDeviceFormat(audio_format_t format) {
581         mDeviceFormat = format;
582     }
583 
getDeviceFormat()584     audio_format_t getDeviceFormat() const {
585         return mDeviceFormat;
586     }
587 
588     void setState(aaudio_stream_state_t state);
589 
isDisconnected()590     bool isDisconnected() const {
591         return mDisconnected.load();
592     }
593     void setDisconnected();
594 
setDeviceId(int32_t deviceId)595     void setDeviceId(int32_t deviceId) {
596         mDeviceId = deviceId;
597     }
598 
599     // This should not be called after the open() call.
setSessionId(int32_t sessionId)600     void setSessionId(int32_t sessionId) {
601         mSessionId = sessionId;
602     }
603 
604     aaudio_result_t createThread_l(int64_t periodNanoseconds,
605                                            aaudio_audio_thread_proc_t threadProc,
606                                            void *threadArg)
607                                            REQUIRES(mStreamLock);
608 
609     aaudio_result_t joinThread_l(void **returnArg) REQUIRES(mStreamLock);
610 
611     std::atomic<bool>    mCallbackEnabled{false};
612 
613     float                mDuckAndMuteVolume = 1.0f;
614 
615 protected:
616 
617     /**
618      * Either convert the data from device format to app format and return a pointer
619      * to the conversion buffer,
620      * OR just pass back the original pointer.
621      *
622      * Note that this is only used for the INPUT path.
623      *
624      * @param audioData
625      * @param numFrames
626      * @return original pointer or the conversion buffer
627      */
maybeConvertDeviceData(const void * audioData,int32_t)628     virtual const void * maybeConvertDeviceData(const void *audioData, int32_t /*numFrames*/) {
629         return audioData;
630     }
631 
setPeriodNanoseconds(int64_t periodNanoseconds)632     void setPeriodNanoseconds(int64_t periodNanoseconds) {
633         mPeriodNanoseconds.store(periodNanoseconds, std::memory_order_release);
634     }
635 
getPeriodNanoseconds()636     int64_t getPeriodNanoseconds() {
637         return mPeriodNanoseconds.load(std::memory_order_acquire);
638     }
639 
640     /**
641      * This should not be called after the open() call.
642      */
setUsage(aaudio_usage_t usage)643     void setUsage(aaudio_usage_t usage) {
644         mUsage = usage;
645     }
646 
647     /**
648      * This should not be called after the open() call.
649      */
setContentType(aaudio_content_type_t contentType)650     void setContentType(aaudio_content_type_t contentType) {
651         mContentType = contentType;
652     }
653 
setSpatializationBehavior(aaudio_spatialization_behavior_t spatializationBehavior)654     void setSpatializationBehavior(aaudio_spatialization_behavior_t spatializationBehavior) {
655         mSpatializationBehavior = spatializationBehavior;
656     }
657 
setIsContentSpatialized(bool isContentSpatialized)658     void setIsContentSpatialized(bool isContentSpatialized) {
659         mIsContentSpatialized = isContentSpatialized;
660     }
661 
662     /**
663      * This should not be called after the open() call.
664      */
setInputPreset(aaudio_input_preset_t inputPreset)665     void setInputPreset(aaudio_input_preset_t inputPreset) {
666         mInputPreset = inputPreset;
667     }
668 
669     /**
670      * This should not be called after the open() call.
671      */
setAllowedCapturePolicy(aaudio_allowed_capture_policy_t policy)672     void setAllowedCapturePolicy(aaudio_allowed_capture_policy_t policy) {
673         mAllowedCapturePolicy = policy;
674     }
675 
676     /**
677      * This should not be called after the open() call.
678      */
setPrivacySensitive(bool privacySensitive)679     void setPrivacySensitive(bool privacySensitive) {
680         mIsPrivacySensitive = privacySensitive;
681     }
682 
683     /**
684      * This should not be called after the open() call.
685      */
setRequireMonoBlend(bool requireMonoBlend)686     void setRequireMonoBlend(bool requireMonoBlend) {
687         mRequireMonoBlend = requireMonoBlend;
688     }
689 
690     /**
691      * This should not be called after the open() call.
692      */
setAudioBalance(float audioBalance)693     void setAudioBalance(float audioBalance) {
694         mAudioBalance = audioBalance;
695     }
696 
697     std::string mMetricsId; // set once during open()
698 
699     std::mutex                 mStreamLock;
700 
701     const android::sp<MyPlayerBase>   mPlayerBase;
702 
703 private:
704 
705     aaudio_result_t safeStop_l() REQUIRES(mStreamLock);
706 
707     /**
708      * Release then close the stream.
709      */
releaseCloseFinal_l()710     void releaseCloseFinal_l() REQUIRES(mStreamLock) {
711         if (getState() != AAUDIO_STREAM_STATE_CLOSING) { // not already released?
712             // Ignore result and keep closing.
713             (void) release_l();
714         }
715         close_l();
716     }
717 
718     std::atomic<aaudio_stream_state_t>          mState{AAUDIO_STREAM_STATE_UNINITIALIZED};
719 
720     std::atomic_bool            mDisconnected{false};
721 
722     // These do not change after open().
723     int32_t                     mSamplesPerFrame = AAUDIO_UNSPECIFIED;
724     int32_t                     mHardwareSamplesPerFrame = AAUDIO_UNSPECIFIED;
725     aaudio_channel_mask_t       mChannelMask = AAUDIO_UNSPECIFIED;
726     int32_t                     mSampleRate = AAUDIO_UNSPECIFIED;
727     int32_t                     mHardwareSampleRate = AAUDIO_UNSPECIFIED;
728     int32_t                     mDeviceId = AAUDIO_UNSPECIFIED;
729     aaudio_sharing_mode_t       mSharingMode = AAUDIO_SHARING_MODE_SHARED;
730     bool                        mSharingModeMatchRequired = false; // must match sharing mode requested
731     audio_format_t              mFormat = AUDIO_FORMAT_DEFAULT;
732     audio_format_t              mHardwareFormat = AUDIO_FORMAT_DEFAULT;
733     aaudio_performance_mode_t   mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
734     int32_t                     mFramesPerBurst = 0;
735     int32_t                     mBufferCapacity = 0;
736 
737     aaudio_usage_t              mUsage           = AAUDIO_UNSPECIFIED;
738     aaudio_content_type_t       mContentType     = AAUDIO_UNSPECIFIED;
739     aaudio_spatialization_behavior_t mSpatializationBehavior = AAUDIO_UNSPECIFIED;
740     bool                        mIsContentSpatialized = false;
741     aaudio_input_preset_t       mInputPreset     = AAUDIO_UNSPECIFIED;
742     aaudio_allowed_capture_policy_t mAllowedCapturePolicy = AAUDIO_ALLOW_CAPTURE_BY_ALL;
743     bool                        mIsPrivacySensitive = false;
744     bool                        mRequireMonoBlend = false;
745     float                       mAudioBalance = 0;
746 
747     int32_t                     mSessionId = AAUDIO_UNSPECIFIED;
748 
749     // Sometimes the hardware is operating with a different format from the app.
750     // Then we require conversion in AAudio.
751     audio_format_t              mDeviceFormat = AUDIO_FORMAT_INVALID;
752 
753     // callback ----------------------------------
754 
755     AAudioStream_dataCallback   mDataCallbackProc = nullptr;  // external callback functions
756     void                       *mDataCallbackUserData = nullptr;
757     int32_t                     mFramesPerDataCallback = AAUDIO_UNSPECIFIED; // frames
758     std::atomic<pid_t>          mDataCallbackThread{CALLBACK_THREAD_NONE};
759 
760     AAudioStream_errorCallback  mErrorCallbackProc = nullptr;
761     void                       *mErrorCallbackUserData = nullptr;
762     std::atomic<pid_t>          mErrorCallbackThread{CALLBACK_THREAD_NONE};
763 
764     // background thread ----------------------------------
765     // Use mHasThread to prevent joining twice, which has undefined behavior.
766     bool                        mHasThread GUARDED_BY(mStreamLock) = false;
767     pthread_t                   mThread  GUARDED_BY(mStreamLock) = {};
768 
769     // These are set by the application thread and then read by the audio pthread.
770     std::atomic<int64_t>        mPeriodNanoseconds; // for tuning SCHED_FIFO threads
771     // TODO make atomic?
772     aaudio_audio_thread_proc_t  mThreadProc = nullptr;
773     void                       *mThreadArg = nullptr;
774     aaudio_result_t             mThreadRegistrationResult = AAUDIO_OK;
775 
776     const aaudio_stream_id_t    mStreamId;
777 
778 };
779 
780 } /* namespace aaudio */
781 
782 #endif /* AAUDIO_AUDIOSTREAM_H */
783