3

I have an AudioRecord thread that writes to database. Now I want to use some audio data in buffer at some intervals and process it using FFT. I want to send audio buffer to FFT as parameter.

When I am trying to use a common buffer then its giving me libc error. How can I use a common buffer to pass it to FFT and also write it to a storage?

When I tried using different read calls there was situation of data loss and hence cant use that.

Following is my code

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);
        }
    }

and I pass buffer to fft using the common buffer sdata.

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);

Following is my c code

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;
}

but this code gives me libc error Fatal Signal 11 code = 1

Can anyone point my mistake?

Dmytro Plekhotkin
  • 1,965
  • 2
  • 23
  • 47
Neji
  • 6,591
  • 5
  • 43
  • 66
  • Fatal Signal 11 code = 1, Two threads trying to access the same memory at the same time, so in your code, the threads running parallel, are accessing the common variable. Check your code for the same. – jitain sharma Sep 03 '14 at 11:29
  • used buffer.clone() to pass buffer with different memory locations still same issue. – Neji Sep 03 '14 at 11:49
  • What is `inbuf` in the native code? Is it the first argument to `ProcessAudio.process` (i.e. `sb`)? AFAIK `ShortBuffer.allocate` doesn't return a direct buffer, and if you pass a non-direct buffer to `GetDirectBufferAddress` it will return `NULL`. – Michael Sep 08 '14 at 08:12
  • @Michael yes it is the first argument of the function – Neji Sep 09 '14 at 06:57
  • Well, that's something you'll probably have to fix then. – Michael Sep 09 '14 at 07:44

1 Answers1

0

I suppose that in your C code N is the number of shorts in inBuff ant that is the third parameter of the function process. And why do you use audioRecorder.count/ Short.SIZE * Byte.SIZE as third parameter. Shouldn't it be just audioRecorder.count. AudioRecorder's read() method returns the number of shorts read if you user buffer oh shorts as input parameter.

You could also check this SO question to see what line of code give the exception.

Community
  • 1
  • 1
sinisha
  • 1,013
  • 13
  • 30