19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2007, The Android Open Source Project
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License.
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project**
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License.
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdint.h>
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/types.h>
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h>
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sched.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h>
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/ioctl.h>
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "AudioHardware"
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h>
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/String8.h>
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "AudioHardwareGeneric.h"
33ad216e51b33c55634ec89d15e81e97cdffd08e1cDave Sparks#include <media/AudioRecord.h>
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic char const * const kAudioDeviceName = "/dev/eac";
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAudioHardwareGeneric::AudioHardwareGeneric()
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : mOutput(0), mInput(0),  mFd(-1), mMicMute(false)
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mFd = ::open(kAudioDeviceName, O_RDWR);
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAudioHardwareGeneric::~AudioHardwareGeneric()
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mFd >= 0) ::close(mFd);
52a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    closeOutputStream((AudioStreamOut *)mOutput);
53a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    closeInputStream((AudioStreamIn *)mInput);
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioHardwareGeneric::initCheck()
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mFd >= 0) {
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (::access(kAudioDeviceName, O_RDWR) == NO_ERROR)
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return NO_ERROR;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_INIT;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAudioStreamOut* AudioHardwareGeneric::openOutputStream(
66a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    AutoMutex lock(mLock);
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // only one output stream allowed
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mOutput) {
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (status) {
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *status = INVALID_OPERATION;
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // create new output stream
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    AudioStreamOutGeneric* out = new AudioStreamOutGeneric();
80a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    status_t lStatus = out->set(this, mFd, devices, format, channels, sampleRate);
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (status) {
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *status = lStatus;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (lStatus == NO_ERROR) {
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOutput = out;
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete out;
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mOutput;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
92a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioHardwareGeneric::closeOutputStream(AudioStreamOut* out) {
93a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mOutput && out == mOutput) {
94a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        delete mOutput;
95a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        mOutput = 0;
96a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAudioStreamIn* AudioHardwareGeneric::openInputStream(
100a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate,
101ad216e51b33c55634ec89d15e81e97cdffd08e1cDave Sparks        status_t *status, AudioSystem::audio_in_acoustics acoustics)
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
103ad216e51b33c55634ec89d15e81e97cdffd08e1cDave Sparks    // check for valid input source
104a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {
105ad216e51b33c55634ec89d15e81e97cdffd08e1cDave Sparks        return 0;
106ad216e51b33c55634ec89d15e81e97cdffd08e1cDave Sparks    }
107ad216e51b33c55634ec89d15e81e97cdffd08e1cDave Sparks
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    AutoMutex lock(mLock);
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // only one input stream allowed
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mInput) {
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (status) {
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *status = INVALID_OPERATION;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 0;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // create new output stream
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    AudioStreamInGeneric* in = new AudioStreamInGeneric();
120a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    status_t lStatus = in->set(this, mFd, devices, format, channels, sampleRate, acoustics);
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (status) {
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *status = lStatus;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (lStatus == NO_ERROR) {
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInput = in;
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        delete in;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return mInput;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
132a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioHardwareGeneric::closeInputStream(AudioStreamIn* in) {
133a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mInput && in == mInput) {
134a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        delete mInput;
135a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        mInput = 0;
136a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioHardwareGeneric::setVoiceVolume(float v)
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Implement: set voice volume
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioHardwareGeneric::setMasterVolume(float v)
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Implement: set master volume
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // return error - software mixer will handle it
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return INVALID_OPERATION;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioHardwareGeneric::setMicMute(bool state)
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mMicMute = state;
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioHardwareGeneric::getMicMute(bool* state)
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *state = mMicMute;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioHardwareGeneric::dumpInternals(int fd, const Vector<String16>& args)
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t SIZE = 256;
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char buffer[SIZE];
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String8 result;
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append("AudioHardwareGeneric::dumpInternals\n");
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    snprintf(buffer, SIZE, "\tmFd: %d mMicMute: %s\n",  mFd, mMicMute? "true": "false");
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append(buffer);
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ::write(fd, result.string(), result.size());
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioHardwareGeneric::dump(int fd, const Vector<String16>& args)
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dumpInternals(fd, args);
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mInput) {
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInput->dump(fd, args);
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mOutput) {
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mOutput->dump(fd, args);
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioStreamOutGeneric::set(
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AudioHardwareGeneric *hw,
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int fd,
193a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        uint32_t devices,
194a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        int *pFormat,
195a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        uint32_t *pChannels,
196a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        uint32_t *pRate)
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
198a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    int lFormat = pFormat ? *pFormat : 0;
199a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    uint32_t lChannels = pChannels ? *pChannels : 0;
200a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    uint32_t lRate = pRate ? *pRate : 0;
201a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // fix up defaults
203a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (lFormat == 0) lFormat = format();
204a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (lChannels == 0) lChannels = channels();
205a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (lRate == 0) lRate = sampleRate();
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // check values
208a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if ((lFormat != format()) ||
209a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            (lChannels != channels()) ||
210a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            (lRate != sampleRate())) {
211a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        if (pFormat) *pFormat = format();
212a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        if (pChannels) *pChannels = channels();
213a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        if (pRate) *pRate = sampleRate();
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return BAD_VALUE;
215a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
216a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
217a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (pFormat) *pFormat = lFormat;
218a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (pChannels) *pChannels = lChannels;
219a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (pRate) *pRate = lRate;
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mAudioHardware = hw;
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mFd = fd;
223a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mDevice = devices;
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAudioStreamOutGeneric::~AudioStreamOutGeneric()
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes)
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Mutex::Autolock _l(mLock);
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return ssize_t(::write(mFd, buffer, bytes));
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioStreamOutGeneric::standby()
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Implement: audio hardware to standby mode
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioStreamOutGeneric::dump(int fd, const Vector<String16>& args)
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t SIZE = 256;
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char buffer[SIZE];
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String8 result;
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    snprintf(buffer, SIZE, "AudioStreamOutGeneric::dump\n");
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append(buffer);
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append(buffer);
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append(buffer);
254a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append(buffer);
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    snprintf(buffer, SIZE, "\tformat: %d\n", format());
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append(buffer);
258a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice);
259a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    result.append(buffer);
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append(buffer);
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append(buffer);
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ::write(fd, result.string(), result.size());
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
268a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioStreamOutGeneric::setParameters(const String8& keyValuePairs)
269a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
270a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioParameter param = AudioParameter(keyValuePairs);
271a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    String8 key = String8(AudioParameter::keyRouting);
272a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    status_t status = NO_ERROR;
273a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    int device;
274a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("setParameters() %s", keyValuePairs.string());
275a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
276a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (param.getInt(key, device) == NO_ERROR) {
277a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        mDevice = device;
278a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        param.remove(key);
279a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
280a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
281a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (param.size()) {
282a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        status = BAD_VALUE;
283a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
284a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return status;
285a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
286a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
287a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentString8 AudioStreamOutGeneric::getParameters(const String8& keys)
288a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
289a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioParameter param = AudioParameter(keys);
290a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    String8 value;
291a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    String8 key = String8(AudioParameter::keyRouting);
292a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
293a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (param.get(key, value) == NO_ERROR) {
294a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        param.addInt(key, (int)mDevice);
295a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
296a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
297a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("getParameters() %s", param.toString().string());
298a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return param.toString();
299a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
300a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
3010986e7907ffc8387b04fb201e285784bcd11b9b7Eric Laurentstatus_t AudioStreamOutGeneric::getRenderPosition(uint32_t *dspFrames)
3020986e7907ffc8387b04fb201e285784bcd11b9b7Eric Laurent{
3030986e7907ffc8387b04fb201e285784bcd11b9b7Eric Laurent    return INVALID_OPERATION;
3040986e7907ffc8387b04fb201e285784bcd11b9b7Eric Laurent}
3050986e7907ffc8387b04fb201e285784bcd11b9b7Eric Laurent
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// record functions
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioStreamInGeneric::set(
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AudioHardwareGeneric *hw,
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int fd,
312a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        uint32_t devices,
313a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        int *pFormat,
314a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        uint32_t *pChannels,
315a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        uint32_t *pRate,
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        AudioSystem::audio_in_acoustics acoustics)
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
318a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (pFormat == 0 || pChannels == 0 || pRate == 0) return BAD_VALUE;
3190986e7907ffc8387b04fb201e285784bcd11b9b7Eric Laurent    LOGV("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, *pFormat, *pChannels, *pRate);
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // check values
321a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if ((*pFormat != format()) ||
322a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        (*pChannels != channels()) ||
323a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        (*pRate != sampleRate())) {
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Error opening input channel");
325a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        *pFormat = format();
326a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        *pChannels = channels();
327a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        *pRate = sampleRate();
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return BAD_VALUE;
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mAudioHardware = hw;
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    mFd = fd;
333a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mDevice = devices;
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAudioStreamInGeneric::~AudioStreamInGeneric()
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes)
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    AutoMutex lock(mLock);
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (mFd < 0) {
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        LOGE("Attempt to read from unopened device");
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NO_INIT;
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return ::read(mFd, buffer, bytes);
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t AudioStreamInGeneric::dump(int fd, const Vector<String16>& args)
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const size_t SIZE = 256;
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char buffer[SIZE];
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String8 result;
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    snprintf(buffer, SIZE, "AudioStreamInGeneric::dump\n");
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append(buffer);
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append(buffer);
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append(buffer);
362a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append(buffer);
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    snprintf(buffer, SIZE, "\tformat: %d\n", format());
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append(buffer);
366a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice);
367a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    result.append(buffer);
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append(buffer);
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    result.append(buffer);
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ::write(fd, result.string(), result.size());
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NO_ERROR;
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
376a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioStreamInGeneric::setParameters(const String8& keyValuePairs)
377a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
378a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioParameter param = AudioParameter(keyValuePairs);
379a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    String8 key = String8(AudioParameter::keyRouting);
380a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    status_t status = NO_ERROR;
381a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    int device;
382a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("setParameters() %s", keyValuePairs.string());
383a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
384a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (param.getInt(key, device) == NO_ERROR) {
385a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        mDevice = device;
386a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        param.remove(key);
387a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
388a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
389a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (param.size()) {
390a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        status = BAD_VALUE;
391a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
392a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return status;
393a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
394a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
395a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentString8 AudioStreamInGeneric::getParameters(const String8& keys)
396a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
397a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioParameter param = AudioParameter(keys);
398a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    String8 value;
399a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    String8 key = String8(AudioParameter::keyRouting);
400a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
401a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (param.get(key, value) == NO_ERROR) {
402a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        param.addInt(key, (int)mDevice);
403a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
404a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
405a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("getParameters() %s", param.toString().string());
406a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return param.toString();
407a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
408a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android
412