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