2014-08-28 1 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; 
} 

하지만이 코드는 나에게

사람이 내 실수를 지적 할 수 Fatal Signal 11 code = 1 libc의 오류를 준다?

+0

치명적인 신호 11 코드 = 1, 두 스레드가 같은 시간에 동일한 메모리에 액세스하려고하므로 코드가 병렬로 실행되는 스레드가 공통 변수에 액세스하고 있습니다. 동일한 코드를 확인하십시오. –

+0

은 buffer.clone()을 사용하여 다른 메모리 위치의 버퍼를 전달하는 데 여전히 같은 문제가 있습니다. – Neji

+0

네이티브 코드에서'inbuf' 란 무엇입니까? ProcessAudio.process' (즉'sb')의 첫 번째 인수입니까? AFAIK'ShortBuffer.allocate'는 다이렉트 버퍼를 리턴하지 않고, 다이렉트 버퍼를'GetDirectBufferAddress'에 전달하면'NULL'을 리턴합니다. – Michael

답변

0

당신의 C 코드에서 NinBuff의 반바지로, process의 세 번째 매개 변수 인 것으로 가정합니다. 그리고 세 번째 매개 변수로 audioRecorder.count/ Short.SIZE * Byte.SIZE을 사용하는 이유는 무엇입니까? 그냥 audioRecorder.count이 아니어야합니다. AudioRecorder'sread() 메서드는 사용자가 단락을 입력 매개 변수로 사용하는 경우 읽을 수있는 단락 수를 반환합니다.

this SO question을 검사하여 예외의 코드 줄을 확인할 수도 있습니다.