#include #include #include #include #include #include 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 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; }