1 /* //device/servers/AudioFlinger/AudioDumpInterface.cpp
3 ** Copyright 2008, The Android Open Source Project
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
9 ** http://www.apache.org/licenses/LICENSE-2.0
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
18 #define LOG_TAG "AudioFlingerDump"
19 //#define LOG_NDEBUG 0
22 #include <sys/types.h>
23 #include <utils/Log.h>
28 #include "AudioDumpInterface.h"
32 // ----------------------------------------------------------------------------
34 AudioDumpInterface::AudioDumpInterface(AudioHardwareInterface* hw)
35 : mPolicyCommands(String8("")), mFileName(String8(""))
38 ALOGE("Dump construct hw = 0");
41 ALOGV("Constructor %p, mFinalInterface %p", this, mFinalInterface);
45 AudioDumpInterface::~AudioDumpInterface()
47 for (size_t i = 0; i < mOutputs.size(); i++) {
48 closeOutputStream((AudioStreamOut *)mOutputs[i]);
51 for (size_t i = 0; i < mInputs.size(); i++) {
52 closeInputStream((AudioStreamIn *)mInputs[i]);
55 if(mFinalInterface) delete mFinalInterface;
59 AudioStreamOut* AudioDumpInterface::openOutputStream(
60 uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
62 AudioStreamOut* outFinal = NULL;
63 int lFormat = AudioSystem::PCM_16_BIT;
64 uint32_t lChannels = AudioSystem::CHANNEL_OUT_STEREO;
65 uint32_t lRate = 44100;
68 outFinal = mFinalInterface->openOutputStream(devices, format, channels, sampleRate, status);
70 lFormat = outFinal->format();
71 lChannels = outFinal->channels();
72 lRate = outFinal->sampleRate();
83 lChannels = *channels;
85 *channels = lChannels;
88 if (sampleRate != 0) {
89 if (*sampleRate != 0) {
95 if (status) *status = NO_ERROR;
97 ALOGV("openOutputStream(), outFinal %p", outFinal);
99 AudioStreamOutDump *dumOutput = new AudioStreamOutDump(this, mOutputs.size(), outFinal,
100 devices, lFormat, lChannels, lRate);
101 mOutputs.add(dumOutput);
106 void AudioDumpInterface::closeOutputStream(AudioStreamOut* out)
108 AudioStreamOutDump *dumpOut = (AudioStreamOutDump *)out;
110 if (mOutputs.indexOf(dumpOut) < 0) {
111 ALOGW("Attempt to close invalid output stream");
115 ALOGV("closeOutputStream() output %p", out);
118 if (dumpOut->finalStream() != NULL) {
119 mFinalInterface->closeOutputStream(dumpOut->finalStream());
122 mOutputs.remove(dumpOut);
126 AudioStreamIn* AudioDumpInterface::openInputStream(uint32_t devices, int *format, uint32_t *channels,
127 uint32_t *sampleRate, status_t *status, AudioSystem::audio_in_acoustics acoustics)
129 AudioStreamIn* inFinal = NULL;
130 int lFormat = AudioSystem::PCM_16_BIT;
131 uint32_t lChannels = AudioSystem::CHANNEL_IN_MONO;
132 uint32_t lRate = 8000;
134 inFinal = mFinalInterface->openInputStream(devices, format, channels, sampleRate, status, acoustics);
136 lFormat = inFinal->format();
137 lChannels = inFinal->channels();
138 lRate = inFinal->sampleRate();
148 if (*channels != 0) {
149 lChannels = *channels;
151 *channels = lChannels;
154 if (sampleRate != 0) {
155 if (*sampleRate != 0) {
161 if (status) *status = NO_ERROR;
163 ALOGV("openInputStream(), inFinal %p", inFinal);
165 AudioStreamInDump *dumInput = new AudioStreamInDump(this, mInputs.size(), inFinal,
166 devices, lFormat, lChannels, lRate);
167 mInputs.add(dumInput);
171 void AudioDumpInterface::closeInputStream(AudioStreamIn* in)
173 AudioStreamInDump *dumpIn = (AudioStreamInDump *)in;
175 if (mInputs.indexOf(dumpIn) < 0) {
176 ALOGW("Attempt to close invalid input stream");
180 if (dumpIn->finalStream() != NULL) {
181 mFinalInterface->closeInputStream(dumpIn->finalStream());
184 mInputs.remove(dumpIn);
189 status_t AudioDumpInterface::setParameters(const String8& keyValuePairs)
191 AudioParameter param = AudioParameter(keyValuePairs);
194 ALOGV("setParameters %s", keyValuePairs.string());
196 if (param.get(String8("test_cmd_file_name"), value) == NO_ERROR) {
198 param.remove(String8("test_cmd_file_name"));
200 if (param.get(String8("test_cmd_policy"), value) == NO_ERROR) {
201 Mutex::Autolock _l(mLock);
202 param.remove(String8("test_cmd_policy"));
203 mPolicyCommands = param.toString();
204 ALOGV("test_cmd_policy command %s written", mPolicyCommands.string());
208 if (mFinalInterface != 0 ) return mFinalInterface->setParameters(keyValuePairs);
212 String8 AudioDumpInterface::getParameters(const String8& keys)
214 AudioParameter param = AudioParameter(keys);
215 AudioParameter response;
218 // ALOGV("getParameters %s", keys.string());
219 if (param.get(String8("test_cmd_policy"), value) == NO_ERROR) {
220 Mutex::Autolock _l(mLock);
221 if (mPolicyCommands.length() != 0) {
222 response = AudioParameter(mPolicyCommands);
223 response.addInt(String8("test_cmd_policy"), 1);
225 response.addInt(String8("test_cmd_policy"), 0);
227 param.remove(String8("test_cmd_policy"));
228 // ALOGV("test_cmd_policy command %s read", mPolicyCommands.string());
231 if (param.get(String8("test_cmd_file_name"), value) == NO_ERROR) {
232 response.add(String8("test_cmd_file_name"), mFileName);
233 param.remove(String8("test_cmd_file_name"));
236 String8 keyValuePairs = response.toString();
238 if (param.size() && mFinalInterface != 0 ) {
239 keyValuePairs += ";";
240 keyValuePairs += mFinalInterface->getParameters(param.toString());
243 return keyValuePairs;
246 status_t AudioDumpInterface::setMode(int mode)
248 return mFinalInterface->setMode(mode);
251 size_t AudioDumpInterface::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
253 return mFinalInterface->getInputBufferSize(sampleRate, format, channelCount);
256 // ----------------------------------------------------------------------------
258 AudioStreamOutDump::AudioStreamOutDump(AudioDumpInterface *interface,
260 AudioStreamOut* finalStream,
265 : mInterface(interface), mId(id),
266 mSampleRate(sampleRate), mFormat(format), mChannels(channels), mLatency(0), mDevice(devices),
267 mBufferSize(1024), mFinalStream(finalStream), mFile(0), mFileCount(0)
269 ALOGV("AudioStreamOutDump Constructor %p, mInterface %p, mFinalStream %p", this, mInterface, mFinalStream);
273 AudioStreamOutDump::~AudioStreamOutDump()
275 ALOGV("AudioStreamOutDump destructor");
279 ssize_t AudioStreamOutDump::write(const void* buffer, size_t bytes)
284 ret = mFinalStream->write(buffer, bytes);
286 usleep((((bytes * 1000) / frameSize()) / sampleRate()) * 1000);
290 if (mInterface->fileName() != "") {
292 sprintf(name, "%s_out_%d_%d.pcm", mInterface->fileName().string(), mId, ++mFileCount);
293 mFile = fopen(name, "wb");
294 ALOGV("Opening dump file %s, fh %p", name, mFile);
298 fwrite(buffer, bytes, 1, mFile);
303 status_t AudioStreamOutDump::standby()
305 ALOGV("AudioStreamOutDump standby(), mFile %p, mFinalStream %p", mFile, mFinalStream);
308 if (mFinalStream != 0 ) return mFinalStream->standby();
312 uint32_t AudioStreamOutDump::sampleRate() const
314 if (mFinalStream != 0 ) return mFinalStream->sampleRate();
318 size_t AudioStreamOutDump::bufferSize() const
320 if (mFinalStream != 0 ) return mFinalStream->bufferSize();
324 uint32_t AudioStreamOutDump::channels() const
326 if (mFinalStream != 0 ) return mFinalStream->channels();
329 int AudioStreamOutDump::format() const
331 if (mFinalStream != 0 ) return mFinalStream->format();
334 uint32_t AudioStreamOutDump::latency() const
336 if (mFinalStream != 0 ) return mFinalStream->latency();
339 status_t AudioStreamOutDump::setVolume(float left, float right)
341 if (mFinalStream != 0 ) return mFinalStream->setVolume(left, right);
344 status_t AudioStreamOutDump::setParameters(const String8& keyValuePairs)
346 ALOGV("AudioStreamOutDump::setParameters %s", keyValuePairs.string());
348 if (mFinalStream != 0 ) {
349 return mFinalStream->setParameters(keyValuePairs);
352 AudioParameter param = AudioParameter(keyValuePairs);
355 status_t status = NO_ERROR;
357 if (param.getInt(String8("set_id"), valueInt) == NO_ERROR) {
361 if (param.getInt(String8("format"), valueInt) == NO_ERROR) {
365 status = INVALID_OPERATION;
368 if (param.getInt(String8("channels"), valueInt) == NO_ERROR) {
369 if (valueInt == AudioSystem::CHANNEL_OUT_STEREO || valueInt == AudioSystem::CHANNEL_OUT_MONO) {
370 mChannels = valueInt;
375 if (param.getInt(String8("sampling_rate"), valueInt) == NO_ERROR) {
376 if (valueInt > 0 && valueInt <= 48000) {
378 mSampleRate = valueInt;
380 status = INVALID_OPERATION;
389 String8 AudioStreamOutDump::getParameters(const String8& keys)
391 if (mFinalStream != 0 ) return mFinalStream->getParameters(keys);
393 AudioParameter param = AudioParameter(keys);
394 return param.toString();
397 status_t AudioStreamOutDump::dump(int fd, const Vector<String16>& args)
399 if (mFinalStream != 0 ) return mFinalStream->dump(fd, args);
403 void AudioStreamOutDump::Close()
411 status_t AudioStreamOutDump::getRenderPosition(uint32_t *dspFrames)
413 if (mFinalStream != 0 ) return mFinalStream->getRenderPosition(dspFrames);
414 return INVALID_OPERATION;
417 // ----------------------------------------------------------------------------
419 AudioStreamInDump::AudioStreamInDump(AudioDumpInterface *interface,
421 AudioStreamIn* finalStream,
426 : mInterface(interface), mId(id),
427 mSampleRate(sampleRate), mFormat(format), mChannels(channels), mDevice(devices),
428 mBufferSize(1024), mFinalStream(finalStream), mFile(0), mFileCount(0)
430 ALOGV("AudioStreamInDump Constructor %p, mInterface %p, mFinalStream %p", this, mInterface, mFinalStream);
434 AudioStreamInDump::~AudioStreamInDump()
439 ssize_t AudioStreamInDump::read(void* buffer, ssize_t bytes)
444 ret = mFinalStream->read(buffer, bytes);
446 if (mInterface->fileName() != "") {
448 sprintf(name, "%s_in_%d_%d.pcm", mInterface->fileName().string(), mId, ++mFileCount);
449 mFile = fopen(name, "wb");
450 ALOGV("Opening input dump file %s, fh %p", name, mFile);
454 fwrite(buffer, bytes, 1, mFile);
457 usleep((((bytes * 1000) / frameSize()) / sampleRate()) * 1000);
461 strcpy(name, "/sdcard/music/sine440");
462 if (channels() == AudioSystem::CHANNEL_IN_MONO) {
467 if (format() == AudioSystem::PCM_16_BIT) {
468 strcat(name, "_16b");
472 if (sampleRate() < 16000) {
474 } else if (sampleRate() < 32000) {
475 strcat(name, "_22k");
476 } else if (sampleRate() < 48000) {
477 strcat(name, "_44k");
479 strcat(name, "_48k");
481 strcat(name, ".wav");
482 mFile = fopen(name, "rb");
483 ALOGV("Opening input read file %s, fh %p", name, mFile);
485 fseek(mFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
489 ssize_t bytesRead = fread(buffer, bytes, 1, mFile);
490 if (bytesRead >=0 && bytesRead < bytes) {
491 fseek(mFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
492 fread((uint8_t *)buffer+bytesRead, bytes-bytesRead, 1, mFile);
500 status_t AudioStreamInDump::standby()
502 ALOGV("AudioStreamInDump standby(), mFile %p, mFinalStream %p", mFile, mFinalStream);
505 if (mFinalStream != 0 ) return mFinalStream->standby();
509 status_t AudioStreamInDump::setGain(float gain)
511 if (mFinalStream != 0 ) return mFinalStream->setGain(gain);
515 uint32_t AudioStreamInDump::sampleRate() const
517 if (mFinalStream != 0 ) return mFinalStream->sampleRate();
521 size_t AudioStreamInDump::bufferSize() const
523 if (mFinalStream != 0 ) return mFinalStream->bufferSize();
527 uint32_t AudioStreamInDump::channels() const
529 if (mFinalStream != 0 ) return mFinalStream->channels();
533 int AudioStreamInDump::format() const
535 if (mFinalStream != 0 ) return mFinalStream->format();
539 status_t AudioStreamInDump::setParameters(const String8& keyValuePairs)
541 ALOGV("AudioStreamInDump::setParameters()");
542 if (mFinalStream != 0 ) return mFinalStream->setParameters(keyValuePairs);
546 String8 AudioStreamInDump::getParameters(const String8& keys)
548 if (mFinalStream != 0 ) return mFinalStream->getParameters(keys);
550 AudioParameter param = AudioParameter(keys);
551 return param.toString();
554 unsigned int AudioStreamInDump::getInputFramesLost() const
556 if (mFinalStream != 0 ) return mFinalStream->getInputFramesLost();
560 status_t AudioStreamInDump::dump(int fd, const Vector<String16>& args)
562 if (mFinalStream != 0 ) return mFinalStream->dump(fd, args);
566 void AudioStreamInDump::Close()
573 }; // namespace android