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
17#include <stdlib.h>
18
19#include "Log.h"
20#include "audio/AudioHardware.h"
21#include "task/TaskCase.h"
22#include "task/TaskInput.h"
23
24TaskInput::TaskInput()
25    : TaskAsync(TaskGeneric::ETaskInput),
26      mRecordingTimeInMs(0)
27{
28
29}
30
31TaskInput::~TaskInput()
32{
33
34}
35
36bool TaskInput::parseAttribute(const android::String8& name, const android::String8& value)
37{
38    if (strcmp(name, "time") == 0) {
39        mRecordingTimeInMs = atoi(value);
40        if (mRecordingTimeInMs < 0) {
41            LOGE("TaskInput::parseAttribute invalid recording time %d", mRecordingTimeInMs);
42            return false;
43        }
44        return true;
45    }
46    return TaskAsync::parseAttribute(name, value);
47}
48
49TaskGeneric::ExecutionResult TaskInput::start()
50{
51    bool localDevice = (mDeviceType == TaskAsync::EDeviceHost);
52    android::sp<AudioHardware> hw = AudioHardware::createAudioHw(localDevice, false,
53            getTestCase());
54    if (hw.get() == NULL) {
55        LOGE("createAudioHw failed");
56        return TaskGeneric::EResultError;
57    }
58    // TODO support stereo mode in local later
59    //     for now, local is captured in stereo, and it is stored to mono
60    //     by keeping only channel 1.
61    // local : stereo only, remote : mono only
62    size_t bufferSize = mRecordingTimeInMs * AudioHardware::ESampleRate_44100 / 1000 *
63            (localDevice ? 4 : 2);
64    android::sp<Buffer> buffer(new Buffer(bufferSize, bufferSize, localDevice));
65    if (buffer.get() == NULL) {
66        LOGE("buffer alloc failed");
67        return TaskGeneric::EResultError;
68    }
69    if (!hw->prepare(AudioHardware::ESampleRate_44100, mVolume, mMode)) {
70        LOGE("prepare failed");
71        return TaskGeneric::EResultError;
72    }
73    if (!hw->startPlaybackOrRecord(buffer)) {
74        LOGE("record failed");
75        return TaskGeneric::EResultError;
76    }
77    // now store sp
78    mHw = hw;
79    mBuffer = buffer;
80    return TaskGeneric::EResultOK;
81}
82
83TaskGeneric::ExecutionResult TaskInput::complete()
84{
85    bool result = mHw->waitForCompletion();
86    mHw->stopPlaybackOrRecord();
87    mHw.clear();
88    if (!result) {
89        LOGE("waitForComletion failed");
90        return TaskGeneric::EResultError;
91    }
92    // TODO: need to keep stereo for local if in stereo mode
93    // For now, convert to mono if it is stereo
94    if (mBuffer->isStereo()) {
95        mBuffer->changeToMono(Buffer::EKeepCh0);
96    }
97    if (!getTestCase()->registerBuffer(mId, mBuffer)) {
98        if (!getTestCase()->updateBuffer(mId, mBuffer)) {
99            LOGE("cannot register/update buffer %s", mId.string());
100            return TaskGeneric::EResultError;
101        }
102    }
103    return TaskGeneric::EResultOK;
104}
105
106
107