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