2010-02-24 147 views
2

我使用lame編碼器在mac osx中使用objective-c和cocoa將wav轉換爲mp3。在音頻編碼方面,我是一個完全新手,而我的C技能並不好。無論我是否偶然發現並進入了實際的編碼階段,這就是我陷入困境的地方。EXC_BAD_ACCESS當調用lame_encode_buffer

從我研究過的代碼看來,我應該使用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上有一箇中斷點時,所有的參數都被賦值爲正確的值(即沒有零指針)。

我猜這是更多的我使用錯誤的方法或給函數的錯誤類型的輸入,但沒有好的演練在這可用,我真的不知道。

編輯(回溯)

#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 
+0

運行這一點 - 當你得到一個崩潰,然後使用「BT」命令來獲得回溯。 – 2010-02-24 13:45:03

+0

我已將它添加進去。雖然看不到任何有用的東西。 – Septih 2010-02-24 14:05:48

+0

該解決方案適合您嗎?如果是這樣,請接受。否則,告訴我們在你遵循1.2.3點後發生了什麼,所以我們可以給予更多的幫助。 – 2010-03-07 13:58:42

回答

2

很難說。你可能超越了一個數組。由於看起來你的輸出數組長度合適,可能是輸入數組。如果您幸運的話,只需嘗試給n_samples/2(因爲2 == sizeof(short))而不是n_samples作爲lame_encode_buffer的參數。

真正的,嚴肅的方式找到一個解決問題的方法是:

  1. 重新編譯與調試信息(-g選項編譯)跛庫,以便你在你的GDB回溯有用的行信息。
  2. 然後,再次獲取gdb回溯,看看是否可以知道段錯誤來自哪裏。
  3. valgrind下運行此命令,它會告訴您非法訪問發生在哪裏(因爲第一次非法訪問時可能不會發生段錯誤)。

我打賭它是與你通過數組的長度,雖然在gdb下:)

+0

正確,使用n_samples/2它最初停止了異常,但產生了一個垃圾mp3 - 一旦啓用調試後它會停止工作。我更新了原始文章中的回溯,其中包含調試數據 - 表明問題發生在lame_encode_flush中。在valgrind下運行表明,在lame_encode_buffer中出現了一些問題,包括幾個無效的指針大小(「無效的寫入大小1 」)和幾個未定義變量的用法(「條件跳轉或移動取決於未初始化的值」)死亡。 – Septih 2010-03-08 10:02:17

+0

因此,它不再是一個段錯誤,它是一個斷言失敗:顯然,你在convert_partition2scalefac_l中得到一個負值的閾值總和,這當然不是預期的。你確定你的輸入數據格式正確嗎? 另一個想法是,在缺乏良好演練的情況下:通過在Google codesearch(www.google.com/codesearch)搜索「lame_encode_buffer」來查看大量示例 – 2010-03-08 10:15:34

+0

我已經查看了很多來自codesearch的示例(雖然8/10的結果是庫本身),重複的主題是,很難辨別他們如何建立他們的輸入數據,因爲通常這些項目將許多格式轉換爲MP3,而不僅僅是wav。無論如何,我會繼續研究,感謝您的調試幫助。 – Septih 2010-03-08 11:48:50

相關問題