mirror of
https://github.com/ioacademy-jikim/multimedia
synced 2025-06-07 07:56:26 +00:00
157 lines
3.7 KiB
C++
157 lines
3.7 KiB
C++
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <signal.h>
|
|
#include <string.h>
|
|
#include <media/AudioRecord.h>
|
|
|
|
using namespace android;
|
|
|
|
#define ID_RIFF 0x46464952
|
|
#define ID_WAVE 0x45564157
|
|
#define ID_FMT 0x20746d66
|
|
#define ID_DATA 0x61746164
|
|
|
|
#define FORMAT_PCM 1
|
|
|
|
struct wav_header {
|
|
uint32_t riff_id;
|
|
uint32_t riff_sz;
|
|
uint32_t riff_fmt;
|
|
uint32_t fmt_id;
|
|
uint32_t fmt_sz;
|
|
uint16_t audio_format;
|
|
uint16_t num_channels;
|
|
uint32_t sample_rate;
|
|
uint32_t byte_rate;
|
|
uint16_t block_align;
|
|
uint16_t bits_per_sample;
|
|
uint32_t data_id;
|
|
uint32_t data_sz;
|
|
};
|
|
|
|
int capturing = 1;
|
|
|
|
unsigned int capture_sample(FILE *file,
|
|
unsigned int channels,
|
|
unsigned int rate,
|
|
unsigned int period_size,
|
|
unsigned int period_count);
|
|
|
|
void sigint_handler(int sig)
|
|
{
|
|
printf("sigint_handler(%d)\n", sig );
|
|
capturing = 0;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
FILE *file;
|
|
struct wav_header header;
|
|
unsigned int channels = 2;
|
|
unsigned int rate = 44100;
|
|
unsigned int bits = 16;
|
|
unsigned int frames;
|
|
unsigned int period_size = 1024;
|
|
unsigned int period_count = 4;
|
|
|
|
printf("argc=%d\n", argc );
|
|
file = fopen(argv[1], "wb");
|
|
if (!file) {
|
|
fprintf(stderr, "Unable to create file '%s'\n", argv[1]);
|
|
return 1;
|
|
}
|
|
|
|
header.riff_id = ID_RIFF;
|
|
header.riff_sz = 0;
|
|
header.riff_fmt = ID_WAVE;
|
|
header.fmt_id = ID_FMT;
|
|
header.fmt_sz = 16;
|
|
header.audio_format = FORMAT_PCM;
|
|
header.num_channels = channels;
|
|
header.sample_rate = rate;
|
|
|
|
header.bits_per_sample = 16;
|
|
header.byte_rate = (header.bits_per_sample / 8) * channels * rate;
|
|
header.block_align = channels * (header.bits_per_sample / 8);
|
|
header.data_id = ID_DATA;
|
|
|
|
fseek(file, sizeof(struct wav_header), SEEK_SET);
|
|
|
|
signal(SIGINT, sigint_handler);
|
|
frames = capture_sample(file,
|
|
header.num_channels,
|
|
header.sample_rate,
|
|
period_size,
|
|
period_count);
|
|
printf("Captured %d frames\n", frames);
|
|
|
|
header.data_sz = frames * header.block_align;
|
|
header.riff_sz = header.data_sz + sizeof(header) - 8;
|
|
fseek(file, 0, SEEK_SET);
|
|
fwrite(&header, sizeof(struct wav_header), 1, file);
|
|
|
|
fclose(file);
|
|
|
|
return 0;
|
|
}
|
|
|
|
unsigned int capture_sample(FILE *file,
|
|
unsigned int channels,
|
|
unsigned int rate,
|
|
unsigned int period_size,
|
|
unsigned int period_count)
|
|
{
|
|
char *buffer;
|
|
unsigned int size;
|
|
unsigned int bytes_read=0;
|
|
int kMaxBufferSize = 2048;
|
|
size_t minFrameCount;
|
|
status_t status = AudioRecord::getMinFrameCount(&minFrameCount,
|
|
rate,
|
|
AUDIO_FORMAT_PCM_16_BIT,
|
|
audio_channel_in_mask_from_count(channels));
|
|
if (status == OK) {
|
|
uint32_t frameCount = kMaxBufferSize / sizeof(int16_t) / channels;
|
|
|
|
size_t bufCount = 2;
|
|
while ((bufCount * frameCount) < minFrameCount) {
|
|
bufCount++;
|
|
}
|
|
|
|
sp<AudioRecord> record = new AudioRecord(
|
|
AUDIO_SOURCE_DEFAULT, rate, AUDIO_FORMAT_PCM_16_BIT,
|
|
audio_channel_in_mask_from_count(channels),
|
|
String16("AAA")
|
|
);
|
|
status = record->initCheck();
|
|
if(status != NO_ERROR) {
|
|
record.clear();
|
|
printf("Failed for initCheck()");
|
|
return 0;
|
|
}
|
|
|
|
|
|
printf("Capturing sample: %u ch, %u hz, %u bit\n", channels, rate,
|
|
16);
|
|
|
|
size = period_count * period_size * channels * 2;
|
|
buffer = (char*)malloc(size);
|
|
|
|
record->start();
|
|
|
|
while (capturing) {
|
|
size = record->read( buffer, size);
|
|
if (fwrite(buffer, 1, size, file) != size) {
|
|
fprintf(stderr,"Error capturing sample\n");
|
|
break;
|
|
}
|
|
bytes_read += size;
|
|
}
|
|
|
|
free(buffer);
|
|
}
|
|
return bytes_read/4;
|
|
}
|
|
|