2014-08-28 91 views
3

我有一個AudioRecord寫入數據庫的線程。現在我想在某些時間間隔使用緩衝區中的一些音頻數據,並使用FFT進行處理。我想發送音頻緩衝區到FFT作爲參數。AudioRecord:如何使用通用緩衝區來處理和存儲?

當我嘗試使用公用緩衝區時,它給我libc錯誤。我如何使用公共緩衝區將它傳遞給FFT並將其寫入存儲?

當我嘗試使用不同的讀取調用有數據丟失的情況,因此不能使用它。

以下是我的代碼

public void start() { 
     startRecording(); 
     _isRecording = true; 

     _recordingThread = new Thread(new Runnable() { 

      public void run() { 

       writeAudioDataToFile(); 

      } 
     }, "AudioRecorder Thread"); 
     _recordingThread.start(); 
    } 

private void writeAudioDataToFile() { 

     while (_isRecording) { 
      // gets the voice output from microphone to byte format 
      count = read(sData, 0, blockSize); 
      byte bData[] = short2byte(sData); 
      WriteToFileAsync.getInstance().writeToFile(bData, 0, 
        blockSize * bytePerElement); 
     } 
    } 

和我通過緩衝使用公用緩衝區SDATA到FFT。

sb = ShortBuffer.allocate(blockSize); 
      sb.put(audioRecorder.sData); 

/************ NATIVE DATA/SIGNAL PROCESSING TASK *************/ 
int pitch = ProcessAudio.process(sb, processed, audioRecorder.count 
        /Short.SIZE * Byte.SIZE); 

以下是我的C代碼

int i; 
int j; 
short* inBuf = (short*) (*env)->GetDirectBufferAddress(env, inbuf); 
double* outBuf = (double*) (*env)->GetDirectBufferAddress(env, outbuf); 

int outval = 0; 
double temp_sum; 
double xcorr[N]; 

int f = 8000; //8000 
int lowr = floor(f/500); 
int upr = ceil(f/75); 
int maxv = 0; 
int maxp = 0; 
int temp_sum1; 
double temp_sum2; 

//voice detection 
temp_sum2 = 0; 
for (i = 0; i < N; i++) { 
    temp_sum2 = temp_sum2 + (double) inBuf[i] * (double) inBuf[i]; 
} 

if (temp_sum2 > 50000000) { //50000000 

    // autocorrelation 
    for (i = 0; i < N; i++) { 
     temp_sum1 = 0; 
     for (j = 0; j <= N - i - 1; j++) { 
      temp_sum1 = temp_sum1 + inBuf[i + j] * inBuf[j]; 
     } 
     xcorr[i] = temp_sum1; 
    } 

    maxv = xcorr[lowr]; 
    maxp = lowr; 
    for (i = lowr; i <= upr; i++) { 
     if (xcorr[i] > maxv) { 
      maxv = xcorr[i]; 
      maxp = i; 
     } 
    } 

    outval = (int) f/maxp; 

    /***************************** Jian Chen ********************************/ 
    double w[N]; 
    double temp[N]; 
    for (i = 0; i < N; i++) { 
     w[i] = 0.54 - 0.45 * cos(2 * 3.1415926 * i/N); 
    } 
    for (i = 0; i < N; i++) { 
     temp[i] = ((double) inBuf[i]) * w[i]; 
    } 
    fftw_plan my_plan; 
    fftw_complex *in, *out; 
    /*in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*2*N); 
    out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*2*N); 
    my_plan = fftw_plan_dft_1d(2*N, in, out, FFTW_FORWARD, FFTW_ESTIMATE); 
    */ 
    in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * 16 * N); //2 
    out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * 16 * N); //2 
    my_plan = fftw_plan_dft_1d(16 * N, in, out, FFTW_FORWARD, 
      FFTW_ESTIMATE); //2 

    for (i = 0; i < N; i++) { 
     in[i][0] = temp[i]; 
     in[i][1] = 0; 
    } 
    for (i = N; i < (16 * N); i++) //2*N 
      { 
     in[i][0] = 0; 
     in[i][1] = 0; 
    } 

    fftw_execute(my_plan); 

    double temp1[N]; 
    for (i = 0; i < N; i++) { 
     temp1[i] = log10(out[i][0] * out[i][0] + out[i][1] * out[i][1]); 

     if (temp1[i] > 12) { 
      temp1[i] = 12; 
     } else if (temp1[i] < 7) { 
      temp1[i] = 7; 
     } 
     outBuf[i] = (temp1[i] * 0.2) - 1.4; //(12.5 6.5;1/6 5/6) (1/6 -1; 12,6) 

     // overwrite to emphasize the pitch 
     // *8*4000 now // 
     if ((i - (int) ((double) outval * (double) 128/(double) 4000 * 16)) 
       < 4 
       && (i 
         - (int) ((double) outval * (double) 128 
           /(double) 4000 * 16)) > 0) 
      outBuf[i] = 1; 

    } 

    fftw_destroy_plan(my_plan); 
    fftw_free(in); 
    fftw_free(out); 
    return outval; 
    //return temp_sum2; 

} else { 
    for (i = 0; i < N; i++) { 
     outBuf[i] = 0; 
    } 
    return outval = 0; 
} 

但是這個代碼給我的libc錯誤Fatal Signal 11 code = 1

任何人都可以指出我的錯誤?

+0

致命信號11代碼= 1,兩個線程試圖同時訪問相同的內存,所以在你的代碼中,並行運行的線程正在訪問公共變量。檢查您的代碼是否相同。 – 2014-09-03 11:29:14

+0

使用buffer.clone()來傳遞具有不同內存位置的緩衝區仍然是相同的問題。 – Neji 2014-09-03 11:49:19

+0

本機代碼中的「inbuf」是什麼?它是「ProcessAudio.process」(即'sb')的第一個參數嗎? AFAIK'ShortBuffer.allocate'不返回直接緩衝區,如果你傳遞一個非直接緩衝區到'GetDirectBufferAddress',它將返回'NULL'。 – Michael 2014-09-08 08:12:05

回答

0

我想你的C代碼NinBuff ant中的短褲數量,它是函數process的第三個參數。爲什麼你使用audioRecorder.count/ Short.SIZE * Byte.SIZE作爲第三個參數。它不應該只是audioRecorder.countAudioRecorder'sread()方法返回如果用戶緩衝區短路作爲輸入參數讀取短路的數量。

您還可以檢查this SO question以查看哪行代碼提供例外。