在 AudioFlinger 中捕获音频数据并保存为原始 PCM 文件
Capturing audio data and save to raw PCM file in AudioFlinger
经过一些研究,我发现可以在 Android 的 libaudioflinger 中捕获音频数据。
我认为音频数据正在此处写入 HAL:
ssize_t framesWritten = mNormalSink->write((char *)mSinkBuffer + offset, count);
所以,我想将 mSinkBuffer + 偏移量保存到一个文件中(我希望它是原始 PCM 音频文件)。我使用这些流将其写入文件:
std::ofstream audioData ("/data/audiodata.raw", std::fstream::app);
audioData.write((char *)mSinkBuffer + offset, count);
audioData.close();
文件写入成功,里面有数据。
但是,当我用 aplay 或 ffplay 播放 PCM 文件 (audiodata.raw) 时,我得到的唯一声音是噪音。
aplay -t raw -c 2 -f S16_LE -r 48000 audiodata.raw
担心aplay的配置问题。所以我打印了一些 libaudioflinger 的日志:
10-07 10:14:54.575 1300 1366 I AudioFlinger: I/O handle: 13
10-07 10:14:54.575 1300 1366 I AudioFlinger: Standby: no
10-07 10:14:54.575 1300 1366 I AudioFlinger: Sample rate: 48000 Hz
10-07 10:14:54.575 1300 1366 I AudioFlinger: HAL frame count: 512
10-07 10:14:54.575 1300 1366 I AudioFlinger: HAL format: 0x1 (AUDIO_FORMAT_PCM_16_BIT)
10-07 10:14:54.575 1300 1366 I AudioFlinger: HAL buffer size: 2048 bytes
10-07 10:14:54.575 1300 1366 I AudioFlinger: Channel count: 2
10-07 10:14:54.575 1300 1366 I AudioFlinger: Channel mask: 0x00000003 (front-left, front-right)
10-07 10:14:54.575 1300 1366 I AudioFlinger: Processing format: 0x5 (AUDIO_FORMAT_PCM_FLOAT)
10-07 10:14:54.576 1300 1366 I AudioFlinger: Processing frame size: 8 bytes
10-07 10:14:54.576 1300 1366 I AudioFlinger: Pending config events:
10-07 10:14:54.576 1300 1366 I AudioFlinger: none
10-07 10:14:54.576 1300 1366 I AudioFlinger: Output device: 0x2 (AUDIO_DEVICE_OUT_SPEAKER)
10-07 10:14:54.576 1300 1366 I AudioFlinger: Input device: 0 (AUDIO_DEVICE_NONE)
10-07 10:14:54.576 1300 1366 I AudioFlinger: Audio source: 0 (default)
我不知道我做错了什么。请帮帮我!
在此先感谢您!
当你必须播放原始文件时,你必须为声音帧使用编解码器格式,例如 wav 或 mp3 等。尝试将原始数据传递到 winmm 中定义的 wav WAVEFORMAT 并从设备获取音频可以通过 C++ 中的 WAVEFORMAT 类型打开和关闭。
以追加|二进制模式打开文件
std::ofstream audioData ("/data/audiodata.raw", std::fstream::app | std::fstream::binary);
binary - binary - Operations are performed in binary mode rather than text.
原始 PCM 缓冲区应以二进制模式写入。
请检查代码以了解字节数和计数之间的差异
(添加了一些评论以供参考,希望能解决您的问题)
if (mNormalSink != 0) {
/* Count is the number of Frames or sample written != bytes */
const size_t count = mBytesRemaining / mFrameSize;
ATRACE_BEGIN("write");
// update the setpoint when AudioFlinger::mScreenState changes
uint32_t screenState = AudioFlinger::mScreenState;
if (screenState != mScreenState) {
mScreenState = screenState;
MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
if (pipe != NULL) {
pipe->setAvgFrames((mScreenState & 1) ?
(pipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2);
}
}
ssize_t framesWritten = mNormalSink->write((char *)mSinkBuffer + offset, count);
ATRACE_END();
if (framesWritten > 0) {
bytesWritten = framesWritten * mFrameSize;
// std::ofstream audioData ("/data/audiodata.raw", std::fstream::binary);
/* File write or stream write is the number of bytes written to the file */
audioData.write((char *)mSinkBuffer + offset, bytesWritten);
// audioData.close();
} else {
bytesWritten = framesWritten;
}
// otherwise use the HAL / AudioStreamOut directly
}
Audacity - 打开原始文件
文件 -> 导入 -> 原始数据
Select原始文件路径
基于您附加的原始文件。
使用这些设置
编码:32 位浮点数
字节顺序:小端
频道:2 个频道(立体声)
起始偏移量:0
进口数量:100
采样率:48000
文件正常播放,没有任何 glitches/noise。
经过一些研究,我发现可以在 Android 的 libaudioflinger 中捕获音频数据。
我认为音频数据正在此处写入 HAL:
ssize_t framesWritten = mNormalSink->write((char *)mSinkBuffer + offset, count);
所以,我想将 mSinkBuffer + 偏移量保存到一个文件中(我希望它是原始 PCM 音频文件)。我使用这些流将其写入文件:
std::ofstream audioData ("/data/audiodata.raw", std::fstream::app);
audioData.write((char *)mSinkBuffer + offset, count);
audioData.close();
文件写入成功,里面有数据。 但是,当我用 aplay 或 ffplay 播放 PCM 文件 (audiodata.raw) 时,我得到的唯一声音是噪音。
aplay -t raw -c 2 -f S16_LE -r 48000 audiodata.raw
担心aplay的配置问题。所以我打印了一些 libaudioflinger 的日志:
10-07 10:14:54.575 1300 1366 I AudioFlinger: I/O handle: 13
10-07 10:14:54.575 1300 1366 I AudioFlinger: Standby: no
10-07 10:14:54.575 1300 1366 I AudioFlinger: Sample rate: 48000 Hz
10-07 10:14:54.575 1300 1366 I AudioFlinger: HAL frame count: 512
10-07 10:14:54.575 1300 1366 I AudioFlinger: HAL format: 0x1 (AUDIO_FORMAT_PCM_16_BIT)
10-07 10:14:54.575 1300 1366 I AudioFlinger: HAL buffer size: 2048 bytes
10-07 10:14:54.575 1300 1366 I AudioFlinger: Channel count: 2
10-07 10:14:54.575 1300 1366 I AudioFlinger: Channel mask: 0x00000003 (front-left, front-right)
10-07 10:14:54.575 1300 1366 I AudioFlinger: Processing format: 0x5 (AUDIO_FORMAT_PCM_FLOAT)
10-07 10:14:54.576 1300 1366 I AudioFlinger: Processing frame size: 8 bytes
10-07 10:14:54.576 1300 1366 I AudioFlinger: Pending config events:
10-07 10:14:54.576 1300 1366 I AudioFlinger: none
10-07 10:14:54.576 1300 1366 I AudioFlinger: Output device: 0x2 (AUDIO_DEVICE_OUT_SPEAKER)
10-07 10:14:54.576 1300 1366 I AudioFlinger: Input device: 0 (AUDIO_DEVICE_NONE)
10-07 10:14:54.576 1300 1366 I AudioFlinger: Audio source: 0 (default)
我不知道我做错了什么。请帮帮我!
在此先感谢您!
当你必须播放原始文件时,你必须为声音帧使用编解码器格式,例如 wav 或 mp3 等。尝试将原始数据传递到 winmm 中定义的 wav WAVEFORMAT 并从设备获取音频可以通过 C++ 中的 WAVEFORMAT 类型打开和关闭。
以追加|二进制模式打开文件
std::ofstream audioData ("/data/audiodata.raw", std::fstream::app | std::fstream::binary);
binary - binary - Operations are performed in binary mode rather than text.
原始 PCM 缓冲区应以二进制模式写入。
请检查代码以了解字节数和计数之间的差异 (添加了一些评论以供参考,希望能解决您的问题)
if (mNormalSink != 0) {
/* Count is the number of Frames or sample written != bytes */
const size_t count = mBytesRemaining / mFrameSize;
ATRACE_BEGIN("write");
// update the setpoint when AudioFlinger::mScreenState changes
uint32_t screenState = AudioFlinger::mScreenState;
if (screenState != mScreenState) {
mScreenState = screenState;
MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
if (pipe != NULL) {
pipe->setAvgFrames((mScreenState & 1) ?
(pipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2);
}
}
ssize_t framesWritten = mNormalSink->write((char *)mSinkBuffer + offset, count);
ATRACE_END();
if (framesWritten > 0) {
bytesWritten = framesWritten * mFrameSize;
// std::ofstream audioData ("/data/audiodata.raw", std::fstream::binary);
/* File write or stream write is the number of bytes written to the file */
audioData.write((char *)mSinkBuffer + offset, bytesWritten);
// audioData.close();
} else {
bytesWritten = framesWritten;
}
// otherwise use the HAL / AudioStreamOut directly
}
Audacity - 打开原始文件
文件 -> 导入 -> 原始数据
Select原始文件路径
基于您附加的原始文件。
使用这些设置
编码:32 位浮点数
字节顺序:小端
频道:2 个频道(立体声)
起始偏移量:0
进口数量:100
采样率:48000
文件正常播放,没有任何 glitches/noise。