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     /* This is the list of supported devices.
     38        MobilePre: M-Audio MobilePre
     39        Track: M-Audio FastTrack
     40      */
     41     android::String8 param("MobilePre Track");
     42     android::String8 resultStr;
     43     if (!SimpleScriptExec::runScript(script, param, resultStr)) {
     44         LOGE("cannot run script");
     45         return -1;
     46     }
     47 
     48     android::String8 match("[ \t]+([A-Za-z0-9_]+)[ \t]+([0-9]+)");
     49     const int nmatch = 3;
     50     regmatch_t pmatch[nmatch];
     51     if (!SimpleScriptExec::checkIfPassed(resultStr, match, nmatch, pmatch)) {
     52         LOGE("result not correct %s", resultStr.string());
     53         return -1;
     54     }
     55     LOGV("pmatch 0: %d, %d  1:%d, %d  2:%d, %d",
     56         pmatch[0].rm_so, pmatch[0].rm_eo,
     57         pmatch[1].rm_so, pmatch[1].rm_eo,
     58         pmatch[2].rm_so, pmatch[2].rm_eo);
     59 
     60     if (pmatch[1].rm_so == -1) {
     61         return -1;
     62     }
     63     if (pmatch[2].rm_so == -1) {
     64         return -1;
     65     }
     66     android::String8 product = StringUtil::substr(resultStr, pmatch[1].rm_so,
     67             pmatch[1].rm_eo - pmatch[1].rm_so);
     68     LOGI("Audio device %s found", product.string());
     69     android::String8 cardNumber = StringUtil::substr(resultStr, pmatch[2].rm_so,
     70             pmatch[2].rm_eo - pmatch[2].rm_so);
     71     int cardN = atoi(cardNumber.string());
     72     LOGI("Card number : %d", cardN);
     73     return cardN;
     74 }
     75 
     76 android::sp<AudioHardware> AudioHardware::createAudioHw(bool local, bool playback,
     77         TaskCase* testCase)
     78 {
     79     android::sp<AudioHardware> hw;
     80     if (local) {
     81         if (mHwId < 0) {
     82             mHwId = detectAudioHw();
     83         }
     84         if (mHwId < 0) {
     85             return NULL;
     86         }
     87         if (playback) {
     88             hw = new AudioPlaybackLocal(mHwId);
     89         } else {
     90             hw = new AudioRecordingLocal(mHwId);
     91         }
     92     } else {
     93         if (testCase != NULL) {
     94             if (playback) {
     95                 hw = new AudioRemotePlayback(testCase->getRemoteAudio());
     96             } else {
     97                 hw = new AudioRemoteRecording(testCase->getRemoteAudio());
     98             }
     99         }
    100     }
    101     return hw;
    102 }
    103 
    104 AudioHardware::~AudioHardware()
    105 {
    106 
    107 }
    108 
    109 bool AudioHardware::startPlaybackOrRecordById(const android::String8& id, TaskCase* testCase)
    110 {
    111     if (testCase == NULL) { // default implementation only handles local buffer.
    112         return false;
    113     }
    114     android::sp<Buffer> buffer = testCase->findBuffer(id);
    115     if (buffer.get() == NULL) {
    116         return false;
    117     }
    118     return startPlaybackOrRecord(buffer);
    119 }
    120