AudioStream.h revision c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fb
1e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk/*
2e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * Copyright 2016 The Android Open Source Project
3e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk *
4e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * Licensed under the Apache License, Version 2.0 (the "License");
5e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * you may not use this file except in compliance with the License.
6e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * You may obtain a copy of the License at
7e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk *
8e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk *      http://www.apache.org/licenses/LICENSE-2.0
9e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk *
10e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * Unless required by applicable law or agreed to in writing, software
11e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * distributed under the License is distributed on an "AS IS" BASIS,
12e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * See the License for the specific language governing permissions and
14e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk * limitations under the License.
15e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk */
16e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
175ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#ifndef AAUDIO_AUDIOSTREAM_H
185ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#define AAUDIO_AUDIOSTREAM_H
19e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
20d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk#include <atomic>
21e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk#include <mutex>
22d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk#include <stdint.h>
235ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#include <aaudio/AAudio.h>
24d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk
25c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "utility/AAudioUtilities.h"
26c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "utility/MonotonicCounter.h"
27e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
285ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burknamespace aaudio {
29e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
30e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burkclass AudioStreamBuilder;
31e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
32e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk/**
335ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk * AAudio audio stream.
34e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk */
35e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burkclass AudioStream {
36e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burkpublic:
37e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
38e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    AudioStream();
39e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
40e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    virtual ~AudioStream();
41e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
42e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
43e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    // =========== Begin ABSTRACT methods ===========================
44e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
45e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    /* Asynchronous requests.
46e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     * Use waitForStateChange() to wait for completion.
47e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     */
485ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t requestStart() = 0;
495ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t requestPause() = 0;
505ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t requestFlush() = 0;
515ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t requestStop() = 0;
52e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
535ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t getTimestamp(clockid_t clockId,
543316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk                                       int64_t *framePosition,
553316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk                                       int64_t *timeNanoseconds) = 0;
56e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
57e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
58e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    /**
59e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk     * Update state while in the middle of waitForStateChange()
60e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk     * @return
61e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk     */
62e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    virtual aaudio_result_t updateStateWhileWaiting() = 0;
63e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
64e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
65e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    // =========== End ABSTRACT methods ===========================
66e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
675ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t waitForStateChange(aaudio_stream_state_t currentState,
68e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk                                               aaudio_stream_state_t *nextState,
69e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk                                               int64_t timeoutNanoseconds);
70e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
71e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    /**
72e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     * Open the stream using the parameters in the builder.
73e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     * Allocate the necessary resources.
74e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     */
755ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t open(const AudioStreamBuilder& builder);
76e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
77e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    /**
78e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     * Close the stream and deallocate any resources from the open() call.
79e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     * It is safe to call close() multiple times.
80e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     */
815ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t close() {
825ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        return AAUDIO_OK;
83e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
84e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
853316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    virtual aaudio_result_t setBufferSize(int32_t requestedFrames) {
865ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        return AAUDIO_ERROR_UNIMPLEMENTED;
87e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
88e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
893316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    virtual aaudio_result_t createThread(int64_t periodNanoseconds,
90e2155ef0ec6742db7a3128c4ef4fb96e02828d1bPhil Burk                                       aaudio_audio_thread_proc_t threadProc,
91d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk                                       void *threadArg);
92e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
933316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    virtual aaudio_result_t joinThread(void **returnArg, int64_t timeoutNanoseconds);
94e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
955ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t registerThread() {
965ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        return AAUDIO_OK;
97d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk    }
98d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk
995ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t unregisterThread() {
1005ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        return AAUDIO_OK;
101d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk    }
102d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk
103d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk    /**
104d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk     * Internal function used to call the audio thread passed by the user.
105d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk     * It is unfortunately public because it needs to be called by a static 'C' function.
106d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk     */
107d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk    void* wrapUserThread();
108d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk
109e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    // ============== Queries ===========================
110e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
1113316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    aaudio_stream_state_t getState() const {
112e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk        return mState;
113e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
114e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
1153316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    virtual int32_t getBufferSize() const {
1165ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        return AAUDIO_ERROR_UNIMPLEMENTED;
117e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
118e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
1193316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    virtual int32_t getBufferCapacity() const {
1205ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        return AAUDIO_ERROR_UNIMPLEMENTED;
121e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
122e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
1233316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    virtual int32_t getFramesPerBurst() const {
1245ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        return AAUDIO_ERROR_UNIMPLEMENTED;
125e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
126e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
127e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    virtual int32_t getXRunCount() const {
1285ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        return AAUDIO_ERROR_UNIMPLEMENTED;
129e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
130e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
131e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    bool isPlaying() const {
1325ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        return mState == AAUDIO_STREAM_STATE_STARTING || mState == AAUDIO_STREAM_STATE_STARTED;
133e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
134e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
1355ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    aaudio_result_t getSampleRate() const {
136e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk        return mSampleRate;
137e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
138e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
1395ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    aaudio_audio_format_t getFormat()  const {
140e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk        return mFormat;
141e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
142e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
1435ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    aaudio_result_t getSamplesPerFrame() const {
144e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk        return mSamplesPerFrame;
145e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
146e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
1473316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    int32_t getDeviceId() const {
148e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk        return mDeviceId;
149e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
150e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
1515ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    aaudio_sharing_mode_t getSharingMode() const {
152e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk        return mSharingMode;
153e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
154e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
1555ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    aaudio_direction_t getDirection() const {
156e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk        return mDirection;
157e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
158e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
159e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    /**
160e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk     * This is only valid after setSamplesPerFrame() and setFormat() have been called.
161e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk     */
1623316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    int32_t getBytesPerFrame() const {
163e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk        return mSamplesPerFrame * getBytesPerSample();
164e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
165e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
166e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    /**
167e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk     * This is only valid after setFormat() has been called.
168e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk     */
1693316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    int32_t getBytesPerSample() const {
1705ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        return AAudioConvert_formatToSizeInBytes(mFormat);
171e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
172e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
1733316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    virtual int64_t getFramesWritten() {
174e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk        return mFramesWritten.get();
175e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
176e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
1773316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    virtual int64_t getFramesRead() {
178e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk        return mFramesRead.get();
179e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
180e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
181e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    AAudioStream_dataCallback getDataCallbackProc() const {
182e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        return mDataCallbackProc;
183e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
184e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    AAudioStream_errorCallback getErrorCallbackProc() const {
185e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        return mErrorCallbackProc;
186e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
187e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
188e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    void *getDataCallbackUserData() const {
189e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        return mDataCallbackUserData;
190e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
191e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    void *getErrorCallbackUserData() const {
192e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        return mErrorCallbackUserData;
193e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
194e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
195e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    int32_t getFramesPerDataCallback() const {
196e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        return mFramesPerDataCallback;
197e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
198e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
199e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    bool isDataCallbackActive() {
200e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk        return (mDataCallbackProc != nullptr) && isPlaying();
201e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    }
202e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
203e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    // ============== I/O ===========================
204e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    // A Stream will only implement read() or write() depending on its direction.
2055ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t write(const void *buffer,
2063316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk                             int32_t numFrames,
2073316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk                             int64_t timeoutNanoseconds) {
2085ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        return AAUDIO_ERROR_UNIMPLEMENTED;
209e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
210e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
2115ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t read(void *buffer,
2123316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk                            int32_t numFrames,
2133316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk                            int64_t timeoutNanoseconds) {
2145ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk        return AAUDIO_ERROR_UNIMPLEMENTED;
215e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
216e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
217e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burkprotected:
218e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
2193316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    virtual int64_t incrementFramesWritten(int32_t frames) {
2203316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk        return static_cast<int64_t>(mFramesWritten.increment(frames));
221e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
222e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
2233316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    virtual int64_t incrementFramesRead(int32_t frames) {
2243316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk        return static_cast<int64_t>(mFramesRead.increment(frames));
225e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
226e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
227e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    /**
228e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     * Wait for a transition from one state to another.
2295ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk     * @return AAUDIO_OK if the endingState was observed, or AAUDIO_ERROR_UNEXPECTED_STATE
230e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     *   if any state that was not the startingState or endingState was observed
2315ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk     *   or AAUDIO_ERROR_TIMEOUT
232e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     */
2335ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual aaudio_result_t waitForStateTransition(aaudio_stream_state_t startingState,
2343316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk                                                   aaudio_stream_state_t endingState,
2353316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk                                                   int64_t timeoutNanoseconds);
236e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
237e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    /**
238e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     * This should not be called after the open() call.
239e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     */
2403316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    void setSampleRate(int32_t sampleRate) {
241e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk        mSampleRate = sampleRate;
242e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
243e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
244e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    /**
245e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     * This should not be called after the open() call.
246e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     */
247e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    void setSamplesPerFrame(int32_t samplesPerFrame) {
248e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk        mSamplesPerFrame = samplesPerFrame;
249e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
250e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
251e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    /**
252e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     * This should not be called after the open() call.
253e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     */
2545ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    void setSharingMode(aaudio_sharing_mode_t sharingMode) {
255e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk        mSharingMode = sharingMode;
256e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
257e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
258e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    /**
259e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     * This should not be called after the open() call.
260e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk     */
2615ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    void setFormat(aaudio_audio_format_t format) {
262e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk        mFormat = format;
263e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
264e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
2655ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    void setState(aaudio_stream_state_t state) {
266e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk        mState = state;
267e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    }
268e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
269c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    void setDeviceId(int32_t deviceId) {
270c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        mDeviceId = deviceId;
271c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
272c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
273e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    std::mutex           mStreamMutex;
274e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
275e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    std::atomic<bool>    mCallbackEnabled;
276d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk
277d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burkprotected:
278e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    MonotonicCounter     mFramesWritten;
279e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    MonotonicCounter     mFramesRead;
280e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
2813316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    void setPeriodNanoseconds(int64_t periodNanoseconds) {
282d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk        mPeriodNanoseconds.store(periodNanoseconds, std::memory_order_release);
283d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk    }
284d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk
2853316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    int64_t getPeriodNanoseconds() {
286d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk        return mPeriodNanoseconds.load(std::memory_order_acquire);
287d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk    }
288d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk
289e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burkprivate:
290e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk    // These do not change after open().
2913316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    int32_t                mSamplesPerFrame = AAUDIO_UNSPECIFIED;
2923316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    int32_t                mSampleRate = AAUDIO_UNSPECIFIED;
2933316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    int32_t                mDeviceId = AAUDIO_UNSPECIFIED;
294c35f3ae6f361a346b6d823601c69dd704afe644aPhil Burk    aaudio_sharing_mode_t  mSharingMode = AAUDIO_SHARING_MODE_SHARED;
2955ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    aaudio_audio_format_t  mFormat = AAUDIO_FORMAT_UNSPECIFIED;
2965ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    aaudio_direction_t     mDirection = AAUDIO_DIRECTION_OUTPUT;
2973316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    aaudio_stream_state_t  mState = AAUDIO_STREAM_STATE_UNINITIALIZED;
298e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
299e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    // callback ----------------------------------
300e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
301e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    AAudioStream_dataCallback   mDataCallbackProc = nullptr;  // external callback functions
302e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    void                       *mDataCallbackUserData = nullptr;
303e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    int32_t                     mFramesPerDataCallback = AAUDIO_UNSPECIFIED; // frames
304e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
305e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    AAudioStream_errorCallback  mErrorCallbackProc = nullptr;
306e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    void                       *mErrorCallbackUserData = nullptr;
307e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
308d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk    // background thread ----------------------------------
3093316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    bool                   mHasThread = false;
3103316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    pthread_t              mThread; // initialized in constructor
311d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk
312d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk    // These are set by the application thread and then read by the audio pthread.
3133316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    std::atomic<int64_t>   mPeriodNanoseconds; // for tuning SCHED_FIFO threads
314d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk    // TODO make atomic?
315e2155ef0ec6742db7a3128c4ef4fb96e02828d1bPhil Burk    aaudio_audio_thread_proc_t mThreadProc = nullptr;
3163316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    void*                  mThreadArg = nullptr;
3175ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    aaudio_result_t        mThreadRegistrationResult = AAUDIO_OK;
318d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk
319d8bdcabbac30d48ed17fa76c83cb9ee95c290a07Phil Burk
320e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk};
321e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
3225ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk} /* namespace aaudio */
323e1ce491a25faf06fdeab00dd938515f71f28b095Phil Burk
3245ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#endif /* AAUDIO_AUDIOSTREAM_H */
325