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