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
detectAudioHw()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
createAudioHw(bool local,bool playback,TaskCase * testCase)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
~AudioHardware()104 AudioHardware::~AudioHardware()
105 {
106
107 }
108
startPlaybackOrRecordById(const android::String8 & id,TaskCase * testCase)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