LAME库裁剪

引言

lame是优秀的音频库,引百度贴吧的话来说:LAME 是最好的MP3编码器,编码高品质MP3的最好也是唯一的选择。最近项目中需要用到mp3解码部分,遂用到了这个库。好了,废话不多说,进入正题。

lame库移植

lame库编译

  1. [lame源代码获取](http://sourceforge.net/projects/lame/files/lame/3.99/
  2. linux开源库编译3步骤:
    • . ./configure –prefix=XXX
    • . make
    • . make install

lame库 内容简介

lame库主要有3个目录:
- libmp3lame 集合了lame的核心,编码功能在这里面
- mpglib 解码功能在这里
- frontend 看字面意义吧 (^__^) 嘻嘻……

lame库的裁剪

好了,进入关键部分了。嵌入式系统各项资源有限(在这小小的吐槽一下O(∩_∩)O~),要用别人的东西而又不得不修剪一下。但不得不说,lame库写的很好,耦合性很低。想要直接使用lame库的编码部分的同学有福了,因为写lame的大神就遇见了这点,只需要在configure 的时候配置一下即可。如下:
./configure --host=$(HOST) --disable-shared --enable-static --disable-frontend --disable-decoder --prefix=$(INST) CC=$(CROSS_COMPILE)gcc CFLAGS=$(CFLAGS) CPPFLAGS=$(CPPFLAGS)

–disable-frontend –disable-decoder 是关键,其他配置选项自己酌情处理。

但撸主的需求恰恰相反,不是要lame的编码部分,而是需要他的解码部分。configure文件配置需要没有支持该功能,没办法只有硬着头皮裁吧。

在不裁剪的情况下,lame完全编译完成之后会有两个库生成,分别是

lame/mpglib/.libs/libmpgdecoder.a
lame/libmp3lame/.libs/libmp3lame.a

解码部分的代码编译成了 libmpgdecoder.a这个库。看到这里是不是有点惊喜,哇,直接把这个静态库拿来用不就OK了么?是啊,当发现这个,撸主也是高兴了好久呢~~~,可是好事多么,lame提供出来的API的实现基本上都在mpglib_interface.c这个文件中,而这个文件却恰恰又在libmp3lame.a这个库中。再就是直接使用libmpgdecoder.a这个库会发现有些地方链接不过,发现libmpgdecoder.a这个库使用了一些打印函数,和有些函数引用了libmp3lame.a库中的函数。没办法,一狠心,将mpglib中的所有文件提取出来,再将里面所有的打印函数屏蔽写成自己的。将libmp3lame.a中的VbrTag.c和tables.c两个文件拷过来(只发现引用了这两个文件中的函数)。再将所有头文件拷贝过来,集体打包编译。根据编译情况,酌情增删改查,最后编译通过。

lame库的使用

lame解码

/*
   MP3帧体的大小由MPEG版本号、比特率、抽样率和填充位4个因素确定。计算公式为:
   帧大小= ((MPEG版本号== 1?144:72) * 比特率)/抽样率 + 填充位
   位率为64kbps,采样频率为44.1kHz,padding(帧长调节)为1时,帧长为210字节。
   位率为128kbps,采样频率为44.1kHz,padding(帧长调节)为0时,帧长为418字节
 */

int mp3_frame_size(int verson,int baudrate, float samprate,int padding)
{
    if(verson == 1 && baudrate == 64 && (samprate-44.1)<0.000001 && padding == 1)
        return 210;
    if(verson == 1 && baudrate == 128 && (samprate-44.1)<0.000001 && padding == 0)
        return 418;

    return (int)((((verson == 1)? 144:72) * baudrate)/samprate + padding);
}

unsigned char mp3_buf[MP3BUF_SIZE];
int main(int argc,char *argv[])
{
    FILE * mp3fp = fopen("testcase.mp3", "rb");
    if (!mp3fp)
    {
        printf("open mp3 file failed!\n");
        return -1;
    }

    FILE * wavfp = fopen("out1.pcm", "wb");
    if (!wavfp)
    {
        printf("create pcm file failed!\n");
        return -1;
    }

    lame_decode_init();

    mp3data_struct mp3str;

    int samples;
    int mp3_bytes;
    int write_bytes;
    int size = 0;

    size = mp3_frame_size(1,64,44.1,1);
    fprintf(stderr,"mp3 frame size:%d\n",size);

    while ((mp3_bytes = fread(mp3_buf, 1, size, mp3fp)) > 0)
    {
        samples = lame_decode(mp3_buf, size, pcm_l, pcm_r);
        if (samples > 0)
        {
            write_bytes = fwrite(pcm_l, sizeof(short), samples, wavfp);
        }
    }
    lame_decode_exit();
    fclose(wavfp);

    return 0;
}

lame_decode_init lame解码初始化
lame_decode_exit lame解码退出
lame_decode 解码
另外在mpglib_interface.c这个文件中还有另一套hip开头的API,跟lame开头的大同小异。

lame编码

以下代码来自stackoverflow

#include <stdio.h>
#include <lame/lame.h>

int main(void)
{
    int read, write;

    FILE *pcm = fopen("file.pcm", "rb");
    FILE *mp3 = fopen("file.mp3", "wb");

    const int PCM_SIZE = 8192;
    const int MP3_SIZE = 8192;

    short int pcm_buffer[PCM_SIZE*2];
    unsigned char mp3_buffer[MP3_SIZE];

    lame_t lame = lame_init();
    lame_set_in_samplerate(lame, 44100);
    lame_set_VBR(lame, vbr_default);
    lame_init_params(lame);

    do {
        read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
        if (read == 0)
            write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
        else
            write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
        fwrite(mp3_buffer, write, 1, mp3);
    } while (read != 0);

    lame_close(lame);
    fclose(mp3);
    fclose(pcm);

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值