调用lame_encode_buffer时EXC_BAD_ACCESS

时间:2010-02-24 13:33:07

标签: objective-c lame

我正在使用lame编码器使用objective-c和cocoa将wav转换为mac osx中的mp3。在音频编码方面,我是一个完全新手,而且我的C技能不是很好。无论我是偶然发现还是进入了实际的编码阶段,这就是我被困住的地方。

从我研究的代码中,看起来我应该使用lame_encode_buffer用于单声道而lame_encode_buffer_interleaved用于立体声(尽管前者为左右声道输入输入混淆的事实我)。我到目前为止的代码是:

-(BOOL)encodeWave:(Wave *)wav {
    if(![self loadLibrary]) {
        return FALSE;
    }

    lame_set_num_channels(lgf,[wav channels]);
    lame_set_in_samplerate(lgf,[wav sampleRate]);
    lame_set_out_samplerate(lgf,[wav sampleRate]);
    lame_set_brate(lgf, [wav getBrateInK]);

    lame_init_params(lgf);

    //encode stuff!
    int total_samples = ([wav data_length] / [wav bytesPerSample]);
    int n_samples = total_samples / [wav channels];
    Byte * inBuf = (Byte *)malloc([wav data_length]);
    if(inBuf == NULL)
        return FALSE;
    memcpy(inBuf, [[wav data] bytes], [wav data_length]);
    int outBuf_size = 7200 + (1.25*n_samples);
    unsigned char * outBuf = (unsigned char *)malloc(outBuf_size);
    if(outBuf == NULL)
        return FALSE;
    lame_encode_buffer(lgf,(short int *)inBuf,(short int *)inBuf, n_samples, outBuf, outBuf_size);

    return TRUE;

}

-(BOOL)loadLibrary {

    NSString * pathToLib = [LAME_LIB_LIKELY_LOC stringByAppendingPathComponent:LAME_LIB_NAME];

    if(![[NSFileManager defaultManager] fileExistsAtPath:pathToLib])
        return FALSE;

    void * lib_handle = dlopen("libmp3lame.dylib",RTLD_LOCAL|RTLD_LAZY);
    if(!lib_handle)
        return FALSE;

    //Init
    lgf = lame_init();

    //set error processor
    lame_set_errorf(lgf,errorHandler);
    lame_set_debugf(lgf,errorHandler);
    lame_set_msgf(lgf,errorHandler);


    return TRUE;

}

我在inBuf上使用了测试代码来打印出所有数据,看起来是正确的。当我在lame_encode_buffer上有一个断点时,所有参数都被赋值给它们的正确值(即没有零指针)。

我猜这更像是我使用错误的方法或给函数输入了错误的输入类型,但由于没有很好的演练,我真的没有线索。

编辑(Backtrace)

#0  0x96e6ae42 in __kill ()
#1  0x96e6ae34 in kill$UNIX2003 ()
#2  0x96edd23a in raise ()
#3  0x96ee9679 in abort ()
#4  0x96ede3db in __assert_rtn ()
#5  0x000938ca in convert_partition2scalefac_l (gfc=0x146ca000, eb=0xbfff3c38, thr=0xbfff3d3c, chn=0) at psymodel.c:498
#6  0x00097c0b in L3psycho_anal_ns (gfp=0x877000, buffer=0xbfff8cac, gr_out=0, ms_ratio=0x146d6eb4, ms_ratio_next=0xbfffcb9c, masking_ratio=0xbfffd390, masking_MS_ratio=0xbfffcbf0, percep_entropy=0xbfffcbb0, percep_MS_entropy=0xbfffcba0, energy=0xbfffcbc8, blocktype_d=0xbfffac24) at psymodel.c:1712
#7  0x00086fa0 in lame_encode_mp3_frame (gfp=0x877000, inbuf_l=0x146ca010, inbuf_r=0x146cde50, mp3buf=0x877800 "", mp3buf_size=9537) at encoder.c:374
#8  0x0008a6e1 in lame_encode_frame (gfp=0x877000, inbuf_l=0x0, inbuf_r=0x0, mp3buf=0x0, mp3buf_size=0) at lame.c:1364
#9  0x0008ab57 in lame_encode_buffer_sample_t (gfp=0x877000, buffer_l=0x146f5000, buffer_r=0x160c0000, nsamples=0, mp3buf=0x877800 "", mp3buf_size=9537) at lame.c:1541
#10 0x0008ad6e in lame_encode_buffer (gfp=0x877000, buffer_l=0xbfffdcb0, buffer_r=0xbfffe5b0, nsamples=576, mp3buf=0x877800 "", mp3buf_size=9537) at lame.c:1591
#11 0x0008ca3f in lame_encode_flush (gfp=0x877000, mp3buffer=0x877000 "\377\377\377\377\001", mp3buffer_size=9537) at lame.c:1869
#12 0x00011d25 in -[MP3EncodingService encodeWave:] (self=0x1d96e0, _cmd=0x14c9f, wav=0x14712460) at /Users/tim/sp/MP3EncodingService.m:50
#13 0x0000edfb in -[LibraryController convert:] (self=0x1887f0, _cmd=0x15046, sender=0x198480) at /Users/tim/sp/LibraryController.m:908
#14 0x93a794cb in -[NSApplication sendAction:to:from:] ()
#15 0x93a79408 in -[NSControl sendAction:to:] ()
#16 0x93a7928e in -[NSCell _sendActionFrom:] ()
#17 0x93a788e7 in -[NSCell trackMouse:inRect:ofView:untilMouseUp:] ()
#18 0x93a7813a in -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] ()
#19 0x93a779f4 in -[NSControl mouseDown:] ()
#20 0x93a76133 in -[NSWindow sendEvent:] ()
#21 0x93a42cd9 in -[NSApplication sendEvent:] ()
#22 0x939a062f in -[NSApplication run] ()
#23 0x9396d834 in NSApplicationMain ()
#24 0x0000292c in main (argc=1, argv=0xbffff748) at /Users/tim/sp/main.m:13

1 个答案:

答案 0 :(得分:2)

很难说。你可能超越了阵列。由于您的输出数组似乎具有正确的长度,因此它可能是输入数组。如果您很幸运,只需尝试将n_samples / 2(因为2 == sizeof(短))而不是n_samples作为lame_encode_buffer的参数。

找到解决问题的真正,认真的方法是:

  1. 使用调试信息(编译器的-g选项)重新编译您的lame库,以便在gdb backtrace中获得有用的行信息。
  2. 然后,再次获取gdb backtrace,看看你是否可以分辨出段错误的来源。
  3. valgrind下运行,这将告诉您非法访问的位置(因为第一次非法访问时可能不会发生段错误。)
  4. 我敢打赌它与您传递的数组长度有关,但是:)