Home | History | Annotate | Download | only in audioflinger
      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 <stdint.h>
     19 #include <sys/types.h>
     20 
     21 #include <stdlib.h>
     22 #include <stdio.h>
     23 #include <unistd.h>
     24 #include <sched.h>
     25 #include <fcntl.h>
     26 #include <sys/ioctl.h>
     27 
     28 #define LOG_TAG "AudioHardware"
     29 #include <utils/Log.h>
     30 #include <utils/String8.h>
     31 
     32 #include "AudioHardwareGeneric.h"
     33 #include <media/AudioRecord.h>
     34 
     35 namespace android {
     36 
     37 // ----------------------------------------------------------------------------
     38 
     39 static char const * const kAudioDeviceName = "/dev/eac";
     40 
     41 // ----------------------------------------------------------------------------
     42 
     43 AudioHardwareGeneric::AudioHardwareGeneric()
     44     : mOutput(0), mInput(0),  mFd(-1), mMicMute(false)
     45 {
     46     mFd = ::open(kAudioDeviceName, O_RDWR);
     47 }
     48 
     49 AudioHardwareGeneric::~AudioHardwareGeneric()
     50 {
     51     if (mFd >= 0) ::close(mFd);
     52     closeOutputStream((AudioStreamOut *)mOutput);
     53     closeInputStream((AudioStreamIn *)mInput);
     54 }
     55 
     56 status_t AudioHardwareGeneric::initCheck()
     57 {
     58     if (mFd >= 0) {
     59         if (::access(kAudioDeviceName, O_RDWR) == NO_ERROR)
     60             return NO_ERROR;
     61     }
     62     return NO_INIT;
     63 }
     64 
     65 AudioStreamOut* AudioHardwareGeneric::openOutputStream(
     66         uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
     67 {
     68     AutoMutex lock(mLock);
     69 
     70     // only one output stream allowed
     71     if (mOutput) {
     72         if (status) {
     73             *status = INVALID_OPERATION;
     74         }
     75         return 0;
     76     }
     77 
     78     // create new output stream
     79     AudioStreamOutGeneric* out = new AudioStreamOutGeneric();
     80     status_t lStatus = out->set(this, mFd, devices, format, channels, sampleRate);
     81     if (status) {
     82         *status = lStatus;
     83     }
     84     if (lStatus == NO_ERROR) {
     85         mOutput = out;
     86     } else {
     87         delete out;
     88     }
     89     return mOutput;
     90 }
     91 
     92 void AudioHardwareGeneric::closeOutputStream(AudioStreamOut* out) {
     93     if (mOutput && out == mOutput) {
     94         delete mOutput;
     95         mOutput = 0;
     96     }
     97 }
     98 
     99 AudioStreamIn* AudioHardwareGeneric::openInputStream(
    100         uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate,
    101         status_t *status, AudioSystem::audio_in_acoustics acoustics)
    102 {
    103     // check for valid input source
    104     if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {
    105         return 0;
    106     }
    107 
    108     AutoMutex lock(mLock);
    109 
    110     // only one input stream allowed
    111     if (mInput) {
    112         if (status) {
    113             *status = INVALID_OPERATION;
    114         }
    115         return 0;
    116     }
    117 
    118     // create new output stream
    119     AudioStreamInGeneric* in = new AudioStreamInGeneric();
    120     status_t lStatus = in->set(this, mFd, devices, format, channels, sampleRate, acoustics);
    121     if (status) {
    122         *status = lStatus;
    123     }
    124     if (lStatus == NO_ERROR) {
    125         mInput = in;
    126     } else {
    127         delete in;
    128     }
    129     return mInput;
    130 }
    131 
    132 void AudioHardwareGeneric::closeInputStream(AudioStreamIn* in) {
    133     if (mInput && in == mInput) {
    134         delete mInput;
    135         mInput = 0;
    136     }
    137 }
    138 
    139 status_t AudioHardwareGeneric::setVoiceVolume(float v)
    140 {
    141     // Implement: set voice volume
    142     return NO_ERROR;
    143 }
    144 
    145 status_t AudioHardwareGeneric::setMasterVolume(float v)
    146 {
    147     // Implement: set master volume
    148     // return error - software mixer will handle it
    149     return INVALID_OPERATION;
    150 }
    151 
    152 status_t AudioHardwareGeneric::setMicMute(bool state)
    153 {
    154     mMicMute = state;
    155     return NO_ERROR;
    156 }
    157 
    158 status_t AudioHardwareGeneric::getMicMute(bool* state)
    159 {
    160     *state = mMicMute;
    161     return NO_ERROR;
    162 }
    163 
    164 status_t AudioHardwareGeneric::dumpInternals(int fd, const Vector<String16>& args)
    165 {
    166     const size_t SIZE = 256;
    167     char buffer[SIZE];
    168     String8 result;
    169     result.append("AudioHardwareGeneric::dumpInternals\n");
    170     snprintf(buffer, SIZE, "\tmFd: %d mMicMute: %s\n",  mFd, mMicMute? "true": "false");
    171     result.append(buffer);
    172     ::write(fd, result.string(), result.size());
    173     return NO_ERROR;
    174 }
    175 
    176 status_t AudioHardwareGeneric::dump(int fd, const Vector<String16>& args)
    177 {
    178     dumpInternals(fd, args);
    179     if (mInput) {
    180         mInput->dump(fd, args);
    181     }
    182     if (mOutput) {
    183         mOutput->dump(fd, args);
    184     }
    185     return NO_ERROR;
    186 }
    187 
    188 // ----------------------------------------------------------------------------
    189 
    190 status_t AudioStreamOutGeneric::set(
    191         AudioHardwareGeneric *hw,
    192         int fd,
    193         uint32_t devices,
    194         int *pFormat,
    195         uint32_t *pChannels,
    196         uint32_t *pRate)
    197 {
    198     int lFormat = pFormat ? *pFormat : 0;
    199     uint32_t lChannels = pChannels ? *pChannels : 0;
    200     uint32_t lRate = pRate ? *pRate : 0;
    201 
    202     // fix up defaults
    203     if (lFormat == 0) lFormat = format();
    204     if (lChannels == 0) lChannels = channels();
    205     if (lRate == 0) lRate = sampleRate();
    206 
    207     // check values
    208     if ((lFormat != format()) ||
    209             (lChannels != channels()) ||
    210             (lRate != sampleRate())) {
    211         if (pFormat) *pFormat = format();
    212         if (pChannels) *pChannels = channels();
    213         if (pRate) *pRate = sampleRate();
    214         return BAD_VALUE;
    215     }
    216 
    217     if (pFormat) *pFormat = lFormat;
    218     if (pChannels) *pChannels = lChannels;
    219     if (pRate) *pRate = lRate;
    220 
    221     mAudioHardware = hw;
    222     mFd = fd;
    223     mDevice = devices;
    224     return NO_ERROR;
    225 }
    226 
    227 AudioStreamOutGeneric::~AudioStreamOutGeneric()
    228 {
    229 }
    230 
    231 ssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes)
    232 {
    233     Mutex::Autolock _l(mLock);
    234     return ssize_t(::write(mFd, buffer, bytes));
    235 }
    236 
    237 status_t AudioStreamOutGeneric::standby()
    238 {
    239     // Implement: audio hardware to standby mode
    240     return NO_ERROR;
    241 }
    242 
    243 status_t AudioStreamOutGeneric::dump(int fd, const Vector<String16>& args)
    244 {
    245     const size_t SIZE = 256;
    246     char buffer[SIZE];
    247     String8 result;
    248     snprintf(buffer, SIZE, "AudioStreamOutGeneric::dump\n");
    249     result.append(buffer);
    250     snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
    251     result.append(buffer);
    252     snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
    253     result.append(buffer);
    254     snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
    255     result.append(buffer);
    256     snprintf(buffer, SIZE, "\tformat: %d\n", format());
    257     result.append(buffer);
    258     snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice);
    259     result.append(buffer);
    260     snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
    261     result.append(buffer);
    262     snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
    263     result.append(buffer);
    264     ::write(fd, result.string(), result.size());
    265     return NO_ERROR;
    266 }
    267 
    268 status_t AudioStreamOutGeneric::setParameters(const String8& keyValuePairs)
    269 {
    270     AudioParameter param = AudioParameter(keyValuePairs);
    271     String8 key = String8(AudioParameter::keyRouting);
    272     status_t status = NO_ERROR;
    273     int device;
    274     LOGV("setParameters() %s", keyValuePairs.string());
    275 
    276     if (param.getInt(key, device) == NO_ERROR) {
    277         mDevice = device;
    278         param.remove(key);
    279     }
    280 
    281     if (param.size()) {
    282         status = BAD_VALUE;
    283     }
    284     return status;
    285 }
    286 
    287 String8 AudioStreamOutGeneric::getParameters(const String8& keys)
    288 {
    289     AudioParameter param = AudioParameter(keys);
    290     String8 value;
    291     String8 key = String8(AudioParameter::keyRouting);
    292 
    293     if (param.get(key, value) == NO_ERROR) {
    294         param.addInt(key, (int)mDevice);
    295     }
    296 
    297     LOGV("getParameters() %s", param.toString().string());
    298     return param.toString();
    299 }
    300 
    301 status_t AudioStreamOutGeneric::getRenderPosition(uint32_t *dspFrames)
    302 {
    303     return INVALID_OPERATION;
    304 }
    305 
    306 // ----------------------------------------------------------------------------
    307 
    308 // record functions
    309 status_t AudioStreamInGeneric::set(
    310         AudioHardwareGeneric *hw,
    311         int fd,
    312         uint32_t devices,
    313         int *pFormat,
    314         uint32_t *pChannels,
    315         uint32_t *pRate,
    316         AudioSystem::audio_in_acoustics acoustics)
    317 {
    318     if (pFormat == 0 || pChannels == 0 || pRate == 0) return BAD_VALUE;
    319     LOGV("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, *pFormat, *pChannels, *pRate);
    320     // check values
    321     if ((*pFormat != format()) ||
    322         (*pChannels != channels()) ||
    323         (*pRate != sampleRate())) {
    324         LOGE("Error opening input channel");
    325         *pFormat = format();
    326         *pChannels = channels();
    327         *pRate = sampleRate();
    328         return BAD_VALUE;
    329     }
    330 
    331     mAudioHardware = hw;
    332     mFd = fd;
    333     mDevice = devices;
    334     return NO_ERROR;
    335 }
    336 
    337 AudioStreamInGeneric::~AudioStreamInGeneric()
    338 {
    339 }
    340 
    341 ssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes)
    342 {
    343     AutoMutex lock(mLock);
    344     if (mFd < 0) {
    345         LOGE("Attempt to read from unopened device");
    346         return NO_INIT;
    347     }
    348     return ::read(mFd, buffer, bytes);
    349 }
    350 
    351 status_t AudioStreamInGeneric::dump(int fd, const Vector<String16>& args)
    352 {
    353     const size_t SIZE = 256;
    354     char buffer[SIZE];
    355     String8 result;
    356     snprintf(buffer, SIZE, "AudioStreamInGeneric::dump\n");
    357     result.append(buffer);
    358     snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
    359     result.append(buffer);
    360     snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
    361     result.append(buffer);
    362     snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
    363     result.append(buffer);
    364     snprintf(buffer, SIZE, "\tformat: %d\n", format());
    365     result.append(buffer);
    366     snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice);
    367     result.append(buffer);
    368     snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
    369     result.append(buffer);
    370     snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
    371     result.append(buffer);
    372     ::write(fd, result.string(), result.size());
    373     return NO_ERROR;
    374 }
    375 
    376 status_t AudioStreamInGeneric::setParameters(const String8& keyValuePairs)
    377 {
    378     AudioParameter param = AudioParameter(keyValuePairs);
    379     String8 key = String8(AudioParameter::keyRouting);
    380     status_t status = NO_ERROR;
    381     int device;
    382     LOGV("setParameters() %s", keyValuePairs.string());
    383 
    384     if (param.getInt(key, device) == NO_ERROR) {
    385         mDevice = device;
    386         param.remove(key);
    387     }
    388 
    389     if (param.size()) {
    390         status = BAD_VALUE;
    391     }
    392     return status;
    393 }
    394 
    395 String8 AudioStreamInGeneric::getParameters(const String8& keys)
    396 {
    397     AudioParameter param = AudioParameter(keys);
    398     String8 value;
    399     String8 key = String8(AudioParameter::keyRouting);
    400 
    401     if (param.get(key, value) == NO_ERROR) {
    402         param.addInt(key, (int)mDevice);
    403     }
    404 
    405     LOGV("getParameters() %s", param.toString().string());
    406     return param.toString();
    407 }
    408 
    409 // ----------------------------------------------------------------------------
    410 
    411 }; // namespace android
    412