【问题标题】:AudioRecord : How can I use a common buffer to use it for processing and storing?AudioRecord:如何使用通用缓冲区来处理和存储?
【发布时间】:2014-09-08 15:32:41
【问题描述】:

我有一个写入数据库的AudioRecord 线程。现在我想每隔一段时间使用缓冲区中的一些音频数据,并使用 FFT 对其进行处理。我想将音频缓冲区作为参数发送到 FFT

当我尝试使用公共缓冲区时,它给了我 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

谁能指出我的错误?

【问题讨论】:

  • 致命信号 11 代码 = 1,两个线程试图同时访问同一内存,因此在您的代码中,并行运行的线程正在访问公共变量。检查您的代码是否相同。
  • 使用 buffer.clone() 传递不同内存位置的缓冲区仍然是同样的问题。
  • 原生代码中的inbuf是什么?它是ProcessAudio.process(即sb)的第一个参数吗? AFAIK ShortBuffer.allocate 不返回直接缓冲区,如果您将非直接缓冲区传递给 GetDirectBufferAddress,它将返回 NULL
  • @Michael 是的,它是函数的第一个参数
  • 嗯,那是你可能必须解决的问题。

标签: android multithreading performance java-native-interface fftw


【解决方案1】:

我想在你的 C 代码中 NinBuff ant 中的短裤数量,它是函数 process 的第三个参数。以及为什么使用audioRecorder.count/ Short.SIZE * Byte.SIZE 作为第三个参数。不应该只是audioRecorder.countAudioRecorder's read() 方法返回读取的短裤数量,如果您将用户缓冲哦短裤作为输入参数。

您还可以检查this SO question 以查看哪一行代码给出了异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-26
    • 2013-07-21
    • 1970-01-01
    • 2012-11-09
    • 2012-09-17
    • 2021-04-01
    • 2011-07-11
    相关资源
    最近更新 更多