blob: cc1bd8ffa22918e1f4ac5e81635f0256e231fedc [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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 ",
Eric Laurentef028272009-04-21 07:56:33 -070056 "HEADSET ",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057 "BLUETOOTH_A2DP "
58};
59static const char* routeNone = "NONE";
60
61static const char* displayMode(int mode)
62{
63 if ((mode < -2) || (mode > 2))
64 return routingModeStrings[0];
65 return routingModeStrings[mode+3];
66}
67
68static const char* displayRoutes(uint32_t routes)
69{
70 static char routeStr[80];
71 if (routes == 0)
72 return routeNone;
73 routeStr[0] = 0;
74 int bitMask = 1;
75 for (int i = 0; i < 4; ++i, bitMask <<= 1) {
76 if (routes & bitMask) {
77 strcat(routeStr, routeStrings[i]);
78 }
79 }
80 routeStr[strlen(routeStr)-1] = 0;
81 return routeStr;
82}
83#endif
84
85// ----------------------------------------------------------------------------
86
87AudioHardwareInterface* AudioHardwareInterface::create()
88{
89 /*
90 * FIXME: This code needs to instantiate the correct audio device
91 * interface. For now - we use compile-time switches.
92 */
93 AudioHardwareInterface* hw = 0;
94 char value[PROPERTY_VALUE_MAX];
95
96#ifdef GENERIC_AUDIO
97 hw = new AudioHardwareGeneric();
98#else
99 // if running in emulation - use the emulator driver
100 if (property_get("ro.kernel.qemu", value, 0)) {
101 LOGD("Running in emulation - using generic audio driver");
102 hw = new AudioHardwareGeneric();
103 }
104 else {
105 LOGV("Creating Vendor Specific AudioHardware");
106 hw = createAudioHardware();
107 }
108#endif
109 if (hw->initCheck() != NO_ERROR) {
110 LOGW("Using stubbed audio hardware. No sound will be produced.");
111 delete hw;
112 hw = new AudioHardwareStub();
113 }
114
115#ifdef DUMP_FLINGER_OUT
116 // This code adds a record of buffers in a file to write calls made by AudioFlinger.
117 // It replaces the current AudioHardwareInterface object by an intermediate one which
118 // will record buffers in a file (after sending them to hardware) for testing purpose.
119 // This feature is enabled by defining symbol DUMP_FLINGER_OUT.
120 // The output file is FLINGER_DUMP_NAME. Pause are not recorded in the file.
121
122 hw = new AudioDumpInterface(hw); // replace interface
123#endif
124 return hw;
125}
126
127AudioStreamOut::~AudioStreamOut()
128{
129}
130
131AudioStreamIn::~AudioStreamIn() {}
132
133AudioHardwareBase::AudioHardwareBase()
134{
135 // force a routing update on initialization
136 memset(&mRoutes, 0, sizeof(mRoutes));
137 mMode = 0;
138}
139
140// generics for audio routing - the real work is done in doRouting
141status_t AudioHardwareBase::setRouting(int mode, uint32_t routes)
142{
143#if LOG_ROUTING_CALLS
144 LOGD("setRouting: mode=%s, routes=[%s]", displayMode(mode), displayRoutes(routes));
145#endif
146 if (mode == AudioSystem::MODE_CURRENT)
147 mode = mMode;
148 if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
149 return BAD_VALUE;
150 uint32_t old = mRoutes[mode];
151 mRoutes[mode] = routes;
152 if ((mode != mMode) || (old == routes))
153 return NO_ERROR;
154#if LOG_ROUTING_CALLS
155 const char* oldRouteStr = strdup(displayRoutes(old));
156 LOGD("doRouting: mode=%s, old route=[%s], new route=[%s]",
157 displayMode(mode), oldRouteStr, displayRoutes(routes));
158 delete oldRouteStr;
159#endif
160 return doRouting();
161}
162
163status_t AudioHardwareBase::getRouting(int mode, uint32_t* routes)
164{
165 if (mode == AudioSystem::MODE_CURRENT)
166 mode = mMode;
167 if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
168 return BAD_VALUE;
169 *routes = mRoutes[mode];
170#if LOG_ROUTING_CALLS
171 LOGD("getRouting: mode=%s, routes=[%s]",
172 displayMode(mode), displayRoutes(*routes));
173#endif
174 return NO_ERROR;
175}
176
177status_t AudioHardwareBase::setMode(int mode)
178{
179#if LOG_ROUTING_CALLS
180 LOGD("setMode(%s)", displayMode(mode));
181#endif
182 if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
183 return BAD_VALUE;
184 if (mMode == mode)
185 return NO_ERROR;
186#if LOG_ROUTING_CALLS
187 LOGD("doRouting: old mode=%s, new mode=%s route=[%s]",
188 displayMode(mMode), displayMode(mode), displayRoutes(mRoutes[mode]));
189#endif
190 mMode = mode;
191 return doRouting();
192}
193
194status_t AudioHardwareBase::getMode(int* mode)
195{
196 // Implement: set audio routing
197 *mode = mMode;
198 return NO_ERROR;
199}
200
201status_t AudioHardwareBase::setParameter(const char* key, const char* value)
202{
203 // default implementation is to ignore
204 return NO_ERROR;
205}
206
207
208// default implementation
209size_t AudioHardwareBase::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
210{
211 if (sampleRate != 8000) {
212 LOGW("getInputBufferSize bad sampling rate: %d", sampleRate);
213 return 0;
214 }
215 if (format != AudioSystem::PCM_16_BIT) {
216 LOGW("getInputBufferSize bad format: %d", format);
217 return 0;
218 }
219 if (channelCount != 1) {
220 LOGW("getInputBufferSize bad channel count: %d", channelCount);
221 return 0;
222 }
223
224 return 320;
225}
226
227status_t AudioHardwareBase::dumpState(int fd, const Vector<String16>& args)
228{
229 const size_t SIZE = 256;
230 char buffer[SIZE];
231 String8 result;
232 snprintf(buffer, SIZE, "AudioHardwareBase::dumpState\n");
233 result.append(buffer);
234 snprintf(buffer, SIZE, "\tmMode: %d\n", mMode);
235 result.append(buffer);
236 for (int i = 0, n = AudioSystem::NUM_MODES; i < n; ++i) {
237 snprintf(buffer, SIZE, "\tmRoutes[%d]: %d\n", i, mRoutes[i]);
238 result.append(buffer);
239 }
240 ::write(fd, result.string(), result.size());
241 dump(fd, args); // Dump the state of the concrete child.
242 return NO_ERROR;
243}
244
245// ----------------------------------------------------------------------------
246
247}; // namespace android