2014-01-14 18 views
2

此代碼旨在打開opensl_es音頻記錄,捕獲單聲道的流,複製流並分別處理左聲道和右聲道,然後將兩個聲道混合成稍後的輸出流使用opensl_es也是如此。彙編代碼的原因是因爲我在混合函數中發現了一個瓶頸,我之前在c中寫過這是一個簡單的循環將左右緩衝區加入輸出緩衝區ARM內聯彙編代碼在運行時無法正常工作

那麼這個問題很奇怪,我把我得到的輸出流中的日誌正是我想要的,左右緩衝區混合工作,我在日誌中看到它,當我嘗試播放應用程序崩潰時的流時,每當我評論日誌時也會發生同樣的情況,由於某種原因,應用程序崩潰,所以我開始認爲它與我正在使用的寄存器或彙編代碼中的某些東西有關,我是裝配新手,因此有什麼我缺少有關手臂裝配的信息嗎?

任何想法爲什麼發生這種情況,或者我應該如何解決這個問題?

這裏是代碼:第一個功能是我用來捕獲聲音呼叫處理功能的主要功能。第二個「mux」是內嵌程序集的功能。

void start_playing() 
{ 
    OPENSL_STREAM *pStream; 
    int samps, i, j; 
    short inbuffer[VECSAMPS_MONO], outbuffer[VECSAMPS_STEREO]; 
    pStream = android_OpenAudioDevice(SR,1,2,BUFFERFRAMES); 
    if(pStream == NULL) 
    { 
     return; 
    } 

    on = 1; 
    iLog = 0; 
    while (on) 
    { 
     samps = android_AudioInRaw(pStream,inbuffer,VECSAMPS_MONO); //audio recording 
     //signal processing process called here for left channel then for right channel (equalizing, etc) 
     mux(inbuffer, inbuffer, outbuffer,VECSAMPS_MONO); //Assembly mixing of left and right channel into output channel 
     //android_AudioOutRaw(pStream,outbuffer,samps*2);//audio playing 
    } 

    android_CloseAudioDevice(pStream); 
} 


//assembly function here 
void mux(short *pLeftBuf, short *pRightBuf, short *pOutBuf, int vecsamps_mono) 
{ 
    int *pIter; 
    *pIter = vecsamps_mono/4; 

    __android_log_print(ANDROID_LOG_INFO, "$$$$$$$$$$$$", "value : %d , %d , %d , %d",pLeftBuf[0],pLeftBuf[1], pRightBuf[0],pRightBuf[1]); 

    asm volatile(
     "ldr r9, %[outbuf];" 
     "ldr r0, %[leftbuf];" 
     "ldr r1, %[rightbuf];" 
     "ldr r2, %[iter];" 
     "ldr r8, [r2];" 

     "loop: " 

     "ldr r2, [r0];" 
     "ldr r3, [r1];" 

     "ldr r7, =0xffff;" 

     "and r4, r2, r7;" 
     "and r5, r3, r7;" 
     "lsl r5, r5, #16;" 
     "orr r4, r4, r5;" 

     "lsl r7, r7, #16;" 

     "and r5, r2, r7;" 
     "and r6, r3, r7;" 
     "lsr r6, r6, #16;" 
     "orr r5, r5, r6;" 

     "str r4, [r9];" 
     "str r5, [r9, #4];" 

     "add r0, r0, #4;" 
     "add r1, r1, #4;" 
     "add r9, r9, #8;" 

     "subs r8, r8, #1;" 
     "bne loop" 
       :[outbuf] "=m" (pOutBuf) 
       :[leftbuf] "m" (pLeftBuf) ,[rightbuf] "m" (pRightBuf),[iter] "m" (pIter) 
       :"r0","r1","r2","r3","r4","r5","r8","r9","memory","cc" 
     ); 
    __android_log_print(ANDROID_LOG_INFO, "##################", "value : %d , %d , %d , %d" ,*pOutBuf,*(pOutBuf+1),*(pOutBuf+2) ,*(pOutBuf+3)); 
} 

有什麼建議嗎? 這是錯誤i的logcat中得到:在00000000(代碼= 1),螺紋16178(線程致命信號11(SIGSEGV):

11月1日至14日:41:40.992:A/libc的(16161) -4783)

+0

你會得到什麼樣的錯誤? (PS:停止使用這些可怕的選項卡。) –

+0

@意義事項我更新了帖子,發現我在logcat中得到的錯誤 – alexm

+0

你應該看看你生成的目標文件。你可能會看到唯一產生的是第一個ldr r9。問題是你使用';'在每個彙編語句結束時,它會在彙編中開始一個註釋,但不會結束行,所以最後你會得到一條帶有註釋的指令。你必須用'\ n'結束每一行。但除非你想這是一個練習,你應該堅持使用C代碼。據我所知,一個體面的編譯器應該能夠輕鬆勝過你的代碼。 –

回答

2
*pIter = vecsamps_mono/4; 
... 
    "ldr r2, %[iter];" 
    "ldr r8, [r2];" 
... 
    ...[iter] "m" (pIter) 

也許,只是也許vecsamps_mono不是4次有效的內存地址。

不是你甚至可以得到那麼多,在第一行中取消引用未初始化的指針。

+0

它看起來也不需要是指針。最終,你只需要'R8'中的值'vecsamps_mono/4',所以只要將它作爲指針傳遞(在未初始化的解引用之上)就可以解引用來獲得它的值,這似乎是多餘的。 – rjp