【问题标题】:libmp3lame encoding to char array slowlibmp3lame 编码为 char 数组慢
【发布时间】:2013-09-03 00:37:53
【问题描述】:

我正在尝试使用 c 程序将使用“mplayer -ao pcm:nowaveheader”生成的 pcm 音频编码为 mp3。我不想将 mp3 写入文件,我想保留在一个数组中,直到我需要将它写入文件,我写了这个,它似乎可以在 0.9 秒的短测试文件中工作,但是它非常慢。到底有什么问题?

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

lame_global_flags *gfp;
int loopcount;
int inputSize;
FILE *fp=NULL;
FILE *fpo=NULL;
char *mp3buffer;
int mp3buffersize;
int countsize;
int x=0;
int y=0;
short *pcmbuffer;
short *lpcmbuffer;
short *rpcmbuffer;

int parse()
{
    printf("loading PCM data...\n");
    pcmbuffer=malloc(inputSize);
    fread(pcmbuffer,2,(inputSize/2),fp);
    printf("data in buffer\n");
    printf("splitting left and right channels\n");
    lpcmbuffer=malloc(inputSize/2);
    countsize=((inputSize/4)-1);
    while (x<=countsize)
    {
        lpcmbuffer[x]=pcmbuffer[x*2];
        x++;
    }
    x=0;
    rpcmbuffer=malloc(inputSize/2);
    while (x<=countsize)
    {
        rpcmbuffer[x]=pcmbuffer[(x*2)+1];
        x++;
    }
    x=0;
    printf("starting lame\n");
    gfp=lame_init();
    lame_set_num_channels(gfp,2);
    lame_set_in_samplerate(gfp,44100);
    lame_set_brate(gfp,256);
    lame_set_mode(gfp,1);
    lame_set_quality(gfp,5);
    if (lame_init_params(gfp)<0)
    {
        return 1;
    }

}

encode()
{
    x=0;
    mp3buffersize=(1.25*countsize+7200);
    mp3buffer=malloc(mp3buffersize);
    while (x!=countsize)
    {
        lame_encode_buffer(gfp,lpcmbuffer,rpcmbuffer,x,mp3buffer,mp3buffersize);
        x++;
        y++;
        if(y==1000)
        {
            printf("%d     %d\n",countsize,x);
            y=0;
        }
    }
    x=0;
    lame_encode_flush(gfp,mp3buffer,mp3buffersize);
    fpo=fopen("test.mp3","w");
    fwrite(mp3buffer,1,countsize,fpo);
}

decode()
{
}

bounty()
{
    //the quicker picker upper
    printf("closing files\n");
    fclose(fpo);
    fclose(fp);
    printf("closing lame\n");
    lame_close(gfp);
    printf("freeing pcmbuffer\n");
    free(pcmbuffer);
    free(lpcmbuffer);
    free(rpcmbuffer);
    free(mp3buffer);
}

int main(int argc,char **argv)
{
    loopcount=atoi(argv[1]);
    fp=fopen(argv[2],"r");
    if (fp==NULL)
    {
        printf("File Read Error\n");
        return 0;
    }
    fseek(fp,0,SEEK_END);
    inputSize=ftell(fp);
    fseek(fp,0,SEEK_SET);
    printf("detected a %d byte(s) file\n",inputSize);
    printf("Proceeding with parsing and importing...\n");
    if (parse()==1)
    {
        printf("lame init error\n");
    }
    printf("loopcount is %d\n",loopcount);
    encode();
    //the Quicker Picker Upper
    bounty();
    return 0;
}

【问题讨论】:

    标签: c lame


    【解决方案1】:

    简短回答,将此作为您的编码函数:

    void encode()
    {
        mp3buffersize=(1.25*countsize+7200);
        mp3buffer=malloc(mp3buffersize);
        lame_encode_buffer(gfp, lpcmbuffer, rpcmbuffer, countsize, mp3buffer, mp3buffersize);
        lame_encode_flush(gfp,mp3buffer,mp3buffersize);
        fpo=fopen("test.mp3","w");
        fwrite(mp3buffer,1,countsize,fpo);
    }
    

    我从未使用过 lame,但是,它看起来像在您的 encode() 函数中,您一次又一次地调用 lame_encode_buffer(),每次都覆盖结果,并从 0countsize 作为数字每个通道的样本数(参数 4)。

    其他cmets:

    你为什么不使用lame_encode_buffer_interleaved()?您的大部分parse() 函数只是撤消文件的现有交错,这似乎是一种浪费。

    IMO,您使用的大量全局变量是丑陋的。理想情况下,您的 encode() 看起来更像:encode(lame_global_flags *gfp, const short * lpcmbuffer, const short * rpcmbuffer, const int countsize) 这样,从读取参数列表中可以清楚地看出变量的类型,并且它们必须来自/由调用者设置。 const 很高兴澄清它们仅供阅读。

    最后,你真的应该做一些分析,例如打印函数进入和退出之间的时间差,以确定你的时间槽在哪里,并发布你发现的内容。我大胆猜测一下你的循环,encode() 函数有唯一的循环,里面有任何肉。我从来没有运行过你的程序,也许我 100% 错了。

    【讨论】:

      猜你喜欢
      • 2010-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-20
      • 2011-06-08
      • 2017-10-08
      • 2015-03-03
      • 1970-01-01
      相关资源
      最近更新 更多