AudioRecord : How can I use a common buffer to use it for processing and storing?
Asked Answered
F

1

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?

Flimsy answered 28/8, 2014 at 11:54 Comment(5)
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.Blacking
used buffer.clone() to pass buffer with different memory locations still same issue.Flimsy
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.Yaupon
@Yaupon yes it is the first argument of the functionFlimsy
Well, that's something you'll probably have to fix then.Yaupon
P
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.

Parlance answered 3/9, 2014 at 11:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.