/*
* 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);
}