AudioHardwareInterface.cpp revision ef02827d4c3b9c0601eddc9c348fc2ea866420a2
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
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    "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
248