一般的录制 PCM 文件,可以简单的修改 tinycap 的代码,将 tinycap 打包 wav 的地方去掉,直接就可以录制 PCM 文件了(原理是 WAV = 头部+PCM 数据)。也可以使用 Android C++ 的 AudioSource 类来进行录制。代码非常简单,如下:
#include <binder/ProcessState.h>
#include <media/mediarecorder.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/AudioSource.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
#include <system/audio.h>
#define LOG_TAG "recordAudio"
using namespace android;
int main() {
static const int32_t kSampleRate = 16000;
static const int32_t kNumChannels = 1;
static const int32_t kRecordTime = 20; //20 seconds
android::ProcessState::self()->startThreadPool();
FILE *fp = fopen("/data/misc/media/audio.pcm","wb");
if (fp == NULL) {
return 0;
}
sp<AudioSource> audioSource = new AudioSource(
AUDIO_SOURCE_CAMCORDER, /*main mic: AUDIO_SOURCE_DEFAULT*/
kSampleRate /* sampleRate */,
kNumChannels /* channelCount */);
status_t err = audioSource->initCheck();
if (err != OK) {
ALOGE("audio source is not initialized, initCheck failed");
return 0;
} else {
sp<MetaData> params = new MetaData;
params->setInt64(kKeyTime, 0ll);
err = audioSource->start(params.get());
}
int64_t start_record = systemTime();
while (1) {
MediaBuffer *mbuf;
err = audioSource->read(&mbuf);
if (err != OK) {
ALOGE("read audio data failed, err: %d", err);
break;
} else {
int64_t timeUs;
mbuf->meta_data()->findInt64(kKeyTime, &timeUs);
ALOGD("audio frame timeUs: %lld", timeUs);
fwrite((const uint8_t *)mbuf->data() + mbuf->range_offset(), 1, mbuf->range_length(), fp);
mbuf->release();
mbuf = NULL;
}
int64_t record_time = ((systemTime() - start_record) / 1000000000L);
if (record_time > kRecordTime) { //record 20 seconds
ALOGE("record audio completed");
break;
}
}
audioSource->stop();
audioSource.clear();
fclose(fp);
return 0;
}
该代码可以放置在 framework\av\cmds\stagefright\ 目录下进行编译。AudioSource 类可查看 framwork \…\AudioSource.cpp 文件。