1/*
2 * Copyright (C) 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_AAUDIO_SERVICE_STREAM_BASE_H
18#define AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H
19
20#include <assert.h>
21#include <mutex>
22
23#include "fifo/FifoBuffer.h"
24#include "binding/IAAudioService.h"
25#include "binding/AudioEndpointParcelable.h"
26#include "binding/AAudioServiceMessage.h"
27#include "utility/AAudioUtilities.h"
28
29#include "SharedRingBuffer.h"
30#include "AAudioThread.h"
31
32namespace aaudio {
33
34// We expect the queue to only have a few commands.
35// This should be way more than we need.
36#define QUEUE_UP_CAPACITY_COMMANDS (128)
37
38/**
39 * Base class for a stream in the AAudio service.
40 */
41class AAudioServiceStreamBase
42    : public Runnable  {
43
44public:
45    AAudioServiceStreamBase();
46    virtual ~AAudioServiceStreamBase();
47
48    enum {
49        ILLEGAL_THREAD_ID = 0
50    };
51
52    // -------------------------------------------------------------------
53    /**
54     * Open the device.
55     */
56    virtual aaudio_result_t open(const aaudio::AAudioStreamRequest &request,
57                                 aaudio::AAudioStreamConfiguration &configurationOutput) = 0;
58
59    virtual aaudio_result_t close();
60
61    /**
62     * Start the flow of data.
63     */
64    virtual aaudio_result_t start();
65
66    /**
67     * Stop the flow of data such that start() can resume with loss of data.
68     */
69    virtual aaudio_result_t pause();
70
71    /**
72     * Stop the flow of data after data in buffer has played.
73     */
74    virtual aaudio_result_t stop();
75
76    /**
77     *  Discard any data held by the underlying HAL or Service.
78     */
79    virtual aaudio_result_t flush();
80
81    // -------------------------------------------------------------------
82
83    /**
84     * Send a message to the client.
85     */
86    aaudio_result_t sendServiceEvent(aaudio_service_event_t event,
87                                     double  dataDouble = 0.0,
88                                     int64_t dataLong = 0);
89
90    /**
91     * Fill in a parcelable description of stream.
92     */
93    aaudio_result_t getDescription(AudioEndpointParcelable &parcelable);
94
95
96    void setRegisteredThread(pid_t pid) {
97        mRegisteredClientThread = pid;
98    }
99
100    pid_t getRegisteredThread() const {
101        return mRegisteredClientThread;
102    }
103
104    int32_t getFramesPerBurst() const {
105        return mFramesPerBurst;
106    }
107
108    int32_t calculateBytesPerFrame() const {
109        return mSamplesPerFrame * AAudioConvert_formatToSizeInBytes(mAudioFormat);
110    }
111
112    void run() override; // to implement Runnable
113
114    void processError();
115
116protected:
117    aaudio_result_t writeUpMessageQueue(AAudioServiceMessage *command);
118
119    aaudio_result_t sendCurrentTimestamp();
120
121    virtual aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) = 0;
122
123    virtual aaudio_result_t getDownDataDescription(AudioEndpointParcelable &parcelable) = 0;
124
125    aaudio_stream_state_t               mState = AAUDIO_STREAM_STATE_UNINITIALIZED;
126
127    pid_t              mRegisteredClientThread = ILLEGAL_THREAD_ID;
128
129    SharedRingBuffer*  mUpMessageQueue;
130    std::mutex         mLockUpMessageQueue;
131
132    AAudioThread        mAAudioThread;
133    // This is used by one thread to tell another thread to exit. So it must be atomic.
134    std::atomic<bool>   mThreadEnabled;
135
136    aaudio_format_t    mAudioFormat = AAUDIO_FORMAT_UNSPECIFIED;
137    int32_t            mFramesPerBurst = 0;
138    int32_t            mSamplesPerFrame = AAUDIO_UNSPECIFIED;
139    int32_t            mSampleRate = AAUDIO_UNSPECIFIED;
140    int32_t            mCapacityInFrames = AAUDIO_UNSPECIFIED;
141};
142
143} /* namespace aaudio */
144
145#endif //AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H
146