12355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk/*
22355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * Copyright (C) 2016 The Android Open Source Project
32355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk *
42355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * Licensed under the Apache License, Version 2.0 (the "License");
52355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * you may not use this file except in compliance with the License.
62355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * You may obtain a copy of the License at
72355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk *
82355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk *      http://www.apache.org/licenses/LICENSE-2.0
92355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk *
102355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * Unless required by applicable law or agreed to in writing, software
112355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * distributed under the License is distributed on an "AS IS" BASIS,
122355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * See the License for the specific language governing permissions and
142355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * limitations under the License.
152355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk */
162355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
175ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#ifndef AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H
185ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#define AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H
192355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
2071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk#include <assert.h>
21c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <mutex>
22dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk
232355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk#include "fifo/FifoBuffer.h"
24c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "binding/IAAudioService.h"
25c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "binding/AudioEndpointParcelable.h"
26c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "binding/AAudioServiceMessage.h"
27c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "utility/AAudioUtilities.h"
28c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
292355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk#include "SharedRingBuffer.h"
305ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#include "AAudioThread.h"
312355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
325ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burknamespace aaudio {
332355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
342355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk// We expect the queue to only have a few commands.
352355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk// This should be way more than we need.
362355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk#define QUEUE_UP_CAPACITY_COMMANDS (128)
372355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
38c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/**
39c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Base class for a stream in the AAudio service.
40c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk */
41c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkclass AAudioServiceStreamBase
42c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    : public Runnable  {
432355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
442355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burkpublic:
455ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    AAudioServiceStreamBase();
465ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    virtual ~AAudioServiceStreamBase();
472355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
482355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk    enum {
492355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk        ILLEGAL_THREAD_ID = 0
502355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk    };
512355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
52c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    // -------------------------------------------------------------------
532355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk    /**
542355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk     * Open the device.
552355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk     */
56c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    virtual aaudio_result_t open(const aaudio::AAudioStreamRequest &request,
57c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                                 aaudio::AAudioStreamConfiguration &configurationOutput) = 0;
58c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
59c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    virtual aaudio_result_t close();
602355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
612355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk    /**
622355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk     * Start the flow of data.
632355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk     */
6471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    virtual aaudio_result_t start();
652355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
662355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk    /**
672355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk     * Stop the flow of data such that start() can resume with loss of data.
682355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk     */
6971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    virtual aaudio_result_t pause();
7071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk
7171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    /**
7271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk     * Stop the flow of data after data in buffer has played.
7371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk     */
7471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    virtual aaudio_result_t stop();
752355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
762355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk    /**
772355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk     *  Discard any data held by the underlying HAL or Service.
782355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk     */
7971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    virtual aaudio_result_t flush();
802355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
81c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    // -------------------------------------------------------------------
822355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
83c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    /**
84c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk     * Send a message to the client.
85c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk     */
86c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t sendServiceEvent(aaudio_service_event_t event,
87c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                                     double  dataDouble = 0.0,
88c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                                     int64_t dataLong = 0);
89dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk
90c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    /**
91c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk     * Fill in a parcelable description of stream.
92c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk     */
93c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t getDescription(AudioEndpointParcelable &parcelable);
942355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
952355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
96c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    void setRegisteredThread(pid_t pid) {
972355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk        mRegisteredClientThread = pid;
982355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk    }
99dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk
100c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    pid_t getRegisteredThread() const {
1012355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk        return mRegisteredClientThread;
1022355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk    }
1032355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
104c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    int32_t getFramesPerBurst() const {
105c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        return mFramesPerBurst;
106c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
107c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
108c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    int32_t calculateBytesPerFrame() const {
109c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        return mSamplesPerFrame * AAudioConvert_formatToSizeInBytes(mAudioFormat);
110c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
111c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
112c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    void run() override; // to implement Runnable
113c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
114c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    void processError();
115c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
1162355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burkprotected:
117c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t writeUpMessageQueue(AAudioServiceMessage *command);
118c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
119c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t sendCurrentTimestamp();
120c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
121c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    virtual aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) = 0;
122c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
123c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    virtual aaudio_result_t getDownDataDescription(AudioEndpointParcelable &parcelable) = 0;
124c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
125c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_stream_state_t               mState = AAUDIO_STREAM_STATE_UNINITIALIZED;
1262355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
1273316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    pid_t              mRegisteredClientThread = ILLEGAL_THREAD_ID;
1282355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
1293316d5e6d375a4f09c681205e9094d30a0bfc4a2Phil Burk    SharedRingBuffer*  mUpMessageQueue;
130c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    std::mutex         mLockUpMessageQueue;
1312355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
132c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    AAudioThread        mAAudioThread;
133c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    // This is used by one thread to tell another thread to exit. So it must be atomic.
134c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    std::atomic<bool>   mThreadEnabled;
135dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk
1369dca9824da74d50be02bc81f539cc77b7bde678aPhil Burk    aaudio_format_t    mAudioFormat = AAUDIO_FORMAT_UNSPECIFIED;
137c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    int32_t            mFramesPerBurst = 0;
138c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    int32_t            mSamplesPerFrame = AAUDIO_UNSPECIFIED;
139c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    int32_t            mSampleRate = AAUDIO_UNSPECIFIED;
140c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    int32_t            mCapacityInFrames = AAUDIO_UNSPECIFIED;
1412355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk};
1422355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
1435ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk} /* namespace aaudio */
1442355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
1455ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#endif //AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H
146