1204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk/*
2204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * Copyright (C) 2016 The Android Open Source Project
3204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk *
4204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * Licensed under the Apache License, Version 2.0 (the "License");
5204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * you may not use this file except in compliance with the License.
6204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * You may obtain a copy of the License at
7204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk *
8204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk *      http://www.apache.org/licenses/LICENSE-2.0
9204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk *
10204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * Unless required by applicable law or agreed to in writing, software
11204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * distributed under the License is distributed on an "AS IS" BASIS,
12204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * See the License for the specific language governing permissions and
14204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk * limitations under the License.
15204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk */
16204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
175204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk#ifndef ANDROID_AAUDIO_AUDIO_STREAM_INTERNAL_H
185204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk#define ANDROID_AAUDIO_AUDIO_STREAM_INTERNAL_H
19204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
20204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk#include <stdint.h>
215ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#include <aaudio/AAudio.h>
22204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
235ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#include "binding/IAAudioService.h"
24204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk#include "binding/AudioEndpointParcelable.h"
25e572f469de5dca1078a79d3d80e5b04f96ae7505Phil Burk#include "binding/AAudioServiceInterface.h"
26204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk#include "client/IsochronousClockModel.h"
27204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk#include "client/AudioEndpoint.h"
28204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk#include "core/AudioStream.h"
29fd34a9310659aa53e9e10d6826651577a75f6447Phil Burk#include "utility/AudioClock.h"
30e572f469de5dca1078a79d3d80e5b04f96ae7505Phil Burk#include "utility/LinearRamp.h"
31c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
32204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burkusing android::sp;
335ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burkusing android::IAAudioService;
34204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
355ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burknamespace aaudio {
36204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
375ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk// A stream that talks to the AAudioService or directly to a HAL.
38965650e5c36f39cb5e6d780a22ff711fbf5a37f5Phil Burkclass AudioStreamInternal : public AudioStream {
39204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
40204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burkpublic:
4187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    AudioStreamInternal(AAudioServiceInterface  &serviceInterface, bool inService);
42204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    virtual ~AudioStreamInternal();
43204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
44c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t requestStart() override;
45204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
46c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t requestStop() override;
47204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
48c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t getTimestamp(clockid_t clockId,
493316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk                                       int64_t *framePosition,
503316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk                                       int64_t *timeNanoseconds) override;
51204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
520befec600314a79c0d142c3edd99f7d1c75e1afePhil Burk    virtual aaudio_result_t updateStateMachine() override;
53204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
54c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t open(const AudioStreamBuilder &builder) override;
55204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
56c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t close() override;
57204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
58c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t setBufferSize(int32_t requestedFrames) override;
59204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
60c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    int32_t getBufferSize() const override;
61204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
62c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    int32_t getBufferCapacity() const override;
63204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
64c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    int32_t getFramesPerBurst() const override;
65204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
66c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    int32_t getXRunCount() const override {
67204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk        return mXRunCount;
68204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk    }
69204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
70c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t registerThread() override;
71204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
72c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t unregisterThread() override;
73204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
7487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    aaudio_result_t joinThread(void** returnArg);
7587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk
76e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    // Called internally from 'C'
7787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    virtual void *callbackLoop() = 0;
78e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
79e2fbb59e729f6c3cade3b531f6f6411417ccbf40Phil Burk
80e2fbb59e729f6c3cade3b531f6f6411417ccbf40Phil Burk    bool isMMap() override {
81e2fbb59e729f6c3cade3b531f6f6411417ccbf40Phil Burk        return true;
82e2fbb59e729f6c3cade3b531f6f6411417ccbf40Phil Burk    }
83e2fbb59e729f6c3cade3b531f6f6411417ccbf40Phil Burk
8487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    // Calculate timeout based on framesPerBurst
8587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    int64_t calculateReasonableTimeout();
8687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk
87cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent    aaudio_result_t startClient(const android::AudioClient& client,
88cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent                                audio_port_handle_t *clientHandle);
89cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent
90cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent    aaudio_result_t stopClient(audio_port_handle_t clientHandle);
91cb4dae216758d9e9a28050f65097f1ce905c03e9Eric Laurent
9239f02ddfbfd9313370d862a6c4727826379a319aPhil Burk    aaudio_handle_t getServiceHandle() const {
9339f02ddfbfd9313370d862a6c4727826379a319aPhil Burk        return mServiceStreamHandle;
9439f02ddfbfd9313370d862a6c4727826379a319aPhil Burk    }
9539f02ddfbfd9313370d862a6c4727826379a319aPhil Burk
96204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burkprotected:
97204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
9887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    aaudio_result_t processData(void *buffer,
9987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk                         int32_t numFrames,
10087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk                         int64_t timeoutNanoseconds);
10187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk
10287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk/**
10387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * Low level data processing that will not block. It will just read or write as much as it can.
10487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk *
10587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * It passed back a recommended time to wake up if wakeTimePtr is not NULL.
10687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk *
10787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk * @return the number of frames processed or a negative error code.
10887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk */
10987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    virtual aaudio_result_t processDataNow(void *buffer,
11087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk                            int32_t numFrames,
11187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk                            int64_t currentTimeNanos,
11287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk                            int64_t *wakeTimePtr) = 0;
11387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk
114bcc3674648bc6f554d89a2a5d7721ed41c53f83bPhil Burk    aaudio_result_t drainTimestampsFromService();
115bcc3674648bc6f554d89a2a5d7721ed41c53f83bPhil Burk
1165ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    aaudio_result_t processCommands();
117204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
11871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    aaudio_result_t requestStopInternal();
119e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
120e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    aaudio_result_t stopCallback();
121e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
122bcc3674648bc6f554d89a2a5d7721ed41c53f83bPhil Burk    virtual void advanceClientToMatchServerPosition() = 0;
123204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
124b336e89d57d51b80b8bf5f0a0caf7667209ffb1dPhil Burk    virtual void onFlushFromServer() {}
125204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
1265ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    aaudio_result_t onEventFromServer(AAudioServiceMessage *message);
127204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
12897350f9df7252c881f011a410fcd9e6d766d2beePhil Burk    aaudio_result_t onTimestampService(AAudioServiceMessage *message);
12997350f9df7252c881f011a410fcd9e6d766d2beePhil Burk
13097350f9df7252c881f011a410fcd9e6d766d2beePhil Burk    aaudio_result_t onTimestampHardware(AAudioServiceMessage *message);
131204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
132ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk    void logTimestamp(AAudioServiceMessage &message);
133ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk
134e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    // Calculate timeout for an operation involving framesPerOperation.
135e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk    int64_t calculateReasonableTimeout(int32_t framesPerOperation);
136e4d7bb418df0fdc4c708c334ba3601f5ed8d89b3Phil Burk
1379dca9824da74d50be02bc81f539cc77b7bde678aPhil Burk    aaudio_format_t          mDeviceFormat = AAUDIO_FORMAT_UNSPECIFIED;
13887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk
13987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    IsochronousClockModel    mClockModel;      // timing model for chasing the HAL
14087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk
14187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    AudioEndpoint            mAudioEndpoint;   // source for reads or sink for writes
14287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    aaudio_handle_t          mServiceStreamHandle; // opaque handle returned from service
14387c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk
14487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    int32_t                  mFramesPerBurst;     // frames per HAL transfer
14587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    int32_t                  mXRunCount = 0;      // how many underrun events?
14687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk
14787c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    // Offset from underlying frame position.
14887c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    int64_t                  mFramesOffsetFromService = 0; // offset for timestamps
14987c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk
15087c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    uint8_t                 *mCallbackBuffer = nullptr;
15187c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    int32_t                  mCallbackFrames = 0;
15287c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk
153ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk    // The service uses this for SHARED mode.
154ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk    bool                     mInService = false;  // Is this running in the client or the service?
155ec89b2e2f8c84a7d3936db1a888034f4a4b0df16Phil Burk
156b336e89d57d51b80b8bf5f0a0caf7667209ffb1dPhil Burk    AAudioServiceInterface  &mServiceInterface;   // abstract interface to the service
157b336e89d57d51b80b8bf5f0a0caf7667209ffb1dPhil Burk
158bcc3674648bc6f554d89a2a5d7721ed41c53f83bPhil Burk    SimpleDoubleBuffer<Timestamp>  mAtomicTimestamp;
159bcc3674648bc6f554d89a2a5d7721ed41c53f83bPhil Burk
160bcc3674648bc6f554d89a2a5d7721ed41c53f83bPhil Burk    AtomicRequestor          mNeedCatchUp;   // Ask read() or write() to sync on first timestamp.
161bcc3674648bc6f554d89a2a5d7721ed41c53f83bPhil Burk
162965650e5c36f39cb5e6d780a22ff711fbf5a37f5Phil Burk    float                    mStreamVolume = 1.0f;
163965650e5c36f39cb5e6d780a22ff711fbf5a37f5Phil Burk
164204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burkprivate:
165c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    /*
166c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk     * Asynchronous write with data conversion.
167c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk     * @param buffer
168c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk     * @param numFrames
169c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk     * @return fdrames written or negative error
170c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk     */
171c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t writeNowWithConversion(const void *buffer,
172c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                                     int32_t numFrames);
173c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
17487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    // Adjust timing model based on timestamp from service.
17587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    void processTimestamp(uint64_t position, int64_t time);
17671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk
177fd34a9310659aa53e9e10d6826651577a75f6447Phil Burk    // Thread on other side of FIFO will have wakeup jitter.
178fd34a9310659aa53e9e10d6826651577a75f6447Phil Burk    // By delaying slightly we can avoid waking up before other side is ready.
179fd34a9310659aa53e9e10d6826651577a75f6447Phil Burk    const int32_t            mWakeupDelayNanos; // delay past typical wakeup jitter
180fd34a9310659aa53e9e10d6826651577a75f6447Phil Burk    const int32_t            mMinimumSleepNanos; // minimum sleep while polling
181fd34a9310659aa53e9e10d6826651577a75f6447Phil Burk
182c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    AudioEndpointParcelable  mEndPointParcelable; // description of the buffers filled by service
183c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    EndpointDescriptor       mEndpointDescriptor; // buffer description with resolved addresses
18497350f9df7252c881f011a410fcd9e6d766d2beePhil Burk
18597350f9df7252c881f011a410fcd9e6d766d2beePhil Burk    int64_t                  mServiceLatencyNanos = 0;
186204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk};
187204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
1885ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk} /* namespace aaudio */
189204a163c86f357a878873fe7d4c4164f3d55c9b6Phil Burk
1905204d315c6c6f53188f8d1414dd1b55b6c90142bPhil Burk#endif //ANDROID_AAUDIO_AUDIO_STREAM_INTERNAL_H
191