如何通过上层代码修改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;
}