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