LINUX.ORG.RU

alsa запись в mp3


0

1

Как с помощью 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(&params);
  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;
}

Может быть мне нужен другой формат, поскольку стоит цель иметь наименьший размер файла (к микрофону подключена рация,в будющем запись будет начинаться только при открытии канала связи) Заранее спасибо!

>Может быть мне нужен другой формат

Если надо писать голос, то для этого подойдёт ogg со speex внутри. Нужны библиотеки liboggz и libspeex. Вот только документация у liboggz отвратительная.

Zenom ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.