Как с помощью ALSA API осуществить запись звука в формат mp3, сейчас у меня сделано только в wav формат:
#define ALSA_PCM_NEW_HW_PARAMS_API
#include <alsa/asoundlib.h>
struct wav_header {
char chunk_id[4];
unsigned int chunk_size;
char format[4];
char subchunk1_id[4];
unsigned int subchunk1_size;
unsigned short int audio_format;
unsigned short int channels;
unsigned int sample_rate;
unsigned int byte_range;
unsigned short int block_align;
unsigned short int bits_per_sample;
char subchunk2_id[4];
unsigned int subchunk2_size;
};
int main() {
long loops;
int rc;
int size;
snd_pcm_t *handle;
snd_pcm_hw_params_t *params;
unsigned int val;
int dir;
snd_pcm_uframes_t frames;
char *buffer;
struct wav_header header;
FILE *output;
/* init wave header */
struct wav_header {
char chunk_id[4];
unsigned int chunk_size;
char format[4];
char subchunk1_id[4];
unsigned int subchunk1_size;
unsigned short int audio_format;
unsigned short int channels;
unsigned int sample_rate;
unsigned int byte_range;
unsigned short int block_align;
unsigned short int bits_per_sample;
char subchunk2_id[4];
unsigned int subchunk2_size;
};
memcpy(header.chunk_id,"RIFF",4);
header.chunk_size = 0;
memcpy(header.format, "WAVE",4);
memcpy(header.subchunk1_id, "fmt ", 4);
header.subchunk1_size = 16;
header.audio_format = 1;
header.channels = 2;
header.sample_rate = 44100;
header.bits_per_sample = 16;
header.block_align = header.channels * header.bits_per_sample/8;
header.byte_range = header.sample_rate * header.channels *
header.bits_per_sample/8;
memcpy(header.subchunk2_id, "data", 4);
header.subchunk2_size = 0;
output = fopen("/mnt/record.wav","w+");
fwrite(&header, sizeof(struct wav_header), 1, output);
/* Open PCM device for recording (capture). */
rc = snd_pcm_open(&handle, "default",
SND_PCM_STREAM_CAPTURE, 0);
if (rc < 0) {
fprintf(stderr,
"unable to open pcm device: %s\n",
snd_strerror(rc));
exit(1);
}
snd_pcm_hw_params_alloca(¶ms);
snd_pcm_hw_params_any(handle, params);
snd_pcm_hw_params_set_access(handle, params,SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_format(handle, params,SND_PCM_FORMAT_S16_LE);
snd_pcm_hw_params_set_channels(handle, params, 2);
val = 44100;
snd_pcm_hw_params_set_rate_near(handle, params,&val, &dir);
frames = 32;
snd_pcm_hw_params_set_period_size_near(handle,params, &frames, &dir);
rc = snd_pcm_hw_params(handle, params);
if (rc < 0) {
fprintf(stderr,
"unable to set hw parameters: %s\n",
snd_strerror(rc));
exit(1);
}
snd_pcm_hw_params_get_period_size(params,&frames, &dir);
size = frames * 4; /* 2 bytes/sample, 2 channels */
buffer = (char *) malloc(size);
/* пишем 5 секунд */
snd_pcm_hw_params_get_period_time(params,&val, &dir);
loops = 5000000 / val;
snd_output_t *output_stat = NULL;
snd_pcm_status_t *status_stat;
rc = snd_output_stdio_attach(&output_stat, stdout, 0);
if (rc < 0) {
printf("Output failed: %s\n", snd_strerror(rc));
return 0;
}
while (loops > 0) {
loops--;
rc = snd_pcm_readi(handle, buffer, frames);
if (rc == -EPIPE) {
/* EPIPE means overrun */
fprintf(stderr, "overrun occurred\n");
snd_pcm_prepare(handle);
} else if (rc < 0) {
fprintf(stderr,
"error from read: %s\n",
snd_strerror(rc));
} else if (rc != (int)frames) {
fprintf(stderr, "short read, read %d frames\n", rc);
}else{
header.subchunk2_size += frames * 4;
fwrite(buffer, frames * 4, 1, output);
}
}
snd_pcm_drain(handle);
snd_pcm_close(handle);
/* save rest of the data */
header.chunk_size = ftell(output) - 8;
fseek(output, 0, SEEK_SET);
fwrite(&header, sizeof(struct wav_header), 1, output);
fclose(output);
printf("File %d bytes, audio length: %d samples\n",header.chunk_size,header.subchunk2_size / header.channels / (header.bits_per_sample /8));
free(buffer);
return 0;
}
Может быть мне нужен другой формат, поскольку стоит цель иметь наименьший размер файла (к микрофону подключена рация,в будющем запись будет начинаться только при открытии канала связи)
Заранее спасибо!