如何通过上层代码修改dump音频数据流
我们在分析杂音等问题的时候, 只抓adb log是不够的, dump audio的数据能直观快速的判断是哪一块出了问题, 这里只针对高通平台
1. 如何在Frameworks层音频数据dump
-
//代码路径:frameworks/av/services/audioflinger/Tracks.cpp#getNextBuffer
-
status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(
-
AudioBufferProvider::Buffer* buffer){
-
ServerProxy::Buffer buf;
-
size_t desiredFrames = buffer->frameCount;
-
buf.mFrameCount = desiredFrames;
-
status_t status = mServerProxy->obtainBuffer(&buf);
-
buffer->frameCount = buf.mFrameCount;
-
buffer->raw = buf.mRaw;
-
if (buf.mFrameCount == 0) {
-
mAudioTrackServerProxy->tallyUnderrunFrames(desiredFrames);
-
} else {
-
mAudioTrackServerProxy->tallyUnderrunFrames(0);
-
}
-
int tmpFd = ::open("/data/misc/audio/dumpTrack.pcm", O_CREAT | O_WRONLY | O_APPEND, 0777);
-
if ( tmpFd < 0 ) {
-
ALOGE("Tracks.cpp Fail to open dumpTrack file");
-
} else {
-
::write(tmpFd, buffer->raw, buffer->frameCount * TrackBase::mChannelCount * 2);
-
::close(tmpFd);
-
}
-
return status;
-
}
2. 如何在HAL层音频数据dump
-
//hardware/qcom/audio/hal/audio_hw.c#out_write
-
static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,size_t bytes){
-
struct stream_out *out = (struct stream_out *)stream;
-
struct audio_device *adev = out->dev;
-
ssize_t ret = 0;
-
......
-
} else {
-
if (out->pcm) {
-
if (out->muted)
-
memset((void *)buffer, 0, bytes);
-
ALOGVV("%s: writing buffer (%d bytes) to pcm device", __func__, bytes);
-
int tmpFd = open("/data/misc/audio/dumpTrack_hal.pcm", O_CREAT | O_WRONLY | O_APPEND, 0777);
-
if ( tmpFd < 0 ) {
-
ALOGE("Fail to open dumpTrack_hal file");
-
} else {
-
write(tmpFd, buffer, bytes);
-
close(tmpFd);
-
}
-
if (adev->adm_request_focus)
-
adev->adm_request_focus(adev->adm_data, out->handle);
-
if (out->usecase == USECASE_AUDIO_PLAYBACK_AFE_PROXY) {
-
ret = pcm_mmap_write(out->pcm, (void *)buffer, bytes);
-
}
-
else
-
ret = pcm_write(out->pcm, (void *)buffer, bytes);
-
if (ret == 0)
-
out->written += bytes / (out->config.channels * sizeof(short));
-
if (adev->adm_abandon_focus)
-
adev->adm_abandon_focus(adev->adm_data, out->handle);
-
}
-
}
-
exit:
-
pthread_mutex_unlock(&out->lock);
-
if (ret != 0) {
-
if (out->pcm)
-
ALOGE("%s: error %zu - %s", __func__, ret, pcm_get_error(out->pcm));
-
out_standby(&out->stream.common);
-
usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
-
out_get_sample_rate(&out->stream.common));
-
}
-
return bytes;
-
}