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//#define LOG_NDEBUG 0
22
23#define LOG_TAG "AudioHardwareInterface"
24#include <utils/Log.h>
25#include <utils/String8.h>
26
27#include "AudioHardwareStub.h"
28#include "AudioHardwareGeneric.h"
29#ifdef WITH_A2DP
30#include "A2dpAudioInterface.h"
31#endif
32
33#ifdef ENABLE_AUDIO_DUMP
34#include "AudioDumpInterface.h"
35#endif
36
37
38// change to 1 to log routing calls
39#define LOG_ROUTING_CALLS 1
40
41namespace android {
42
43#if LOG_ROUTING_CALLS
44static const char* routingModeStrings[] =
45{
46    "OUT OF RANGE",
47    "INVALID",
48    "CURRENT",
49    "NORMAL",
50    "RINGTONE",
51    "IN_CALL"
52};
53
54static const char* routeNone = "NONE";
55
56static const char* displayMode(int mode)
57{
58    if ((mode < -2) || (mode > 2))
59        return routingModeStrings[0];
60    return routingModeStrings[mode+3];
61}
62#endif
63
64// ----------------------------------------------------------------------------
65
66AudioHardwareInterface* AudioHardwareInterface::create()
67{
68    /*
69     * FIXME: This code needs to instantiate the correct audio device
70     * interface. For now - we use compile-time switches.
71     */
72    AudioHardwareInterface* hw = 0;
73    char value[PROPERTY_VALUE_MAX];
74
75#ifdef GENERIC_AUDIO
76    hw = new AudioHardwareGeneric();
77#else
78    // if running in emulation - use the emulator driver
79    if (property_get("ro.kernel.qemu", value, 0)) {
80        LOGD("Running in emulation - using generic audio driver");
81        hw = new AudioHardwareGeneric();
82    }
83    else {
84        LOGV("Creating Vendor Specific AudioHardware");
85        hw = createAudioHardware();
86    }
87#endif
88    if (hw->initCheck() != NO_ERROR) {
89        LOGW("Using stubbed audio hardware. No sound will be produced.");
90        delete hw;
91        hw = new AudioHardwareStub();
92    }
93
94#ifdef WITH_A2DP
95    hw = new A2dpAudioInterface(hw);
96#endif
97
98#ifdef ENABLE_AUDIO_DUMP
99    // This code adds a record of buffers in a file to write calls made by AudioFlinger.
100    // It replaces the current AudioHardwareInterface object by an intermediate one which
101    // will record buffers in a file (after sending them to hardware) for testing purpose.
102    // This feature is enabled by defining symbol ENABLE_AUDIO_DUMP.
103    // The output file is set with setParameters("test_cmd_file_name=<name>"). Pause are not recorded in the file.
104    LOGV("opening PCM dump interface");
105    hw = new AudioDumpInterface(hw);    // replace interface
106#endif
107    return hw;
108}
109
110AudioStreamOut::~AudioStreamOut()
111{
112}
113
114AudioStreamIn::~AudioStreamIn() {}
115
116AudioHardwareBase::AudioHardwareBase()
117{
118    mMode = 0;
119}
120
121status_t AudioHardwareBase::setMode(int mode)
122{
123#if LOG_ROUTING_CALLS
124    LOGD("setMode(%s)", displayMode(mode));
125#endif
126    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
127        return BAD_VALUE;
128    if (mMode == mode)
129        return ALREADY_EXISTS;
130    mMode = mode;
131    return NO_ERROR;
132}
133
134// default implementation
135status_t AudioHardwareBase::setParameters(const String8& keyValuePairs)
136{
137    return NO_ERROR;
138}
139
140// default implementation
141String8 AudioHardwareBase::getParameters(const String8& keys)
142{
143    AudioParameter param = AudioParameter(keys);
144    return param.toString();
145}
146
147// default implementation
148size_t AudioHardwareBase::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
149{
150    if (sampleRate != 8000) {
151        LOGW("getInputBufferSize bad sampling rate: %d", sampleRate);
152        return 0;
153    }
154    if (format != AudioSystem::PCM_16_BIT) {
155        LOGW("getInputBufferSize bad format: %d", format);
156        return 0;
157    }
158    if (channelCount != 1) {
159        LOGW("getInputBufferSize bad channel count: %d", channelCount);
160        return 0;
161    }
162
163    return 320;
164}
165
166status_t AudioHardwareBase::dumpState(int fd, const Vector<String16>& args)
167{
168    const size_t SIZE = 256;
169    char buffer[SIZE];
170    String8 result;
171    snprintf(buffer, SIZE, "AudioHardwareBase::dumpState\n");
172    result.append(buffer);
173    snprintf(buffer, SIZE, "\tmMode: %d\n", mMode);
174    result.append(buffer);
175    ::write(fd, result.string(), result.size());
176    dump(fd, args);  // Dump the state of the concrete child.
177    return NO_ERROR;
178}
179
180// ----------------------------------------------------------------------------
181
182}; // namespace android
183