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、付费专栏及课程。

余额充值