OSDN Git Service

Template files from frameworks/base/libs/audioflinger
[android-x86/hardware-alsa_sound.git] / AudioHardwareInterface.cpp
1 /*
2 **
3 ** Copyright 2007, 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 #include <cutils/properties.h>
19 #include <string.h>
20 #include <unistd.h>
21
22 #define LOG_TAG "AudioHardwareInterface"
23 #include <utils/Log.h>
24 #include <utils/String8.h>
25
26 #include "AudioHardwareStub.h"
27 #include "AudioHardwareGeneric.h"
28
29 // #define DUMP_FLINGER_OUT        // if defined allows recording samples in a file
30 #ifdef DUMP_FLINGER_OUT
31 #include "AudioDumpInterface.h"
32 #endif
33
34
35 // change to 1 to log routing calls
36 #define LOG_ROUTING_CALLS 0
37
38 namespace android {
39
40 #if LOG_ROUTING_CALLS
41 static const char* routingModeStrings[] =
42 {
43     "OUT OF RANGE",
44     "INVALID",
45     "CURRENT",
46     "NORMAL",
47     "RINGTONE",
48     "IN_CALL"
49 };
50
51 static const char* routeStrings[] =
52 {
53     "EARPIECE ",
54     "SPEAKER ",
55     "BLUETOOTH ",
56     "HEADSET "
57 };
58 static const char* routeNone = "NONE";
59
60 static const char* displayMode(int mode)
61 {
62     if ((mode < -2) || (mode > 2))
63         return routingModeStrings[0];
64     return routingModeStrings[mode+3];
65 }
66
67 static const char* displayRoutes(uint32_t routes)
68 {
69     static char routeStr[80];
70     if (routes == 0)
71         return routeNone;
72     routeStr[0] = 0;
73     int bitMask = 1;
74     for (int i = 0; i < 4; ++i, bitMask <<= 1) {
75         if (routes & bitMask) {
76             strcat(routeStr, routeStrings[i]);
77         }
78     }
79     routeStr[strlen(routeStr)-1] = 0;
80     return routeStr;
81 }
82 #endif
83
84 // ----------------------------------------------------------------------------
85
86 AudioHardwareInterface* AudioHardwareInterface::create()
87 {
88     /*
89      * FIXME: This code needs to instantiate the correct audio device
90      * interface. For now - we use compile-time switches.
91      */
92     AudioHardwareInterface* hw = 0;
93     char value[PROPERTY_VALUE_MAX];
94
95 #ifdef GENERIC_AUDIO
96     hw = new AudioHardwareGeneric();
97 #else
98     // if running in emulation - use the emulator driver
99     if (property_get("ro.kernel.qemu", value, 0)) {
100         LOGD("Running in emulation - using generic audio driver");
101         hw = new AudioHardwareGeneric();
102     }
103     else {
104         LOGV("Creating Vendor Specific AudioHardware");
105         hw = createAudioHardware();
106     }
107 #endif
108     if (hw->initCheck() != NO_ERROR) {
109         LOGW("Using stubbed audio hardware. No sound will be produced.");
110         delete hw;
111         hw = new AudioHardwareStub();
112     }
113     
114 #ifdef DUMP_FLINGER_OUT
115     // This code adds a record of buffers in a file to write calls made by AudioFlinger.
116     // It replaces the current AudioHardwareInterface object by an intermediate one which
117     // will record buffers in a file (after sending them to hardware) for testing purpose.
118     // This feature is enabled by defining symbol DUMP_FLINGER_OUT and setting environement
119     // "audioflinger.dump = 1". The output file is "tmp/FlingerOut.pcm". Pause are not recorded
120     // in the file.
121     
122     // read dump mode
123     property_get("audioflinger.dump", value, "0");
124     switch(value[0]) {
125     case '1':
126         LOGV("Dump mode");
127         hw = new AudioDumpInterface(hw);    // replace interface
128         return hw;
129         break;
130     case '0':
131     default:
132         LOGV("No Dump mode");
133         return hw;
134         break;
135     }
136 #endif
137     return hw;
138 }
139
140 AudioStreamOut::~AudioStreamOut()
141 {
142 }
143
144 AudioStreamIn::~AudioStreamIn() {}
145
146 AudioHardwareInterface::AudioHardwareInterface()
147 {
148     // force a routing update on initialization
149     memset(&mRoutes, 0, sizeof(mRoutes));
150     mMode = 0;
151 }
152
153 // generics for audio routing - the real work is done in doRouting
154 status_t AudioHardwareInterface::setRouting(int mode, uint32_t routes)
155 {
156 #if LOG_ROUTING_CALLS
157     LOGD("setRouting: mode=%s, routes=[%s]", displayMode(mode), displayRoutes(routes));
158 #endif
159     if (mode == AudioSystem::MODE_CURRENT)
160         mode = mMode;
161     if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
162         return BAD_VALUE;
163     uint32_t old = mRoutes[mode];
164     mRoutes[mode] = routes;
165     if ((mode != mMode) || (old == routes))
166         return NO_ERROR;
167 #if LOG_ROUTING_CALLS
168     const char* oldRouteStr = strdup(displayRoutes(old));
169     LOGD("doRouting: mode=%s, old route=[%s], new route=[%s]",
170            displayMode(mode), oldRouteStr, displayRoutes(routes));
171     delete oldRouteStr;
172 #endif
173     return doRouting();
174 }
175
176 status_t AudioHardwareInterface::getRouting(int mode, uint32_t* routes)
177 {
178     if (mode == AudioSystem::MODE_CURRENT)
179         mode = mMode;
180     if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
181         return BAD_VALUE;
182     *routes = mRoutes[mode];
183 #if LOG_ROUTING_CALLS
184     LOGD("getRouting: mode=%s, routes=[%s]",
185            displayMode(mode), displayRoutes(*routes));
186 #endif
187     return NO_ERROR;
188 }
189
190 status_t AudioHardwareInterface::setMode(int mode)
191 {
192 #if LOG_ROUTING_CALLS
193     LOGD("setMode(%s)", displayMode(mode));
194 #endif
195     if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
196         return BAD_VALUE;
197     if (mMode == mode)
198         return NO_ERROR;
199 #if LOG_ROUTING_CALLS
200     LOGD("doRouting: old mode=%s, new mode=%s route=[%s]",
201             displayMode(mMode), displayMode(mode), displayRoutes(mRoutes[mode]));
202 #endif
203     mMode = mode;
204     return doRouting();
205 }
206
207 status_t AudioHardwareInterface::getMode(int* mode)
208 {
209     // Implement: set audio routing
210     *mode = mMode;
211     return NO_ERROR;
212 }
213
214 status_t AudioHardwareInterface::setParameter(const char* key, const char* value)
215 {
216     // default implementation is to ignore
217     return NO_ERROR;
218 }
219
220 status_t AudioHardwareInterface::dumpState(int fd, const Vector<String16>& args)
221 {
222     const size_t SIZE = 256;
223     char buffer[SIZE];
224     String8 result;
225     snprintf(buffer, SIZE, "AudioHardwareInterface::dumpState\n");
226     result.append(buffer);
227     snprintf(buffer, SIZE, "\tmMode: %d\n", mMode);
228     result.append(buffer);
229     for (int i = 0, n = AudioSystem::NUM_MODES; i < n; ++i) {
230         snprintf(buffer, SIZE, "\tmRoutes[%d]: %d\n", i, mRoutes[i]);
231         result.append(buffer);
232     }
233     ::write(fd, result.string(), result.size());
234     dump(fd, args);  // Dump the state of the concrete child.
235     return NO_ERROR;
236 }
237
238 // ----------------------------------------------------------------------------
239
240 }; // namespace android