데이터베이스에 쓰는 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의 오류를 준다?
치명적인 신호 11 코드 = 1, 두 스레드가 같은 시간에 동일한 메모리에 액세스하려고하므로 코드가 병렬로 실행되는 스레드가 공통 변수에 액세스하고 있습니다. 동일한 코드를 확인하십시오. –
은 buffer.clone()을 사용하여 다른 메모리 위치의 버퍼를 전달하는 데 여전히 같은 문제가 있습니다. – Neji
네이티브 코드에서'inbuf' 란 무엇입니까? ProcessAudio.process' (즉'sb')의 첫 번째 인수입니까? AFAIK'ShortBuffer.allocate'는 다이렉트 버퍼를 리턴하지 않고, 다이렉트 버퍼를'GetDirectBufferAddress'에 전달하면'NULL'을 리턴합니다. – Michael