Home | History | Annotate | Download | only in audio
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
      5  * use this file except in compliance with the License. You may obtain a copy of
      6  * the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     13  * License for the specific language governing permissions and limitations under
     14  * the License.
     15  */
     16 #include <sys/types.h>
     17 #include <regex.h>
     18 #include <stdlib.h>
     19 
     20 #include <tinyalsa/asoundlib.h>
     21 
     22 #include "Log.h"
     23 #include "StringUtil.h"
     24 #include "SimpleScriptExec.h"
     25 #include "audio/AudioHardware.h"
     26 #include "audio/Buffer.h"
     27 #include "audio/AudioPlaybackLocal.h"
     28 #include "audio/AudioRecordingLocal.h"
     29 #include "audio/AudioRemote.h"
     30 #include "task/TaskCase.h"
     31 
     32 int AudioHardware::mHwId = -1;
     33 
     34 int AudioHardware::detectAudioHw()
     35 {
     36     android::String8 script("test_description/conf/detect_usb_audio.py");
     37     android::String8 param("MobilePre");
     38     android::String8 resultStr;
     39     if (!SimpleScriptExec::runScript(script, param, resultStr)) {
     40         LOGE("cannot run script");
     41         return -1;
     42     }
     43 
     44     android::String8 match("[ \t]+([A-Za-z0-9_]+)[ \t]+([0-9]+)");
     45     const int nmatch = 3;
     46     regmatch_t pmatch[nmatch];
     47     if (!SimpleScriptExec::checkIfPassed(resultStr, match, nmatch, pmatch)) {
     48         LOGE("result not correct %s", resultStr.string());
     49         return -1;
     50     }
     51     LOGV("pmatch 0: %d, %d  1:%d, %d  2:%d, %d",
     52         pmatch[0].rm_so, pmatch[0].rm_eo,
     53         pmatch[1].rm_so, pmatch[1].rm_eo,
     54         pmatch[2].rm_so, pmatch[2].rm_eo);
     55 
     56     if (pmatch[1].rm_so == -1) {
     57         return -1;
     58     }
     59     if (pmatch[2].rm_so == -1) {
     60         return -1;
     61     }
     62     android::String8 product = StringUtil::substr(resultStr, pmatch[1].rm_so,
     63             pmatch[1].rm_eo - pmatch[1].rm_so);
     64     LOGI("Audio device %s found", product.string());
     65     android::String8 cardNumber = StringUtil::substr(resultStr, pmatch[2].rm_so,
     66             pmatch[2].rm_eo - pmatch[2].rm_so);
     67     int cardN = atoi(cardNumber.string());
     68     LOGI("Card number : %d", cardN);
     69     return cardN;
     70 }
     71 
     72 android::sp<AudioHardware> AudioHardware::createAudioHw(bool local, bool playback,
     73         TaskCase* testCase)
     74 {
     75     android::sp<AudioHardware> hw;
     76     if (local) {
     77         if (mHwId < 0) {
     78             mHwId = detectAudioHw();
     79         }
     80         if (mHwId < 0) {
     81             return NULL;
     82         }
     83         if (playback) {
     84             hw = new AudioPlaybackLocal(mHwId);
     85         } else {
     86             hw = new AudioRecordingLocal(mHwId);
     87         }
     88     } else {
     89         if (testCase != NULL) {
     90             if (playback) {
     91                 hw = new AudioRemotePlayback(testCase->getRemoteAudio());
     92             } else {
     93                 hw = new AudioRemoteRecording(testCase->getRemoteAudio());
     94             }
     95         }
     96     }
     97     return hw;
     98 }
     99 
    100 AudioHardware::~AudioHardware()
    101 {
    102 
    103 }
    104 
    105 bool AudioHardware::startPlaybackOrRecordById(const android::String8& id, TaskCase* testCase)
    106 {
    107     if (testCase == NULL) { // default implementation only handles local buffer.
    108         return false;
    109     }
    110     android::sp<Buffer> buffer = testCase->findBuffer(id);
    111     if (buffer.get() == NULL) {
    112         return false;
    113     }
    114     return startPlaybackOrRecord(buffer);
    115 }
    116