blob: 7387b3d36e3b33b8e6f7da5f23acafa7160a8cee [file] [log] [blame]
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001/*
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
38namespace android {
39
40#if LOG_ROUTING_CALLS
41static const char* routingModeStrings[] =
42{
43 "OUT OF RANGE",
44 "INVALID",
45 "CURRENT",
46 "NORMAL",
47 "RINGTONE",
48 "IN_CALL"
49};
50
51static const char* routeStrings[] =
52{
53 "EARPIECE ",
54 "SPEAKER ",
55 "BLUETOOTH ",
56 "HEADSET "
57};
58static const char* routeNone = "NONE";
59
60static const char* displayMode(int mode)
61{
62 if ((mode < -2) || (mode > 2))
63 return routingModeStrings[0];
64 return routingModeStrings[mode+3];
65}
66
67static 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
86AudioHardwareInterface* 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
140AudioStreamOut::~AudioStreamOut()
141{
142}
143
144AudioStreamIn::~AudioStreamIn() {}
145
146AudioHardwareInterface::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
154status_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
176status_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
190status_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
207status_t AudioHardwareInterface::getMode(int* mode)
208{
209 // Implement: set audio routing
210 *mode = mMode;
211 return NO_ERROR;
212}
213
214status_t AudioHardwareInterface::setParameter(const char* key, const char* value)
215{
216 // default implementation is to ignore
217 return NO_ERROR;
218}
219
220status_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