1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
/*
**
** Copyright 2011, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#ifndef ANDROID_AUDIO_OUTPUT_H
#define ANDROID_AUDIO_OUTPUT_H
#include <semaphore.h>
#include <tinyalsa/asoundlib.h>
#include <utils/String16.h>
#include <utils/String8.h>
#include <utils/threads.h>
#include <utils/Vector.h>
#include "LinearTransform.h"
namespace android {
class AudioStreamOut;
class AudioOutput : public RefBase {
public:
// Audio ouput state machine states.
enum State {
// Ouput not yet started or synchronized.
OUT_OF_SYNC,
// Silence primed to output to start DMA.
PRIMED,
// DMA started, ready to align to other inputs.
DMA_START,
// DMA active.
ACTIVE,
// Fatal, unrecoverable error.
FATAL,
};
AudioOutput(const char* alsa_name,
enum pcm_format alsa_pcm_format);
virtual ~AudioOutput();
virtual status_t initCheck();
virtual status_t setupForStream(const AudioStreamOut& stream) = 0;
// State machine transition functions.
State getState() { return mState; };
bool hasFatalError() { return mState == FATAL; }
// Prime data to output device, go to PRIMED state.
void primeOutput(bool hasActiveOutputs);
// Adjust for write timestamp difference, go to ACTIVE state.
void adjustDelay(int32_t nFrames);
// Send one chunk of data to ALSA, if state machine permits. This is called
// for every chunk sent down, regardless of the state of the output.
void processOneChunk(const uint8_t* data, size_t len,
bool hasActiveOutputs, audio_format_t format);
status_t getNextWriteTimestamp(int64_t* timestamp,
bool* discon);
bool getLastNextWriteTSValid() const;
int64_t getLastNextWriteTS() const;
uint32_t getExternalDelay_uSec() const;
void setExternalDelay_uSec(uint32_t delay);
void setDelayComp_uSec(uint32_t delay_usec);
void setVolume(float vol);
void setMute(bool mute);
void setOutputIsFixed(bool fixed);
void setFixedOutputLevel(float level);
float getVolume() const { return mVolume; }
bool getMute() const { return mMute; }
bool getOutputIsFixed() const { return mOutputFixed; }
float getFixedOutputLevel() const { return mFixedLvl; }
int getHardwareTimestamp(unsigned int *pAvail,
struct timespec *pTimestamp);
uint32_t getKernelBufferSize() { return mFramesPerChunk * mBufferChunks; }
virtual void dump(String8& result) = 0;
virtual const char* getOutputName() = 0;
virtual uint32_t devMask() const = 0;
virtual void cleanupResources();
static const uint32_t kMaxDelayCompensationMSec;
static const uint32_t kPrimeTimeoutChunks;
protected:
void pushSilence(uint32_t nFrames);
virtual void openPCMDevice();
virtual void reset();
virtual status_t getDMAStartData(int64_t* dma_start_time,
int64_t* frames_queued_to_driver);
void doPCMWrite(const uint8_t* data, size_t len, audio_format_t format);
void setupInternal();
// Current state machine state.
State mState;
// Output format
uint32_t mFramesPerChunk;
uint32_t mFramesPerSec;
uint32_t mBufferChunks;
uint32_t mChannelCnt;
const char* mALSAName;
enum pcm_format mALSAFormat;
// These numbers are relative to the ALSA output.
uint32_t mBytesPerSample;
uint32_t mBytesPerFrame;
uint32_t mBytesPerChunk;
size_t mStagingSize;
void* mStagingBuf;
size_t mSilenceSize;
void* mSilenceBuf;
// Get next write time stuff.
bool mLastNextWriteTimeValid;
int64_t mLastNextWriteTime;
int64_t mLastDMAStartTime;
// External delay compensation.
uint32_t mMaxDelayCompFrames;
uint32_t mExternalDelayUSec;
uint32_t mExternalDelayLocalTicks;
LinearTransform mFramesToLocalTime;
// ALSA device stuff.
Mutex mDeviceLock;
struct pcm* mDevice;
int mDeviceExtFd;
int mALSACardID;
uint64_t mFramesQueuedToDriver;
uint32_t mPrimeTimeoutChunks;
// reduce log spew
bool mReportedWriteFail;
// Volume stuff
Mutex mVolumeLock;
float mVolume;
float mFixedLvl;
bool mMute;
bool mOutputFixed;
bool mVolParamsDirty;
virtual void applyPendingVolParams() = 0;
};
typedef Vector< sp<AudioOutput> > AudioOutputList;
} // namespace android
#endif // ANDROID_AUDIO_OUTPUT_H
|