Linux下直接录制mp3

本文提供了一个使用lame编码直接录制mp3音频的实例,包括设备文件配置、lame源码下载、编译安装步骤,以及一个简单的C语言程序实现音频录制并转换为mp3格式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是一个用lame编码的直接录制mp3音频的小例子(设备文件:/dev/dsp),说明:
1)若没有,则产生/dev/dsp,方法:modprobe snd_pcm_oss
2)lame源码: http://sourceforge.net/projects/lame/files/lame
3)采用“三步走”的方式编译安装,./configure;make;make install

4)编译下面的小例子:gcc xxx.c -o xxx -lmp3lame (注意:要加上链接库-lmp3lame)

/opt/buildroot-gcc342/bin/mipsel-linux-gcc mp3send.c -o mipsmp3send -I/home/armmlinux/zdfwork/project/audio/mips/lame-3.99.5/_install/include/lame -L/home/armmlinux/zdfwork/project/audio/mips/lame-3.99.5/_install/lib  -lmp3lame

#include <stdio.h>
#include <stdlib.h>
#include <errno.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/lame.h"

#define TIMES    20   	/*录音时间,秒*/
#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) {
		perror("Set fmt to bit");
		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) {
		perror("Set Audio Channels");
		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
发出的红包

打赏作者

武溪嵌人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值