1*79330504STreehugger Robot /* //device/servers/AudioFlinger/AudioDumpInterface.cpp
2*79330504STreehugger Robot **
3*79330504STreehugger Robot ** Copyright 2008, The Android Open Source Project
4*79330504STreehugger Robot **
5*79330504STreehugger Robot ** Licensed under the Apache License, Version 2.0 (the "License");
6*79330504STreehugger Robot ** you may not use this file except in compliance with the License.
7*79330504STreehugger Robot ** You may obtain a copy of the License at
8*79330504STreehugger Robot **
9*79330504STreehugger Robot ** http://www.apache.org/licenses/LICENSE-2.0
10*79330504STreehugger Robot **
11*79330504STreehugger Robot ** Unless required by applicable law or agreed to in writing, software
12*79330504STreehugger Robot ** distributed under the License is distributed on an "AS IS" BASIS,
13*79330504STreehugger Robot ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*79330504STreehugger Robot ** See the License for the specific language governing permissions and
15*79330504STreehugger Robot ** limitations under the License.
16*79330504STreehugger Robot */
17*79330504STreehugger Robot
18*79330504STreehugger Robot #define LOG_TAG "AudioFlingerDump"
19*79330504STreehugger Robot //#define LOG_NDEBUG 0
20*79330504STreehugger Robot
21*79330504STreehugger Robot #include <stdint.h>
22*79330504STreehugger Robot #include <sys/types.h>
23*79330504STreehugger Robot #include <utils/Log.h>
24*79330504STreehugger Robot
25*79330504STreehugger Robot #include <stdlib.h>
26*79330504STreehugger Robot #include <unistd.h>
27*79330504STreehugger Robot
28*79330504STreehugger Robot #include "AudioDumpInterface.h"
29*79330504STreehugger Robot
30*79330504STreehugger Robot namespace android {
31*79330504STreehugger Robot
32*79330504STreehugger Robot // ----------------------------------------------------------------------------
33*79330504STreehugger Robot
AudioDumpInterface(AudioHardwareInterface * hw)34*79330504STreehugger Robot AudioDumpInterface::AudioDumpInterface(AudioHardwareInterface* hw)
35*79330504STreehugger Robot : mPolicyCommands(String8("")), mFileName(String8(""))
36*79330504STreehugger Robot {
37*79330504STreehugger Robot if(hw == 0) {
38*79330504STreehugger Robot ALOGE("Dump construct hw = 0");
39*79330504STreehugger Robot }
40*79330504STreehugger Robot mFinalInterface = hw;
41*79330504STreehugger Robot ALOGV("Constructor %p, mFinalInterface %p", this, mFinalInterface);
42*79330504STreehugger Robot }
43*79330504STreehugger Robot
44*79330504STreehugger Robot
~AudioDumpInterface()45*79330504STreehugger Robot AudioDumpInterface::~AudioDumpInterface()
46*79330504STreehugger Robot {
47*79330504STreehugger Robot for (size_t i = 0; i < mOutputs.size(); i++) {
48*79330504STreehugger Robot closeOutputStream((AudioStreamOut *)mOutputs[i]);
49*79330504STreehugger Robot }
50*79330504STreehugger Robot
51*79330504STreehugger Robot for (size_t i = 0; i < mInputs.size(); i++) {
52*79330504STreehugger Robot closeInputStream((AudioStreamIn *)mInputs[i]);
53*79330504STreehugger Robot }
54*79330504STreehugger Robot
55*79330504STreehugger Robot if(mFinalInterface) delete mFinalInterface;
56*79330504STreehugger Robot }
57*79330504STreehugger Robot
58*79330504STreehugger Robot
openOutputStream(uint32_t devices,int * format,uint32_t * channels,uint32_t * sampleRate,status_t * status)59*79330504STreehugger Robot AudioStreamOut* AudioDumpInterface::openOutputStream(
60*79330504STreehugger Robot uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
61*79330504STreehugger Robot {
62*79330504STreehugger Robot AudioStreamOut* outFinal = NULL;
63*79330504STreehugger Robot int lFormat = AudioSystem::PCM_16_BIT;
64*79330504STreehugger Robot uint32_t lChannels = AudioSystem::CHANNEL_OUT_STEREO;
65*79330504STreehugger Robot uint32_t lRate = 44100;
66*79330504STreehugger Robot
67*79330504STreehugger Robot
68*79330504STreehugger Robot outFinal = mFinalInterface->openOutputStream(devices, format, channels, sampleRate, status);
69*79330504STreehugger Robot if (outFinal != 0) {
70*79330504STreehugger Robot lFormat = outFinal->format();
71*79330504STreehugger Robot lChannels = outFinal->channels();
72*79330504STreehugger Robot lRate = outFinal->sampleRate();
73*79330504STreehugger Robot } else {
74*79330504STreehugger Robot if (format != 0) {
75*79330504STreehugger Robot if (*format != 0) {
76*79330504STreehugger Robot lFormat = *format;
77*79330504STreehugger Robot } else {
78*79330504STreehugger Robot *format = lFormat;
79*79330504STreehugger Robot }
80*79330504STreehugger Robot }
81*79330504STreehugger Robot if (channels != 0) {
82*79330504STreehugger Robot if (*channels != 0) {
83*79330504STreehugger Robot lChannels = *channels;
84*79330504STreehugger Robot } else {
85*79330504STreehugger Robot *channels = lChannels;
86*79330504STreehugger Robot }
87*79330504STreehugger Robot }
88*79330504STreehugger Robot if (sampleRate != 0) {
89*79330504STreehugger Robot if (*sampleRate != 0) {
90*79330504STreehugger Robot lRate = *sampleRate;
91*79330504STreehugger Robot } else {
92*79330504STreehugger Robot *sampleRate = lRate;
93*79330504STreehugger Robot }
94*79330504STreehugger Robot }
95*79330504STreehugger Robot if (status) *status = NO_ERROR;
96*79330504STreehugger Robot }
97*79330504STreehugger Robot ALOGV("openOutputStream(), outFinal %p", outFinal);
98*79330504STreehugger Robot
99*79330504STreehugger Robot AudioStreamOutDump *dumOutput = new AudioStreamOutDump(this, mOutputs.size(), outFinal,
100*79330504STreehugger Robot devices, lFormat, lChannels, lRate);
101*79330504STreehugger Robot mOutputs.add(dumOutput);
102*79330504STreehugger Robot
103*79330504STreehugger Robot return dumOutput;
104*79330504STreehugger Robot }
105*79330504STreehugger Robot
closeOutputStream(AudioStreamOut * out)106*79330504STreehugger Robot void AudioDumpInterface::closeOutputStream(AudioStreamOut* out)
107*79330504STreehugger Robot {
108*79330504STreehugger Robot AudioStreamOutDump *dumpOut = (AudioStreamOutDump *)out;
109*79330504STreehugger Robot
110*79330504STreehugger Robot if (mOutputs.indexOf(dumpOut) < 0) {
111*79330504STreehugger Robot ALOGW("Attempt to close invalid output stream");
112*79330504STreehugger Robot return;
113*79330504STreehugger Robot }
114*79330504STreehugger Robot
115*79330504STreehugger Robot ALOGV("closeOutputStream() output %p", out);
116*79330504STreehugger Robot
117*79330504STreehugger Robot dumpOut->standby();
118*79330504STreehugger Robot if (dumpOut->finalStream() != NULL) {
119*79330504STreehugger Robot mFinalInterface->closeOutputStream(dumpOut->finalStream());
120*79330504STreehugger Robot }
121*79330504STreehugger Robot
122*79330504STreehugger Robot mOutputs.remove(dumpOut);
123*79330504STreehugger Robot delete dumpOut;
124*79330504STreehugger Robot }
125*79330504STreehugger Robot
openInputStream(uint32_t devices,int * format,uint32_t * channels,uint32_t * sampleRate,status_t * status,AudioSystem::audio_in_acoustics acoustics)126*79330504STreehugger Robot AudioStreamIn* AudioDumpInterface::openInputStream(uint32_t devices, int *format, uint32_t *channels,
127*79330504STreehugger Robot uint32_t *sampleRate, status_t *status, AudioSystem::audio_in_acoustics acoustics)
128*79330504STreehugger Robot {
129*79330504STreehugger Robot AudioStreamIn* inFinal = NULL;
130*79330504STreehugger Robot int lFormat = AudioSystem::PCM_16_BIT;
131*79330504STreehugger Robot uint32_t lChannels = AudioSystem::CHANNEL_IN_MONO;
132*79330504STreehugger Robot uint32_t lRate = 8000;
133*79330504STreehugger Robot
134*79330504STreehugger Robot inFinal = mFinalInterface->openInputStream(devices, format, channels, sampleRate, status, acoustics);
135*79330504STreehugger Robot if (inFinal != 0) {
136*79330504STreehugger Robot lFormat = inFinal->format();
137*79330504STreehugger Robot lChannels = inFinal->channels();
138*79330504STreehugger Robot lRate = inFinal->sampleRate();
139*79330504STreehugger Robot } else {
140*79330504STreehugger Robot if (format != 0) {
141*79330504STreehugger Robot if (*format != 0) {
142*79330504STreehugger Robot lFormat = *format;
143*79330504STreehugger Robot } else {
144*79330504STreehugger Robot *format = lFormat;
145*79330504STreehugger Robot }
146*79330504STreehugger Robot }
147*79330504STreehugger Robot if (channels != 0) {
148*79330504STreehugger Robot if (*channels != 0) {
149*79330504STreehugger Robot lChannels = *channels;
150*79330504STreehugger Robot } else {
151*79330504STreehugger Robot *channels = lChannels;
152*79330504STreehugger Robot }
153*79330504STreehugger Robot }
154*79330504STreehugger Robot if (sampleRate != 0) {
155*79330504STreehugger Robot if (*sampleRate != 0) {
156*79330504STreehugger Robot lRate = *sampleRate;
157*79330504STreehugger Robot } else {
158*79330504STreehugger Robot *sampleRate = lRate;
159*79330504STreehugger Robot }
160*79330504STreehugger Robot }
161*79330504STreehugger Robot if (status) *status = NO_ERROR;
162*79330504STreehugger Robot }
163*79330504STreehugger Robot ALOGV("openInputStream(), inFinal %p", inFinal);
164*79330504STreehugger Robot
165*79330504STreehugger Robot AudioStreamInDump *dumInput = new AudioStreamInDump(this, mInputs.size(), inFinal,
166*79330504STreehugger Robot devices, lFormat, lChannels, lRate);
167*79330504STreehugger Robot mInputs.add(dumInput);
168*79330504STreehugger Robot
169*79330504STreehugger Robot return dumInput;
170*79330504STreehugger Robot }
closeInputStream(AudioStreamIn * in)171*79330504STreehugger Robot void AudioDumpInterface::closeInputStream(AudioStreamIn* in)
172*79330504STreehugger Robot {
173*79330504STreehugger Robot AudioStreamInDump *dumpIn = (AudioStreamInDump *)in;
174*79330504STreehugger Robot
175*79330504STreehugger Robot if (mInputs.indexOf(dumpIn) < 0) {
176*79330504STreehugger Robot ALOGW("Attempt to close invalid input stream");
177*79330504STreehugger Robot return;
178*79330504STreehugger Robot }
179*79330504STreehugger Robot dumpIn->standby();
180*79330504STreehugger Robot if (dumpIn->finalStream() != NULL) {
181*79330504STreehugger Robot mFinalInterface->closeInputStream(dumpIn->finalStream());
182*79330504STreehugger Robot }
183*79330504STreehugger Robot
184*79330504STreehugger Robot mInputs.remove(dumpIn);
185*79330504STreehugger Robot delete dumpIn;
186*79330504STreehugger Robot }
187*79330504STreehugger Robot
188*79330504STreehugger Robot
setParameters(const String8 & keyValuePairs)189*79330504STreehugger Robot status_t AudioDumpInterface::setParameters(const String8& keyValuePairs)
190*79330504STreehugger Robot {
191*79330504STreehugger Robot AudioParameter param = AudioParameter(keyValuePairs);
192*79330504STreehugger Robot String8 value;
193*79330504STreehugger Robot int valueInt;
194*79330504STreehugger Robot ALOGV("setParameters %s", keyValuePairs.string());
195*79330504STreehugger Robot
196*79330504STreehugger Robot if (param.get(String8("test_cmd_file_name"), value) == NO_ERROR) {
197*79330504STreehugger Robot mFileName = value;
198*79330504STreehugger Robot param.remove(String8("test_cmd_file_name"));
199*79330504STreehugger Robot }
200*79330504STreehugger Robot if (param.get(String8("test_cmd_policy"), value) == NO_ERROR) {
201*79330504STreehugger Robot Mutex::Autolock _l(mLock);
202*79330504STreehugger Robot param.remove(String8("test_cmd_policy"));
203*79330504STreehugger Robot mPolicyCommands = param.toString();
204*79330504STreehugger Robot ALOGV("test_cmd_policy command %s written", mPolicyCommands.string());
205*79330504STreehugger Robot return NO_ERROR;
206*79330504STreehugger Robot }
207*79330504STreehugger Robot
208*79330504STreehugger Robot if (mFinalInterface != 0 ) return mFinalInterface->setParameters(keyValuePairs);
209*79330504STreehugger Robot return NO_ERROR;
210*79330504STreehugger Robot }
211*79330504STreehugger Robot
getParameters(const String8 & keys)212*79330504STreehugger Robot String8 AudioDumpInterface::getParameters(const String8& keys)
213*79330504STreehugger Robot {
214*79330504STreehugger Robot AudioParameter param = AudioParameter(keys);
215*79330504STreehugger Robot AudioParameter response;
216*79330504STreehugger Robot String8 value;
217*79330504STreehugger Robot
218*79330504STreehugger Robot // ALOGV("getParameters %s", keys.string());
219*79330504STreehugger Robot if (param.get(String8("test_cmd_policy"), value) == NO_ERROR) {
220*79330504STreehugger Robot Mutex::Autolock _l(mLock);
221*79330504STreehugger Robot if (mPolicyCommands.length() != 0) {
222*79330504STreehugger Robot response = AudioParameter(mPolicyCommands);
223*79330504STreehugger Robot response.addInt(String8("test_cmd_policy"), 1);
224*79330504STreehugger Robot } else {
225*79330504STreehugger Robot response.addInt(String8("test_cmd_policy"), 0);
226*79330504STreehugger Robot }
227*79330504STreehugger Robot param.remove(String8("test_cmd_policy"));
228*79330504STreehugger Robot // ALOGV("test_cmd_policy command %s read", mPolicyCommands.string());
229*79330504STreehugger Robot }
230*79330504STreehugger Robot
231*79330504STreehugger Robot if (param.get(String8("test_cmd_file_name"), value) == NO_ERROR) {
232*79330504STreehugger Robot response.add(String8("test_cmd_file_name"), mFileName);
233*79330504STreehugger Robot param.remove(String8("test_cmd_file_name"));
234*79330504STreehugger Robot }
235*79330504STreehugger Robot
236*79330504STreehugger Robot String8 keyValuePairs = response.toString();
237*79330504STreehugger Robot
238*79330504STreehugger Robot if (param.size() && mFinalInterface != 0 ) {
239*79330504STreehugger Robot keyValuePairs += ";";
240*79330504STreehugger Robot keyValuePairs += mFinalInterface->getParameters(param.toString());
241*79330504STreehugger Robot }
242*79330504STreehugger Robot
243*79330504STreehugger Robot return keyValuePairs;
244*79330504STreehugger Robot }
245*79330504STreehugger Robot
setMode(int mode)246*79330504STreehugger Robot status_t AudioDumpInterface::setMode(int mode)
247*79330504STreehugger Robot {
248*79330504STreehugger Robot return mFinalInterface->setMode(mode);
249*79330504STreehugger Robot }
250*79330504STreehugger Robot
getInputBufferSize(uint32_t sampleRate,int format,int channelCount)251*79330504STreehugger Robot size_t AudioDumpInterface::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
252*79330504STreehugger Robot {
253*79330504STreehugger Robot return mFinalInterface->getInputBufferSize(sampleRate, format, channelCount);
254*79330504STreehugger Robot }
255*79330504STreehugger Robot
256*79330504STreehugger Robot // ----------------------------------------------------------------------------
257*79330504STreehugger Robot
AudioStreamOutDump(AudioDumpInterface * interface,int id,AudioStreamOut * finalStream,uint32_t devices,int format,uint32_t channels,uint32_t sampleRate)258*79330504STreehugger Robot AudioStreamOutDump::AudioStreamOutDump(AudioDumpInterface *interface,
259*79330504STreehugger Robot int id,
260*79330504STreehugger Robot AudioStreamOut* finalStream,
261*79330504STreehugger Robot uint32_t devices,
262*79330504STreehugger Robot int format,
263*79330504STreehugger Robot uint32_t channels,
264*79330504STreehugger Robot uint32_t sampleRate)
265*79330504STreehugger Robot : mInterface(interface), mId(id),
266*79330504STreehugger Robot mSampleRate(sampleRate), mFormat(format), mChannels(channels), mLatency(0), mDevice(devices),
267*79330504STreehugger Robot mBufferSize(1024), mFinalStream(finalStream), mFile(0), mFileCount(0)
268*79330504STreehugger Robot {
269*79330504STreehugger Robot ALOGV("AudioStreamOutDump Constructor %p, mInterface %p, mFinalStream %p", this, mInterface, mFinalStream);
270*79330504STreehugger Robot }
271*79330504STreehugger Robot
272*79330504STreehugger Robot
~AudioStreamOutDump()273*79330504STreehugger Robot AudioStreamOutDump::~AudioStreamOutDump()
274*79330504STreehugger Robot {
275*79330504STreehugger Robot ALOGV("AudioStreamOutDump destructor");
276*79330504STreehugger Robot Close();
277*79330504STreehugger Robot }
278*79330504STreehugger Robot
write(const void * buffer,size_t bytes)279*79330504STreehugger Robot ssize_t AudioStreamOutDump::write(const void* buffer, size_t bytes)
280*79330504STreehugger Robot {
281*79330504STreehugger Robot ssize_t ret;
282*79330504STreehugger Robot
283*79330504STreehugger Robot if (mFinalStream) {
284*79330504STreehugger Robot ret = mFinalStream->write(buffer, bytes);
285*79330504STreehugger Robot } else {
286*79330504STreehugger Robot usleep((((bytes * 1000) / frameSize()) / sampleRate()) * 1000);
287*79330504STreehugger Robot ret = bytes;
288*79330504STreehugger Robot }
289*79330504STreehugger Robot if(!mFile) {
290*79330504STreehugger Robot if (mInterface->fileName() != "") {
291*79330504STreehugger Robot char name[255];
292*79330504STreehugger Robot sprintf(name, "%s_out_%d_%d.pcm", mInterface->fileName().string(), mId, ++mFileCount);
293*79330504STreehugger Robot mFile = fopen(name, "wb");
294*79330504STreehugger Robot ALOGV("Opening dump file %s, fh %p", name, mFile);
295*79330504STreehugger Robot }
296*79330504STreehugger Robot }
297*79330504STreehugger Robot if (mFile) {
298*79330504STreehugger Robot fwrite(buffer, bytes, 1, mFile);
299*79330504STreehugger Robot }
300*79330504STreehugger Robot return ret;
301*79330504STreehugger Robot }
302*79330504STreehugger Robot
standby()303*79330504STreehugger Robot status_t AudioStreamOutDump::standby()
304*79330504STreehugger Robot {
305*79330504STreehugger Robot ALOGV("AudioStreamOutDump standby(), mFile %p, mFinalStream %p", mFile, mFinalStream);
306*79330504STreehugger Robot
307*79330504STreehugger Robot Close();
308*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->standby();
309*79330504STreehugger Robot return NO_ERROR;
310*79330504STreehugger Robot }
311*79330504STreehugger Robot
sampleRate() const312*79330504STreehugger Robot uint32_t AudioStreamOutDump::sampleRate() const
313*79330504STreehugger Robot {
314*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->sampleRate();
315*79330504STreehugger Robot return mSampleRate;
316*79330504STreehugger Robot }
317*79330504STreehugger Robot
bufferSize() const318*79330504STreehugger Robot size_t AudioStreamOutDump::bufferSize() const
319*79330504STreehugger Robot {
320*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->bufferSize();
321*79330504STreehugger Robot return mBufferSize;
322*79330504STreehugger Robot }
323*79330504STreehugger Robot
channels() const324*79330504STreehugger Robot uint32_t AudioStreamOutDump::channels() const
325*79330504STreehugger Robot {
326*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->channels();
327*79330504STreehugger Robot return mChannels;
328*79330504STreehugger Robot }
format() const329*79330504STreehugger Robot int AudioStreamOutDump::format() const
330*79330504STreehugger Robot {
331*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->format();
332*79330504STreehugger Robot return mFormat;
333*79330504STreehugger Robot }
latency() const334*79330504STreehugger Robot uint32_t AudioStreamOutDump::latency() const
335*79330504STreehugger Robot {
336*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->latency();
337*79330504STreehugger Robot return 0;
338*79330504STreehugger Robot }
setVolume(float left,float right)339*79330504STreehugger Robot status_t AudioStreamOutDump::setVolume(float left, float right)
340*79330504STreehugger Robot {
341*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->setVolume(left, right);
342*79330504STreehugger Robot return NO_ERROR;
343*79330504STreehugger Robot }
setParameters(const String8 & keyValuePairs)344*79330504STreehugger Robot status_t AudioStreamOutDump::setParameters(const String8& keyValuePairs)
345*79330504STreehugger Robot {
346*79330504STreehugger Robot ALOGV("AudioStreamOutDump::setParameters %s", keyValuePairs.string());
347*79330504STreehugger Robot
348*79330504STreehugger Robot if (mFinalStream != 0 ) {
349*79330504STreehugger Robot return mFinalStream->setParameters(keyValuePairs);
350*79330504STreehugger Robot }
351*79330504STreehugger Robot
352*79330504STreehugger Robot AudioParameter param = AudioParameter(keyValuePairs);
353*79330504STreehugger Robot String8 value;
354*79330504STreehugger Robot int valueInt;
355*79330504STreehugger Robot status_t status = NO_ERROR;
356*79330504STreehugger Robot
357*79330504STreehugger Robot if (param.getInt(String8("set_id"), valueInt) == NO_ERROR) {
358*79330504STreehugger Robot mId = valueInt;
359*79330504STreehugger Robot }
360*79330504STreehugger Robot
361*79330504STreehugger Robot if (param.getInt(String8("format"), valueInt) == NO_ERROR) {
362*79330504STreehugger Robot if (mFile == 0) {
363*79330504STreehugger Robot mFormat = valueInt;
364*79330504STreehugger Robot } else {
365*79330504STreehugger Robot status = INVALID_OPERATION;
366*79330504STreehugger Robot }
367*79330504STreehugger Robot }
368*79330504STreehugger Robot if (param.getInt(String8("channels"), valueInt) == NO_ERROR) {
369*79330504STreehugger Robot if (valueInt == AudioSystem::CHANNEL_OUT_STEREO || valueInt == AudioSystem::CHANNEL_OUT_MONO) {
370*79330504STreehugger Robot mChannels = valueInt;
371*79330504STreehugger Robot } else {
372*79330504STreehugger Robot status = BAD_VALUE;
373*79330504STreehugger Robot }
374*79330504STreehugger Robot }
375*79330504STreehugger Robot if (param.getInt(String8("sampling_rate"), valueInt) == NO_ERROR) {
376*79330504STreehugger Robot if (valueInt > 0 && valueInt <= 48000) {
377*79330504STreehugger Robot if (mFile == 0) {
378*79330504STreehugger Robot mSampleRate = valueInt;
379*79330504STreehugger Robot } else {
380*79330504STreehugger Robot status = INVALID_OPERATION;
381*79330504STreehugger Robot }
382*79330504STreehugger Robot } else {
383*79330504STreehugger Robot status = BAD_VALUE;
384*79330504STreehugger Robot }
385*79330504STreehugger Robot }
386*79330504STreehugger Robot return status;
387*79330504STreehugger Robot }
388*79330504STreehugger Robot
getParameters(const String8 & keys)389*79330504STreehugger Robot String8 AudioStreamOutDump::getParameters(const String8& keys)
390*79330504STreehugger Robot {
391*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->getParameters(keys);
392*79330504STreehugger Robot
393*79330504STreehugger Robot AudioParameter param = AudioParameter(keys);
394*79330504STreehugger Robot return param.toString();
395*79330504STreehugger Robot }
396*79330504STreehugger Robot
dump(int fd,const Vector<String16> & args)397*79330504STreehugger Robot status_t AudioStreamOutDump::dump(int fd, const Vector<String16>& args)
398*79330504STreehugger Robot {
399*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->dump(fd, args);
400*79330504STreehugger Robot return NO_ERROR;
401*79330504STreehugger Robot }
402*79330504STreehugger Robot
Close()403*79330504STreehugger Robot void AudioStreamOutDump::Close()
404*79330504STreehugger Robot {
405*79330504STreehugger Robot if(mFile) {
406*79330504STreehugger Robot fclose(mFile);
407*79330504STreehugger Robot mFile = 0;
408*79330504STreehugger Robot }
409*79330504STreehugger Robot }
410*79330504STreehugger Robot
getRenderPosition(uint32_t * dspFrames)411*79330504STreehugger Robot status_t AudioStreamOutDump::getRenderPosition(uint32_t *dspFrames)
412*79330504STreehugger Robot {
413*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->getRenderPosition(dspFrames);
414*79330504STreehugger Robot return INVALID_OPERATION;
415*79330504STreehugger Robot }
416*79330504STreehugger Robot
417*79330504STreehugger Robot // ----------------------------------------------------------------------------
418*79330504STreehugger Robot
AudioStreamInDump(AudioDumpInterface * interface,int id,AudioStreamIn * finalStream,uint32_t devices,int format,uint32_t channels,uint32_t sampleRate)419*79330504STreehugger Robot AudioStreamInDump::AudioStreamInDump(AudioDumpInterface *interface,
420*79330504STreehugger Robot int id,
421*79330504STreehugger Robot AudioStreamIn* finalStream,
422*79330504STreehugger Robot uint32_t devices,
423*79330504STreehugger Robot int format,
424*79330504STreehugger Robot uint32_t channels,
425*79330504STreehugger Robot uint32_t sampleRate)
426*79330504STreehugger Robot : mInterface(interface), mId(id),
427*79330504STreehugger Robot mSampleRate(sampleRate), mFormat(format), mChannels(channels), mDevice(devices),
428*79330504STreehugger Robot mBufferSize(1024), mFinalStream(finalStream), mFile(0), mFileCount(0)
429*79330504STreehugger Robot {
430*79330504STreehugger Robot ALOGV("AudioStreamInDump Constructor %p, mInterface %p, mFinalStream %p", this, mInterface, mFinalStream);
431*79330504STreehugger Robot }
432*79330504STreehugger Robot
433*79330504STreehugger Robot
~AudioStreamInDump()434*79330504STreehugger Robot AudioStreamInDump::~AudioStreamInDump()
435*79330504STreehugger Robot {
436*79330504STreehugger Robot Close();
437*79330504STreehugger Robot }
438*79330504STreehugger Robot
read(void * buffer,ssize_t bytes)439*79330504STreehugger Robot ssize_t AudioStreamInDump::read(void* buffer, ssize_t bytes)
440*79330504STreehugger Robot {
441*79330504STreehugger Robot ssize_t ret;
442*79330504STreehugger Robot
443*79330504STreehugger Robot if (mFinalStream) {
444*79330504STreehugger Robot ret = mFinalStream->read(buffer, bytes);
445*79330504STreehugger Robot if(!mFile) {
446*79330504STreehugger Robot if (mInterface->fileName() != "") {
447*79330504STreehugger Robot char name[255];
448*79330504STreehugger Robot sprintf(name, "%s_in_%d_%d.pcm", mInterface->fileName().string(), mId, ++mFileCount);
449*79330504STreehugger Robot mFile = fopen(name, "wb");
450*79330504STreehugger Robot ALOGV("Opening input dump file %s, fh %p", name, mFile);
451*79330504STreehugger Robot }
452*79330504STreehugger Robot }
453*79330504STreehugger Robot if (mFile) {
454*79330504STreehugger Robot fwrite(buffer, bytes, 1, mFile);
455*79330504STreehugger Robot }
456*79330504STreehugger Robot } else {
457*79330504STreehugger Robot usleep((((bytes * 1000) / frameSize()) / sampleRate()) * 1000);
458*79330504STreehugger Robot ret = bytes;
459*79330504STreehugger Robot if(!mFile) {
460*79330504STreehugger Robot char name[255];
461*79330504STreehugger Robot strcpy(name, "/sdcard/music/sine440");
462*79330504STreehugger Robot if (channels() == AudioSystem::CHANNEL_IN_MONO) {
463*79330504STreehugger Robot strcat(name, "_mo");
464*79330504STreehugger Robot } else {
465*79330504STreehugger Robot strcat(name, "_st");
466*79330504STreehugger Robot }
467*79330504STreehugger Robot if (format() == AudioSystem::PCM_16_BIT) {
468*79330504STreehugger Robot strcat(name, "_16b");
469*79330504STreehugger Robot } else {
470*79330504STreehugger Robot strcat(name, "_8b");
471*79330504STreehugger Robot }
472*79330504STreehugger Robot if (sampleRate() < 16000) {
473*79330504STreehugger Robot strcat(name, "_8k");
474*79330504STreehugger Robot } else if (sampleRate() < 32000) {
475*79330504STreehugger Robot strcat(name, "_22k");
476*79330504STreehugger Robot } else if (sampleRate() < 48000) {
477*79330504STreehugger Robot strcat(name, "_44k");
478*79330504STreehugger Robot } else {
479*79330504STreehugger Robot strcat(name, "_48k");
480*79330504STreehugger Robot }
481*79330504STreehugger Robot strcat(name, ".wav");
482*79330504STreehugger Robot mFile = fopen(name, "rb");
483*79330504STreehugger Robot ALOGV("Opening input read file %s, fh %p", name, mFile);
484*79330504STreehugger Robot if (mFile) {
485*79330504STreehugger Robot fseek(mFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
486*79330504STreehugger Robot }
487*79330504STreehugger Robot }
488*79330504STreehugger Robot if (mFile) {
489*79330504STreehugger Robot ssize_t bytesRead = fread(buffer, bytes, 1, mFile);
490*79330504STreehugger Robot if (bytesRead >=0 && bytesRead < bytes) {
491*79330504STreehugger Robot fseek(mFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
492*79330504STreehugger Robot fread((uint8_t *)buffer+bytesRead, bytes-bytesRead, 1, mFile);
493*79330504STreehugger Robot }
494*79330504STreehugger Robot }
495*79330504STreehugger Robot }
496*79330504STreehugger Robot
497*79330504STreehugger Robot return ret;
498*79330504STreehugger Robot }
499*79330504STreehugger Robot
standby()500*79330504STreehugger Robot status_t AudioStreamInDump::standby()
501*79330504STreehugger Robot {
502*79330504STreehugger Robot ALOGV("AudioStreamInDump standby(), mFile %p, mFinalStream %p", mFile, mFinalStream);
503*79330504STreehugger Robot
504*79330504STreehugger Robot Close();
505*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->standby();
506*79330504STreehugger Robot return NO_ERROR;
507*79330504STreehugger Robot }
508*79330504STreehugger Robot
setGain(float gain)509*79330504STreehugger Robot status_t AudioStreamInDump::setGain(float gain)
510*79330504STreehugger Robot {
511*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->setGain(gain);
512*79330504STreehugger Robot return NO_ERROR;
513*79330504STreehugger Robot }
514*79330504STreehugger Robot
sampleRate() const515*79330504STreehugger Robot uint32_t AudioStreamInDump::sampleRate() const
516*79330504STreehugger Robot {
517*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->sampleRate();
518*79330504STreehugger Robot return mSampleRate;
519*79330504STreehugger Robot }
520*79330504STreehugger Robot
bufferSize() const521*79330504STreehugger Robot size_t AudioStreamInDump::bufferSize() const
522*79330504STreehugger Robot {
523*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->bufferSize();
524*79330504STreehugger Robot return mBufferSize;
525*79330504STreehugger Robot }
526*79330504STreehugger Robot
channels() const527*79330504STreehugger Robot uint32_t AudioStreamInDump::channels() const
528*79330504STreehugger Robot {
529*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->channels();
530*79330504STreehugger Robot return mChannels;
531*79330504STreehugger Robot }
532*79330504STreehugger Robot
format() const533*79330504STreehugger Robot int AudioStreamInDump::format() const
534*79330504STreehugger Robot {
535*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->format();
536*79330504STreehugger Robot return mFormat;
537*79330504STreehugger Robot }
538*79330504STreehugger Robot
setParameters(const String8 & keyValuePairs)539*79330504STreehugger Robot status_t AudioStreamInDump::setParameters(const String8& keyValuePairs)
540*79330504STreehugger Robot {
541*79330504STreehugger Robot ALOGV("AudioStreamInDump::setParameters()");
542*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->setParameters(keyValuePairs);
543*79330504STreehugger Robot return NO_ERROR;
544*79330504STreehugger Robot }
545*79330504STreehugger Robot
getParameters(const String8 & keys)546*79330504STreehugger Robot String8 AudioStreamInDump::getParameters(const String8& keys)
547*79330504STreehugger Robot {
548*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->getParameters(keys);
549*79330504STreehugger Robot
550*79330504STreehugger Robot AudioParameter param = AudioParameter(keys);
551*79330504STreehugger Robot return param.toString();
552*79330504STreehugger Robot }
553*79330504STreehugger Robot
getInputFramesLost() const554*79330504STreehugger Robot unsigned int AudioStreamInDump::getInputFramesLost() const
555*79330504STreehugger Robot {
556*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->getInputFramesLost();
557*79330504STreehugger Robot return 0;
558*79330504STreehugger Robot }
559*79330504STreehugger Robot
dump(int fd,const Vector<String16> & args)560*79330504STreehugger Robot status_t AudioStreamInDump::dump(int fd, const Vector<String16>& args)
561*79330504STreehugger Robot {
562*79330504STreehugger Robot if (mFinalStream != 0 ) return mFinalStream->dump(fd, args);
563*79330504STreehugger Robot return NO_ERROR;
564*79330504STreehugger Robot }
565*79330504STreehugger Robot
Close()566*79330504STreehugger Robot void AudioStreamInDump::Close()
567*79330504STreehugger Robot {
568*79330504STreehugger Robot if(mFile) {
569*79330504STreehugger Robot fclose(mFile);
570*79330504STreehugger Robot mFile = 0;
571*79330504STreehugger Robot }
572*79330504STreehugger Robot }
573*79330504STreehugger Robot }; // namespace android
574