/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ #include <sys/types.h> #include <regex.h> #include <stdlib.h> #include <tinyalsa/asoundlib.h> #include "Log.h" #include "StringUtil.h" #include "SimpleScriptExec.h" #include "audio/AudioHardware.h" #include "audio/Buffer.h" #include "audio/AudioPlaybackLocal.h" #include "audio/AudioRecordingLocal.h" #include "audio/AudioRemote.h" #include "task/TaskCase.h" int AudioHardware::mHwId = -1; int AudioHardware::detectAudioHw() { android::String8 script("test_description/conf/detect_usb_audio.py"); /* This is the list of supported devices. MobilePre: M-Audio MobilePre Track: M-Audio FastTrack */ android::String8 param("MobilePre Track"); android::String8 resultStr; if (!SimpleScriptExec::runScript(script, param, resultStr)) { LOGE("cannot run script"); return -1; } android::String8 match("[ \t]+([A-Za-z0-9_]+)[ \t]+([0-9]+)"); const int nmatch = 3; regmatch_t pmatch[nmatch]; if (!SimpleScriptExec::checkIfPassed(resultStr, match, nmatch, pmatch)) { LOGE("result not correct %s", resultStr.string()); return -1; } LOGV("pmatch 0: %d, %d 1:%d, %d 2:%d, %d", pmatch[0].rm_so, pmatch[0].rm_eo, pmatch[1].rm_so, pmatch[1].rm_eo, pmatch[2].rm_so, pmatch[2].rm_eo); if (pmatch[1].rm_so == -1) { return -1; } if (pmatch[2].rm_so == -1) { return -1; } android::String8 product = StringUtil::substr(resultStr, pmatch[1].rm_so, pmatch[1].rm_eo - pmatch[1].rm_so); LOGI("Audio device %s found", product.string()); android::String8 cardNumber = StringUtil::substr(resultStr, pmatch[2].rm_so, pmatch[2].rm_eo - pmatch[2].rm_so); int cardN = atoi(cardNumber.string()); LOGI("Card number : %d", cardN); return cardN; } android::sp<AudioHardware> AudioHardware::createAudioHw(bool local, bool playback, TaskCase* testCase) { android::sp<AudioHardware> hw; if (local) { if (mHwId < 0) { mHwId = detectAudioHw(); } if (mHwId < 0) { return NULL; } if (playback) { hw = new AudioPlaybackLocal(mHwId); } else { hw = new AudioRecordingLocal(mHwId); } } else { if (testCase != NULL) { if (playback) { hw = new AudioRemotePlayback(testCase->getRemoteAudio()); } else { hw = new AudioRemoteRecording(testCase->getRemoteAudio()); } } } return hw; } AudioHardware::~AudioHardware() { } bool AudioHardware::startPlaybackOrRecordById(const android::String8& id, TaskCase* testCase) { if (testCase == NULL) { // default implementation only handles local buffer. return false; } android::sp<Buffer> buffer = testCase->findBuffer(id); if (buffer.get() == NULL) { return false; } return startPlaybackOrRecord(buffer); }