2013-09-03 2 views
1

Я пытаюсь закодировать звук pcm, который я создал с помощью «mplayer -ao pcm: nowaveheader» в mp3 с программой c. Я не хочу писать mp3 в файл, я хочу хранить его в массиве, пока мне не нужно записать его в файл, я написал это и, похоже, работает в коротком тестовом файле .9 секунд, но он очень медленный. Что именно не так?libmp3lame encoding to char array slow

#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; 
} 

ответ

0

Короткий ответ, сделайте это ваш закодировать функцию:

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); 
} 

Я никогда не использовал хромает, но это выглядело как в вашей encode() функции вы звонили lame_encode_buffer() снова и снова, переписывая результат каждый раз и от 0 до countsize в качестве количества выборок на канал (аргумент 4).

Другие комментарии:

Почему вы не используете lame_encode_buffer_interleaved()? Большая часть вашей функции parse() просто уничтожает существующее чередование вашего файла, кажется, пустой тратой.

IMO, масса глобальных переменных, которые вы используете, - это UGLY. В идеале ваш encode() будет больше похож: encode(lame_global_flags *gfp, const short * lpcmbuffer, const short * rpcmbuffer, const int countsize) Таким образом, из чтения списка параметров видно, что тип переменных и что они должны были быть установлены/установлены вызывающим. const приятно прояснить, что они предназначены только для чтения.

Наконец, вы действительно должны были выполнить профилирование, например. различия времени печати между входом и выходом функций, чтобы определить, где находится ваше время, и опубликовали то, что вы нашли. Я отважился угадать, глядя на ваши петли, функция encode() имела единственный цикл с любым мясом в нем. Я никогда не запускал вашу программу, может быть, я на 100% ошибаюсь.