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

半世苍凉 提交于 2020-01-13 17:08:54

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/25548166/audiorecord-how-can-i-use-a-common-buffer-to-use-it-for-processing-and-storing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!