Home | History | Annotate | Download | only in libaudio
      1 /*
      2 **
      3 ** Copyright 2012, 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 #define LOG_TAG "AudioHAL:AudioStreamIn"
     19 #include <utils/Log.h>
     20 
     21 #include "AudioStreamIn.h"
     22 #include "AudioHardwareInput.h"
     23 
     24 #include <assert.h>
     25 #include <stdio.h>
     26 #include <string.h>
     27 #include <unistd.h>
     28 #include <sys/types.h>
     29 #include <sys/stat.h>
     30 #include <fcntl.h>
     31 
     32 #include <utils/String8.h>
     33 #include <media/AudioParameter.h>
     34 
     35 // for turning Remote mic on/off
     36 #ifdef REMOTE_CONTROL_INTERFACE
     37 #include <IRemoteControlService.h>
     38 #endif
     39 
     40 namespace android {
     41 
     42 const audio_format_t AudioStreamIn::kAudioFormat = AUDIO_FORMAT_PCM_16_BIT;
     43 const uint32_t AudioStreamIn::kChannelMask = AUDIO_CHANNEL_IN_MONO;
     44 
     45 // number of periods in the ALSA buffer
     46 const int AudioStreamIn::kPeriodCount = 4;
     47 
     48 AudioStreamIn::AudioStreamIn(AudioHardwareInput& owner)
     49     : mOwnerHAL(owner)
     50     , mCurrentDeviceInfo(NULL)
     51     , mRequestedSampleRate(0)
     52     , mStandby(true)
     53     , mDisabled(false)
     54     , mPcm(NULL)
     55     , mResampler(NULL)
     56     , mBuffer(NULL)
     57     , mBufferSize(0)
     58     , mInputSource(AUDIO_SOURCE_DEFAULT)
     59     , mReadStatus(0)
     60     , mFramesIn(0)
     61 {
     62     struct resampler_buffer_provider& provider =
     63             mResamplerProviderWrapper.provider;
     64     provider.get_next_buffer = getNextBufferThunk;
     65     provider.release_buffer = releaseBufferThunk;
     66     mResamplerProviderWrapper.thiz = this;
     67 }
     68 
     69 AudioStreamIn::~AudioStreamIn()
     70 {
     71     Mutex::Autolock _l(mLock);
     72     standby_l();
     73 }
     74 
     75 // Perform stream initialization that may fail.
     76 // Must only be called once at construction time.
     77 status_t AudioStreamIn::set(audio_format_t *pFormat, uint32_t *pChannelMask,
     78                             uint32_t *pRate)
     79 {
     80     Mutex::Autolock _l(mLock);
     81 
     82     assert(mRequestedSampleRate == 0);
     83 
     84     // Respond with a request for mono if a different format is given.
     85     if (*pChannelMask != kChannelMask) {
     86         *pChannelMask = kChannelMask;
     87         return BAD_VALUE;
     88     }
     89 
     90     if (*pFormat != kAudioFormat) {
     91         *pFormat = kAudioFormat;
     92         return BAD_VALUE;
     93     }
     94 
     95     mRequestedSampleRate = *pRate;
     96 
     97     return NO_ERROR;
     98 }
     99 
    100 uint32_t AudioStreamIn::getSampleRate()
    101 {
    102     Mutex::Autolock _l(mLock);
    103     return mRequestedSampleRate;
    104 }
    105 
    106 status_t AudioStreamIn::setSampleRate(uint32_t rate)
    107 {
    108     (void) rate;
    109     // this is a no-op in other audio HALs
    110     return NO_ERROR;
    111 }
    112 
    113 size_t AudioStreamIn::getBufferSize()
    114 {
    115     Mutex::Autolock _l(mLock);
    116 
    117     size_t size = AudioHardwareInput::calculateInputBufferSize(
    118         mRequestedSampleRate, kAudioFormat, getChannelCount());
    119     return size;
    120 }
    121 
    122 uint32_t AudioStreamIn::getChannelMask()
    123 {
    124     return kChannelMask;
    125 }
    126 
    127 audio_format_t AudioStreamIn::getFormat()
    128 {
    129     return kAudioFormat;
    130 }
    131 
    132 status_t AudioStreamIn::setFormat(audio_format_t format)
    133 {
    134     (void) format;
    135     // other audio HALs fail any call to this API (even if the format matches
    136     // the current format)
    137     return INVALID_OPERATION;
    138 }
    139 
    140 status_t AudioStreamIn::standby()
    141 {
    142     Mutex::Autolock _l(mLock);
    143     return standby_l();
    144 }
    145 
    146 status_t AudioStreamIn::standby_l()
    147 {
    148     if (mStandby) {
    149         return NO_ERROR;
    150     }
    151     if (mPcm) {
    152         ALOGD("AudioStreamIn::standby_l, call pcm_close()");
    153         pcm_close(mPcm);
    154         mPcm = NULL;
    155     }
    156 
    157     // Turn OFF Remote MIC if we were recording from Remote.
    158     if (mCurrentDeviceInfo != NULL) {
    159         if (mCurrentDeviceInfo->forVoiceRecognition) {
    160             setRemoteControlMicEnabled(false);
    161         }
    162     }
    163 
    164     if (mResampler) {
    165         release_resampler(mResampler);
    166         mResampler = NULL;
    167     }
    168     if (mBuffer) {
    169         delete [] mBuffer;
    170         mBuffer = NULL;
    171     }
    172 
    173     mCurrentDeviceInfo = NULL;
    174     mStandby = true;
    175     mDisabled = false;
    176 
    177     return NO_ERROR;
    178 }
    179 
    180 #define DUMP(a...) \
    181     snprintf(buffer, SIZE, a); \
    182     buffer[SIZE - 1] = 0; \
    183     result.append(buffer);
    184 
    185 status_t AudioStreamIn::dump(int fd)
    186 {
    187     const size_t SIZE = 256;
    188     char buffer[SIZE];
    189     String8 result;
    190     DUMP("\n AudioStreamIn::dump\n");
    191 
    192     {
    193         DUMP("\toutput sample rate: %d\n", mRequestedSampleRate);
    194         if (mPcm) {
    195             DUMP("\tinput sample rate: %d\n", mPcmConfig.rate);
    196             DUMP("\tinput channels: %d\n", mPcmConfig.channels);
    197         }
    198     }
    199 
    200     ::write(fd, result.string(), result.size());
    201 
    202     return NO_ERROR;
    203 }
    204 
    205 status_t AudioStreamIn::setParameters(struct audio_stream* stream,
    206                                       const char* kvpairs)
    207 {
    208     (void) stream;
    209     AudioParameter param = AudioParameter(String8(kvpairs));
    210     status_t status = NO_ERROR;
    211     String8 keySource = String8(AudioParameter::keyInputSource);
    212     int intVal;
    213 
    214     if (param.getInt(keySource, intVal) == NO_ERROR) {
    215         ALOGI("AudioStreamIn::setParameters, mInputSource set to %d", intVal);
    216         mInputSource = intVal;
    217     }
    218 
    219     return status;
    220 }
    221 
    222 char* AudioStreamIn::getParameters(const char* keys)
    223 {
    224     (void) keys;
    225     return strdup("");
    226 }
    227 
    228 status_t AudioStreamIn::setGain(float gain)
    229 {
    230     (void) gain;
    231     // In other HALs, this is a no-op and returns success.
    232     return NO_ERROR;
    233 }
    234 
    235 uint32_t AudioStreamIn::getInputFramesLost()
    236 {
    237     return 0;
    238 }
    239 
    240 status_t AudioStreamIn::addAudioEffect(effect_handle_t effect)
    241 {
    242     (void) effect;
    243     // In other HALs, this is a no-op and returns success.
    244     return 0;
    245 }
    246 
    247 status_t AudioStreamIn::removeAudioEffect(effect_handle_t effect)
    248 {
    249     (void) effect;
    250     // In other HALs, this is a no-op and returns success.
    251     return 0;
    252 }
    253 
    254 ssize_t AudioStreamIn::read(void* buffer, size_t bytes)
    255 {
    256     Mutex::Autolock _l(mLock);
    257 
    258     status_t status = NO_ERROR;
    259 
    260     if (mStandby) {
    261         status = startInputStream_l();
    262         // Only try to start once to prevent pointless spew.
    263         // If mic is not available then read will return silence.
    264         // This is needed to prevent apps from hanging.
    265         mStandby = false;
    266         if (status != NO_ERROR) {
    267             mDisabled = true;
    268         }
    269     }
    270 
    271     if ((status == NO_ERROR) && !mDisabled) {
    272         int ret = readFrames_l(buffer, bytes / getFrameSize());
    273         status = (ret < 0) ? INVALID_OPERATION : NO_ERROR;
    274     }
    275 
    276     if ((status != NO_ERROR) || mDisabled) {
    277         memset(buffer, 0, bytes);
    278 
    279         // TODO: This code needs to project a timeline based on the number
    280         // of audio frames synthesized from the last time we returned data
    281         // from an actual audio device (or establish a fake timeline to obey
    282         // if we have never returned any data from an actual device and need
    283         // to synth on the first call to read)
    284         usleep(bytes * 1000000 / getFrameSize() / mRequestedSampleRate);
    285     } else {
    286         bool mute;
    287         mOwnerHAL.getMicMute(&mute);
    288         if (mute) {
    289             memset(buffer, 0, bytes);
    290         }
    291     }
    292 
    293     return bytes;
    294 }
    295 
    296 void AudioStreamIn::setRemoteControlMicEnabled(bool flag)
    297 {
    298 #ifdef REMOTE_CONTROL_INTERFACE
    299     sp<IRemoteControlService> service = IRemoteControlService::getInstance();
    300     if (service == NULL) {
    301         ALOGE("%s: No RemoteControl service detected, ignoring\n", __func__);
    302         return;
    303     }
    304     service->setMicEnabled(flag);
    305 #else
    306     (void)flag;
    307 #endif
    308 }
    309 
    310 status_t AudioStreamIn::startInputStream_l()
    311 {
    312 
    313     ALOGI("AudioStreamIn::startInputStream_l, entry, built %s", __DATE__);
    314 
    315     // Get the most appropriate device for the given input source, eg VOICE_RECOGNITION
    316     const AudioHotplugThread::DeviceInfo *deviceInfo = mOwnerHAL.getBestDevice(mInputSource);
    317     if (deviceInfo == NULL) {
    318         return INVALID_OPERATION;
    319     }
    320 
    321     memset(&mPcmConfig, 0, sizeof(mPcmConfig));
    322 
    323     unsigned int requestedChannelCount = getChannelCount();
    324 
    325     // Clip to min/max available.
    326     if (requestedChannelCount < deviceInfo->minChannelCount ) {
    327         mPcmConfig.channels = deviceInfo->minChannelCount;
    328     } else if (requestedChannelCount > deviceInfo->maxChannelCount ) {
    329         mPcmConfig.channels = deviceInfo->maxChannelCount;
    330     } else {
    331         mPcmConfig.channels = requestedChannelCount;
    332     }
    333 
    334     ALOGD("AudioStreamIn::startInputStream_l, mRequestedSampleRate = %d",
    335         mRequestedSampleRate);
    336 
    337     // Clip to min/max available from driver.
    338     uint32_t chosenSampleRate = mRequestedSampleRate;
    339     if (chosenSampleRate < deviceInfo->minSampleRate) {
    340         chosenSampleRate = deviceInfo->minSampleRate;
    341     } else if (chosenSampleRate > deviceInfo->maxSampleRate) {
    342         chosenSampleRate = deviceInfo->maxSampleRate;
    343     }
    344 
    345     // Turn on RemoteControl MIC if we are recording from it.
    346     if (deviceInfo->forVoiceRecognition) {
    347         setRemoteControlMicEnabled(true);
    348     }
    349 
    350     mPcmConfig.rate = chosenSampleRate;
    351 
    352     mPcmConfig.period_size =
    353             AudioHardwareInput::kPeriodMsec * mPcmConfig.rate / 1000;
    354     mPcmConfig.period_count = kPeriodCount;
    355     mPcmConfig.format = PCM_FORMAT_S16_LE;
    356 
    357     ALOGD("AudioStreamIn::startInputStream_l, call pcm_open()");
    358     struct pcm* pcm = pcm_open(deviceInfo->pcmCard, deviceInfo->pcmDevice,
    359                                PCM_IN, &mPcmConfig);
    360 
    361     if (!pcm_is_ready(pcm)) {
    362         ALOGE("ERROR AudioStreamIn::startInputStream_l, pcm_open failed");
    363         pcm_close(pcm);
    364         if (deviceInfo->forVoiceRecognition) {
    365             setRemoteControlMicEnabled(false);
    366         }
    367         return NO_MEMORY;
    368     }
    369 
    370     mCurrentDeviceInfo = deviceInfo;
    371 
    372     mBufferSize = pcm_frames_to_bytes(pcm, mPcmConfig.period_size);
    373     if (mBuffer) {
    374         delete [] mBuffer;
    375     }
    376     mBuffer = new int16_t[mBufferSize / sizeof(uint16_t)];
    377 
    378     if (mResampler) {
    379         release_resampler(mResampler);
    380         mResampler = NULL;
    381     }
    382     if (mPcmConfig.rate != mRequestedSampleRate) {
    383         ALOGD("AudioStreamIn::startInputStream_l, call create_resampler( %d  to %d)",
    384             mPcmConfig.rate, mRequestedSampleRate);
    385         int ret = create_resampler(mPcmConfig.rate,
    386                                    mRequestedSampleRate,
    387                                    1,
    388                                    RESAMPLER_QUALITY_DEFAULT,
    389                                    &mResamplerProviderWrapper.provider,
    390                                    &mResampler);
    391         if (ret != 0) {
    392             ALOGW("AudioStreamIn: unable to create resampler");
    393             pcm_close(pcm);
    394             return static_cast<status_t>(ret);
    395         }
    396     }
    397 
    398     mPcm = pcm;
    399 
    400     return NO_ERROR;
    401 }
    402 
    403 // readFrames() reads frames from kernel driver, down samples to the capture
    404 // rate if necessary and outputs the number of frames requested to the buffer
    405 // specified
    406 ssize_t AudioStreamIn::readFrames_l(void* buffer, ssize_t frames)
    407 {
    408     ssize_t framesWr = 0;
    409     size_t frameSize = getFrameSize();
    410 
    411     while (framesWr < frames) {
    412         size_t framesRd = frames - framesWr;
    413         if (mResampler) {
    414             char* outFrame = static_cast<char*>(buffer) +
    415                     (framesWr * frameSize);
    416             mResampler->resample_from_provider(
    417                 mResampler,
    418                 reinterpret_cast<int16_t*>(outFrame),
    419                 &framesRd);
    420         } else {
    421             struct resampler_buffer buf;
    422             buf.raw = NULL;
    423             buf.frame_count = framesRd;
    424 
    425             getNextBuffer(&buf);
    426             if (buf.raw != NULL) {
    427                 memcpy(static_cast<char*>(buffer) + (framesWr * frameSize),
    428                        buf.raw,
    429                        buf.frame_count * frameSize);
    430                 framesRd = buf.frame_count;
    431             }
    432             releaseBuffer(&buf);
    433         }
    434         // mReadStatus is updated by getNextBuffer(), which is called by the
    435         // resampler
    436         if (mReadStatus != 0)
    437             return mReadStatus;
    438 
    439         framesWr += framesRd;
    440     }
    441     return framesWr;
    442 }
    443 
    444 int AudioStreamIn::getNextBufferThunk(
    445         struct resampler_buffer_provider* bufferProvider,
    446         struct resampler_buffer* buffer)
    447 {
    448     ResamplerBufferProviderWrapper* wrapper =
    449             reinterpret_cast<ResamplerBufferProviderWrapper*>(
    450                 reinterpret_cast<char*>(bufferProvider) -
    451                 offsetof(ResamplerBufferProviderWrapper, provider));
    452 
    453     return wrapper->thiz->getNextBuffer(buffer);
    454 }
    455 
    456 void AudioStreamIn::releaseBufferThunk(
    457         struct resampler_buffer_provider* bufferProvider,
    458         struct resampler_buffer* buffer)
    459 {
    460     ResamplerBufferProviderWrapper* wrapper =
    461             reinterpret_cast<ResamplerBufferProviderWrapper*>(
    462                 reinterpret_cast<char*>(bufferProvider) -
    463                 offsetof(ResamplerBufferProviderWrapper, provider));
    464 
    465     wrapper->thiz->releaseBuffer(buffer);
    466 }
    467 
    468 // called while holding mLock
    469 int AudioStreamIn::getNextBuffer(struct resampler_buffer* buffer)
    470 {
    471     if (buffer == NULL) {
    472         return -EINVAL;
    473     }
    474 
    475     if (mPcm == NULL) {
    476         buffer->raw = NULL;
    477         buffer->frame_count = 0;
    478         mReadStatus = -ENODEV;
    479         return -ENODEV;
    480     }
    481 
    482     if (mFramesIn == 0) {
    483         mReadStatus = pcm_read(mPcm, mBuffer, mBufferSize);
    484         if (mReadStatus) {
    485             ALOGE("get_next_buffer() pcm_read error %d", mReadStatus);
    486             buffer->raw = NULL;
    487             buffer->frame_count = 0;
    488             return mReadStatus;
    489         }
    490 
    491         mFramesIn = mPcmConfig.period_size;
    492         if (mPcmConfig.channels == 2) {
    493             // Discard the right channel.
    494             // TODO: this is what other HALs are doing to handle stereo input
    495             // devices.  Need to verify if this is appropriate for ATV Remote.
    496             for (unsigned int i = 1; i < mFramesIn; i++) {
    497                 mBuffer[i] = mBuffer[i * 2];
    498             }
    499         }
    500     }
    501 
    502     buffer->frame_count = (buffer->frame_count > mFramesIn) ?
    503             mFramesIn : buffer->frame_count;
    504     buffer->i16 = mBuffer + (mPcmConfig.period_size - mFramesIn);
    505 
    506     return mReadStatus;
    507 }
    508 
    509 // called while holding mLock
    510 void AudioStreamIn::releaseBuffer(struct resampler_buffer* buffer)
    511 {
    512     if (buffer == NULL) {
    513         return;
    514     }
    515 
    516     mFramesIn -= buffer->frame_count;
    517 }
    518 
    519 }; // namespace android
    520