Linux声卡录音程序之——mp3

本程序用的Lame进行编程
编写程序之前先要安装Lame:
一. 下载最新版lame源码:
http://sourceforge.net/projects/lame/files/lame/3.99/
二. % ./configure
%make (需要root权限)
% make install (需要root权限)


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <memory.h>
#include <linux/soundcard.h>
#include "lame.h"

#define TIMES      10    //录音时间,秒
#define RATE      44100 //采样频率
#define BITS      16    //量化位数
#define CHANNELS 2    //声道数目
#define INBUFF_SIZE 4096
#define MP3BUFF_SIZE (int) (1.25 * INBUFF_SIZE) + 7200

int SetFormat(int fd, unsigned int bit, unsigned int channel, unsigned int hz)
{
      int ioctl_val;

     
      ioctl_val = bit;
      if (ioctl(fd, SOUND_PCM_WRITE_BITS, &ioctl_val) < 0) {
              printf("Set fmt to bit %d failed:%s\n", bit, strerror(errno));
              return -1;
      }
      if (ioctl_val != bit) {
              printf("Do not support bit %d, supported %d\n", bit, ioctl_val);
              return (-1);
      }

     
      ioctl_val = channel;
      if ((ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &ioctl_val)) == -1) {
              fprintf(stderr, "Set Audio Channels %d failed:%s\n", channel, strerror(
                              errno));
              return (-1);
      }
      if (ioctl_val != channel) {
              fprintf(stderr, "Do not support channel %d,supported %d\n", channel,
                              ioctl_val);
              return (-1);
      }

     
      ioctl_val = hz;
      if (ioctl(fd, SOUND_PCM_WRITE_RATE, &ioctl_val) == -1) {
              fprintf(stderr, "Set speed to %d failed:%s/n", hz, strerror(errno));
              return (-1);
      }
      if (ioctl_val != hz) {
              fprintf(stderr, "Do not support speed %d,supported is %d\n", hz,
                              ioctl_val);
              return (-1);
      }

      return 0;

}

int main(int argc, char **argv)
{
      int status = 0;
      int fd_dsp;
      FILE* fd_tmp;
      FILE* fd_mp3;
      lame_global_flags* gfp;
      short *input_buff;
      unsigned char *mp3_buff;

      int samples;
      int mp3_bytes;
      int write_bytes;
      int num = 0;
      int ch;
      int i = 0;

      int ret_code = 0;

      if (argc != 2) {
              fprintf(stderr, "Useage: ./mp3_record test.mp3\n");
              return -1;
      }

      if ((fd_dsp = open("/dev/dsp", O_RDONLY, 0777)) < 0) {
              fprintf(stderr, "Open audio device error: %s\n", strerror(errno));
              status = -1;
              goto EXIT;
      }
      if (SetFormat(fd_dsp, BITS, CHANNELS, RATE) < 0) {
              printf("Cannot set /dev/dsp in bit 16, channel 2, speed 44100.\n");
              status = -1;
              goto EXIT;
      }

      if ((fd_mp3 = fopen(argv[1], "w")) < 0) {
              fprintf(stderr, "Open file error: %s\n", strerror(errno));
              status = -1;
              goto CLOSE_DSP;
      }
     
      gfp = lame_init();
      if (gfp == NULL) {
              printf("lame_init failed\n");
              status = -1;
              goto CLOSE_MP3;
      }

      lame_set_in_samplerate(gfp, RATE);
      //lame_set_out_samplerate(gfp, RATE);
      lame_set_num_channels(gfp, CHANNELS);

      ret_code = lame_init_params(gfp);
      if (ret_code < 0) {
              printf("lame_init_params returned %d\n", ret_code);
              status = -1;
              goto CLOSE_LAME;
      }
      //printf("default rate is %d, out rate is %d.\n", lame_get_in_samplerate(gfp), lame_get_out_samplerate(gfp));
      //ch = lame_get_num_channels(gfp);
      //printf("default brate is %d.\n", lame_get_brate(gfp));
      //printf("default samples is %lu.\n", lame_get_num_samples(gfp));
      //printf("default channel is %d.\n", ch);
      //printf("default vbr_mode is %d.\n", lame_get_VBR(gfp));
      //printf("default force_ms is %d.\n", lame_get_force_ms(gfp));
      //printf("default mode is %d.\n", lame_get_mode(gfp));
      //printf("default compression_ratio is %f.\n", lame_get_compression_ratio(gfp));
      //printf("default VBR_mean_bitrate is %d.\n", lame_get_VBR_mean_bitrate_kbps(gfp));
      //printf("default quality is %d.\n", lame_get_quality(gfp));
     

      input_buff = (short *) malloc(INBUFF_SIZE * 2);
      mp3_buff = (unsigned char *) malloc(MP3BUFF_SIZE);
      if (input_buff == NULL || mp3_buff == NULL) {
              printf("Failed to malloc.\n");
              goto FREE_BUF;
      }

      if ((TIMES*RATE*BITS*CHANNELS/8)%(INBUFF_SIZE * 2) != 0)
              num = (TIMES*RATE*BITS*CHANNELS/8)/(INBUFF_SIZE * 2) + 1;
      else
              num = (TIMES*RATE*BITS*CHANNELS/8)/(INBUFF_SIZE * 2);
      for(i = 0; i < num; i++) {
              memset(input_buff, 0, INBUFF_SIZE * 2);
              memset(mp3_buff, 0, MP3BUFF_SIZE);
             
              samples = read(fd_dsp, input_buff, INBUFF_SIZE * 2);
              if (samples < 0) {
                      perror("Read sound device failed");
                      status = -1;
                      goto FREE_BUF;
              }
                      //printf("samples is %d.\n", samples);
                     
              mp3_bytes = lame_encode_buffer_interleaved(gfp, input_buff,
                              samples/4, mp3_buff, MP3BUFF_SIZE);
              //printf("mp3_bytes is %d.\n", mp3_bytes);
              if (mp3_bytes < 0) {
                      printf("lame_encode_buffer_interleaved returned %d\n", mp3_bytes);
                      status = -1;
                      goto FREE_BUF;
              }
              write_bytes = fwrite(mp3_buff, 1, mp3_bytes, fd_mp3);
              if (write_bytes < 0) {
                      perror("Write sound data file failed\n");
                      status = -1;
                      goto FREE_BUF;
              } else fflush(fd_mp3);
      }
      mp3_bytes = lame_encode_flush(gfp, mp3_buff, sizeof(mp3_buff));
      if (mp3_bytes > 0) {
                      printf("Writing %d mp3 bytes.\n", mp3_bytes);
                      if (fwrite(mp3_buff, 1, mp3_bytes, fd_mp3) < 0)
                              printf("'Writing mp3 bytes error.\n");
                      else
                              fflush(fd_mp3);
              } else
                      printf("Writing mp3 bytes 0.\n");
                     
      FREE_BUF:
      free(mp3_buff);
      mp3_buff = NULL;
      free(input_buff);
      input_buff = NULL;
     
      CLOSE_LAME: lame_close(gfp);
      CLOSE_MP3: fclose(fd_mp3);
      CLOSE_DSP: close(fd_dsp);

      EXIT: return status;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值