音频demo:使用开源项目lame来将PCM数据编码成MP3数据

1、README

前言

本demo是使用开源项目lame来将PCM数据编码成MP3数据。(环境:x86_64 Ubuntu16.04 64位)

a. 编译使用

lame的编译: (源码下载地址:https://sourceforge.net/projects/lame/files/lame/)

bash 复制代码
tar xzf lame-3.100.tar.gz
cd lame-3.100/
./configure --prefix=$PWD/_install
make
make install

本demo的编译与使用:

bash 复制代码
$ make clean && make
$ 
$ ./pcm2mp3
Usage: 
    ./pcm2mp3 <in pcm file> <smaplerate> <channels> <out mp3 file>
Examples: 
    ./pcm2mp3 audio/test1_44100_16bit_stereo.pcm 44100 2 out1_44100_stereo.mp3
    ./pcm2mp3 audio/test2_22050_16bit_stereo.pcm 22050 2 out2_22050_stereo.mp3
    ./pcm2mp3 audio/test3_22050_16bit_mono.pcm   22050 1 out3_22050_mono.mp3
    ./pcm2mp3 audio/test4_8000_16bit_mono.pcm     8000 1 out4_8000_mono.mp3
b. 参考文章
c. demo目录架构
bash 复制代码
$ tree
.
├── audio
│   ├── out1_44100_stereo.mp3
│   ├── out2_22050_stereo.mp3
│   ├── out3_22050_mono.mp3
│   ├── out4_8000_mono.mp3
│   ├── test1_44100_16bit_stereo.pcm
│   ├── test2_22050_16bit_stereo.pcm
│   ├── test3_22050_16bit_mono.pcm
│   └── test4_8000_16bit_mono.pcm
├── docs
│   ├── c++ - 使用 libmp3lame_liblame_lame 将单声道 PCM 文件编码为 MP3 - IT工具网.mhtml
│   ├── Is there any LAME C++ wrapper_simplifier (working on Linux Mac and Win from pure code)_ - Stack Overflow.mhtml
│   └── 使用libmp3lame库编码mp3_太上绝情的博客-CSDN博客_libmp3lame.mhtml
├── include
│   └── lame
│       └── lame.h
├── lib
│   └── libmp3lame.a
├── main.c
├── Makefile
└── README.md

2、主要代码片段

main.c
c 复制代码
#include <stdio.h>
#include <stdlib.h>

#include "lame/lame.h"


#define PCM_SAMPLE_CNT 	(4096)


#define PCM_BUF_SIZE 	(PCM_SAMPLE_CNT * sizeof(short))
#define MP3_BUF_SIZE 	(PCM_SAMPLE_CNT * sizeof(short))


int main(int argc, char *argv[])
{
	char *pcmFileName = NULL;
	char *mp3FileName = NULL;
	FILE *fpPcm = NULL;
	FILE *fpMp3 = NULL;
	int readSampleCnt = -1;
	int encBytes = -1;
	int samplerate = -1;
	int channels = -1;	
	short pcmBuf[PCM_BUF_SIZE];
	unsigned char mp3Buf[MP3_BUF_SIZE];
	lame_t mp3EncHandler = NULL;

	if(argc != 5)
	{
		printf("Usage: \n"
			   "    %s <in pcm file> <smaplerate> <channels> <out mp3 file>\n"
			   "Examples: \n"
			   "    %s audio/test1_44100_16bit_stereo.pcm 44100 2 out1_44100_stereo.mp3\n"
			   "    %s audio/test2_22050_16bit_stereo.pcm 22050 2 out2_22050_stereo.mp3\n"
			   "    %s audio/test3_22050_16bit_mono.pcm   22050 1 out3_22050_mono.mp3\n"
			   "    %s audio/test4_8000_16bit_mono.pcm     8000 1 out4_8000_mono.mp3\n",
			   argv[0], argv[0], argv[0], argv[0], argv[0]);
		return -1;
	}
	else
	{
		pcmFileName = argv[1];
		samplerate  = atoi(argv[2]);
		channels    = atoi(argv[3]);
		mp3FileName = argv[4];
	}

	/* open file */
	fpPcm = fopen(pcmFileName, "rb");
	fpMp3 = fopen(mp3FileName, "wb");
	if(!fpPcm || !fpMp3)
	{
		printf("[%s:%d]: open %s or %s failed!\n", __FUNCTION__, __LINE__, pcmFileName, mp3FileName);
		return -1;
	}

	/* mp3 encode 1/5 : open encoder */
	mp3EncHandler = lame_init();
	if(!mp3EncHandler)
	{
		printf("[%s:%d] open MP3 encoder failed!\n", __FUNCTION__, __LINE__);
		goto exit;
	}

	/* mp3 encode 2/5 : configure encoder params */
	lame_set_in_samplerate(mp3EncHandler, samplerate); 		/* default = 44100hz */
	//lame_set_out_samplerate(mp3EncHandler, samplerate); 	/* if not set, it will be auto configured */
	lame_set_num_channels(mp3EncHandler, channels); 		/* number of channels in input stream. default=2  */
	//lame_set_mode(mp3EncHandler, STEREO); 				/* if not set, it will be auto configured */
	lame_set_VBR(mp3EncHandler, vbr_mtrh); 					/* Types of VBR. vbr_default=vbr_mtrh */
	//lame_set_brate(mp3EncHandler, 160; 					/* for CBR */
	//lame_set_VBR_mean_bitrate_kbps(mp3EncHandler, 160); 	/* Ignored except for VBR=vbr_abr (ABR mode) */
    lame_init_params(mp3EncHandler);

	while(1)
	{
		readSampleCnt = fread(pcmBuf, sizeof(short)/* 16bit */, PCM_SAMPLE_CNT, fpPcm);
		if(readSampleCnt == PCM_SAMPLE_CNT)
		{
			if(channels == 1)
			{
				/* mp3 encode 3/5 : encode(mono) */
				//encBytes = lame_encode_buffer(mp3EncHandler, NULL, pcmBuf, readSampleCnt/channels, mp3Buf, MP3_BUF_SIZE); /* R */
				encBytes = lame_encode_buffer(mp3EncHandler, pcmBuf, NULL, readSampleCnt/channels, mp3Buf, MP3_BUF_SIZE); /* L */
			}
			else if(channels == 2)
			{
				/* mp3 encode 3/5 : encode(stereo) */
				encBytes = lame_encode_buffer_interleaved(mp3EncHandler, pcmBuf, readSampleCnt/channels, /* number of samples per channel, not number of samples in pcmBuf*/
																	 mp3Buf, MP3_BUF_SIZE);
			}
			else
			{
				printf("[%s:%d] Unknown channels(%d)!\n", __FUNCTION__, __LINE__, channels);
				goto exit;
			}

			if(encBytes > 0)
			{
				/* save to file */
				fwrite(mp3Buf, 1, encBytes, fpMp3);
				printf("<in> [pcm bytes: %d]   |   <out> [mp3 bytes: %d]\n", (int)(readSampleCnt * sizeof(short)), encBytes);
			}
			else
			{
				printf("[%s:%d] encode failed!\n", __FUNCTION__, __LINE__);
				goto exit;
			}
		}
		else
		{
			break;
		}
	}

	/* mp3 encode 4/5 : flush to file */
	encBytes = lame_encode_flush(mp3EncHandler, mp3Buf, MP3_BUF_SIZE);
	if(encBytes > 0)
	{
		/* save to file */
		fwrite(mp3Buf, 1, encBytes, fpMp3);
		printf("<in> [pcm bytes: %d]   |   <out> [mp3 bytes: %d]\n", (int)(readSampleCnt * sizeof(short)), encBytes);
	}
	else
	{
		printf("[%s:%d] encode failed!\n", __FUNCTION__, __LINE__);
		goto exit;
	}

	printf("\e[32m%s -> %s success!\e[0m\n", argv[1], argv[4]);

exit:
	/* mp3 encode 5/5 : close encoder */
	if(mp3EncHandler) lame_close(mp3EncHandler);

	if(mp3EncHandler) {fflush(fpMp3); fclose(fpMp3);}
	if(mp3EncHandler) fclose(fpPcm);

	return 0;
}

3、demo下载地址(任选一个)

相关推荐
Android系统攻城狮1 小时前
Linux FFmpeg深度解析之avcodec_parameters_copy调用流程与实战(二十五)
linux·运维·服务器·ffmpeg·音视频·车载音频
听我哔哔2 小时前
口播视频唇形总对不上?Seedance 2.5 在 zeekeAI 里的同步实操
人工智能·音视频
YWamy10 小时前
如何降低RTC SDK在复杂网络环境下的运行成本
网络·音视频·实时音视频
FlightYe12 小时前
视界原理之3D视频(四):裸眼、眼镜和头显
android·linux·c++·3d·ffmpeg·音视频
小豆庄13 小时前
本地视频打码:多模型检测、帧间追踪与18种模糊的选型
opencv·目标检测·ai·自然语言处理·音视频·视频
TST-魚爷18 小时前
小型视频会议室音频踩坑:一体化拾音扩音方案实测分享(易视讯)
stm32·电脑·音视频·钉钉·腾讯会议·zoom会议
Sayai19 小时前
让动漫角色复刻真人动作!MiniMax H3 动作控制实战:一段视频驱动角色动画(12G 显存,附模型下载)
人工智能·aigc·音视频·comfyui·动作捕捉·minimax
美狐美颜SDK开放平台1 天前
开发直播APP、电商短视频与视频社交平台时,能否共用一套美颜SDK?
android·图像处理·人工智能·音视频·直播美颜sdk
AI日报派送佬1 天前
2026年11月02日 AI 行业日报|商汤开源 Loop-9B、Pika 发布 H3 Flex 音视频模型、Meta× 傅利叶推出人形机器人 Max
人工智能·微软·开源·音视频·openai·1024程序员节·ai日报
揽秀亭长1 天前
音频、五线谱、MIDI 如何转成简谱?
人工智能·音视频