天天看點

Visual Studio下用LAME将wav編碼為mp3

1、何為LAME

LAME 是最好的MP3編碼器,編碼高品質MP3的最好也是唯一的選擇,是目前最好的MP3編碼引擎。LAME編碼出來的MP3音色純厚、空間寬廣、低音清晰、細節表現良好,它獨創的心理音響模型技術保證了CD音頻還原的真實性,配合VBR和ABR參數,音質幾乎可以媲美CD音頻,但檔案體積卻非常小。對于一個免費引擎,LAME的優勢不言而喻。

2、LAME的三種編碼方式

VBR(Variable Bitrate)動态比特率。也就是沒有固定的比特率,壓縮軟體在壓縮時根據音頻資料即時确定使用什麼比特率,這是以品質為前提兼顧檔案大小的方式,推薦編碼模式;

ABR(Average Bitrate)平均比特率,是VBR的一種插值參數。LAME針對CBR不佳的檔案體積比和VBR生成檔案大小不定的特點獨創了這種編碼模式。ABR在指定的檔案大小内,以每50幀(30幀約1秒)為一段,低頻和不敏感頻率使用相對低的流量,高頻和大動态表現時使用高流量,可以做為VBR和CBR的一種折衷選擇。

CBR(Constant Bitrate),常數比特率,指檔案從頭到尾都是一種位速率。相對于VBR和ABR來講,它壓縮出來的檔案體積很大,而且音質相對于VBR和ABR不會有明顯的提高。

3、使用LAME對wav檔案進行編碼

在vs環境下的配置就不說了,很簡單,主要介紹代碼:

#include "stdafx.h"
#include "lame.h"

#include <stdlib.h>

#define INBUFSIZE 4096
#define MP3BUFSIZE (int) (1.25 * INBUFSIZE) + 7200

int encode(char * inPath, char * outPath)
{
	int status = 0;
	lame_global_flags * gfp = NULL;
	int ret_code = 0;
	FILE * infp = NULL;
	FILE * outfp = NULL;
	short * input_buffer = NULL;
	int input_samples = 0;
	unsigned char * mp3_buffer = NULL;
	int mp3_bytes = 0;
           
gfp = lame_init();   //初始化編碼器,設定編碼器的預設參數,成功傳回指向一個全局的結構體指針,失敗傳回NULL
           
if (gfp == NULL)
	{
		printf("lame_init failed/n");
		status = -1;
		goto exit;
	}

	ret_code = lame_init_params(gfp);   //根據得到的gfp配置其他元件,成功傳回0,失敗傳回-1
           
if (ret_code < 0)
	{
		printf("lame_init_params returned %d/n",ret_code);
		status = -1;
		goto close_lame;
	}

	infp = fopen(inPath, "rb");      //打開要編碼的wav檔案
           
outfp = fopen(outPath, "wb");    //打開要生成的mp3檔案
           
input_buffer = (short*)malloc(INBUFSIZE*2);       //為讀取wav檔案内容申請緩存
           
mp3_buffer = (unsigned char*)malloc(MP3BUFSIZE);  //為編碼的MP3檔案内容申請緩存
           
do
	{
		input_samples = fread(input_buffer, 2, INBUFSIZE, infp);
           
//這個函數是編碼左右聲道資料交替的函數,傳回編碼資料的長度
           
mp3_bytes = lame_encode_buffer_interleaved(gfp, input_buffer,input_samples/2, mp3_buffer, MP3BUFSIZE);
		if (mp3_bytes < 0)
		{
			printf("lame_encode_buffer_interleaved returned %d/n", mp3_bytes);
			status = -1;
			goto free_buffers;
		}
		else if(mp3_bytes > 0)
		{
			fwrite(mp3_buffer, 1, mp3_bytes, outfp);
		}
	}while (input_samples == INBUFSIZE);
           
mp3_bytes = lame_encode_flush(gfp, mp3_buffer, sizeof(mp3_buffer));
	if (mp3_bytes > 0)
	{
		printf("writing %d mp3 bytes/n", mp3_bytes);
		fwrite(mp3_buffer, 1, mp3_bytes, outfp);
	}

free_buffers:
	free(mp3_buffer);
	free(input_buffer);

	fclose(outfp);
	fclose(infp);
close_lame:
           
//釋放所有記憶體
           
lame_close(gfp);
exit:
	return status;
}


int _tmain(int argc, char * argv[])
{
	if (argc < 3) 
	{
		printf("usage: lame_test rawinfile mp3outfile/n");
	}

	encode(/*argv[1]*/"cunzai.wav", /*argv[2]*/"cunzai.mp3");

	return 0;
}
           
4、總結
大家可以在編碼過程中使用lame.h檔案中的接口設定各種參數,具體大家自己去嘗試吧
           

繼續閱讀