问题描述
我需要你的帮助.我正在尝试使用 Androids AudioRecord 类录制一些音频.大多数情况下这工作得很好,但有时我会收到 SIGSEGV 错误.
I need your help. I'm trying to record some audio with Androids AudioRecord class. Most time this works very well but sometimes I get a SIGSEGV error.
这是在录制音频时在单独的线程中运行的代码:
Here is the code which runs in a seperate Thread while recording audio:
private void startRecording() {
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING, bufferSize);
recorder.startRecording();
isRecording = true;
recordingThread = new Thread(new Runnable() {
@Override
public void run() {
writeAudioDataToFile();
}
}, "AudioRecorder Thread");
recordingThread.start();
}
private void writeAudioDataToFile() {
byte data[] = new byte[bufferSize];
String filename = getTempFilename();
FileOutputStream os = null;
try {
os = new FileOutputStream(filename);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int read = 0;
if (null != os) {
while (isRecording) {
read = recorder.read(data, 0, bufferSize);
if (AudioRecord.ERROR_INVALID_OPERATION != read) {
try {
os.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
os.close();
os.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
当录制停止时,我会这样做:
And here is what I do, when the recording stops:
public void stopRecording() {
if (null != recorder) {
isRecording = false;
mRecordingBlocked = true;
mProgressDialog = RecorderDialog.newInstance();
mProgressDialog.show(getFragmentManager(), "progressDialog");
recorder.stop();
recorder.release();
recorder = null;
recordingThread = null;
new Thread(new Runnable() {
@Override
public void run() {
String fileName = getFilename();
copyWaveFile(getTempFilename(), fileName);
final TelephonyManager tm = (TelephonyManager) getActivity().getBaseContext().getSystemService(Context.TELEPHONY_SERVICE);
final String tmDevice, tmSerial, androidId;
tmDevice = "" + tm.getDeviceId();
tmSerial = "" + tm.getSimSerialNumber();
androidId = "" + android.provider.Settings.Secure.getString(getActivity().getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
UUID deviceUuid = new UUID(androidId.hashCode(), ((long) tmDevice.hashCode() << 32) | tmSerial.hashCode());
String deviceId = deviceUuid.toString();
App.db.insertEntry(deviceId, "Song title", fileName);
deleteTempFile();
if (cbox_overdub.isChecked()) {
phrases.add(playAudio(fileName, true));
}
}
}).start();
}
}
private void copyWaveFile(String inFilename, String outFilename) {
FileInputStream in;
FileOutputStream out;
long totalAudioLen = 0;
long totalDataLen;
long longSampleRate = RECORDER_SAMPLERATE;
int channels = 2;
long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels / 8;
try {
AppLog.logString("begin copyWaveFile try{}");
File file = new File(inFilename);
in = new FileInputStream(file);
byte[] bytes = new byte[(int) file.length()];
totalAudioLen = in.getChannel().size();
totalDataLen = totalAudioLen + 36;
in.read(bytes);
in.close();
out = new FileOutputStream(outFilename);
AppLog.logString("fos created");
WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
longSampleRate, channels, byteRate);
AppLog.logString("wave header written");
int bufferLength = 1024;
publishProgress(0);
for (int i = 0; i < bytes.length; i += bufferLength) {
int progress = (int) ((i / (float) bytes.length) * 100);
publishProgress(progress);
if (bytes.length - i >= bufferLength) {
out.write(bytes, i, bufferLength);
} else {
out.write(bytes, i, bytes.length - i);
}
}
publishProgress(100);
AppLog.logString("progress complete");
mRecordingBlocked = false;
mProgressDialog.dismiss();
out.close();
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
这个错误似乎发生在 AudioRecord 的实例已经停止之后.然后我将临时 temp_record.wav(SD 卡)的内容复制到目标(SD 卡),并设置适当的波形文件头.
It seems this error occurs after the instance of AudioRecord has already been stopped. Then I copy the contents of my temporary temp_record.wav (SD Card) to the destination (SD Card) with setting a proper wave file header.
我无法从以下调试信息中过滤出任何有用的信息.我希望有人有一个想法.谢谢!
I'm not able to filter any useful information out of the following debug information. I hope someone has an idea. Thank you!
这是 Logcat 输出:
06-30 14:47:53.311: INFO/DEBUG(9381): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
06-30 14:47:53.311: INFO/DEBUG(9381): Build fingerprint: 'otorola/RTGB/umts_milestone2:2.3.4/MILS2_U6_4.1-22/1317097892:user/release-keys'
06-30 14:47:53.311: INFO/DEBUG(9381): pid: 9459, tid: 9525 >>> de.intermeco.android.apps.ilaugh <<<
06-30 14:47:53.311: INFO/DEBUG(9381): signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 4640e000
06-30 14:47:53.311: INFO/DEBUG(9381): r0 4640e000 r1 00000000 r2 fffffd49 r3 4670da18
06-30 14:47:53.311: INFO/DEBUG(9381): r4 4640e000 r5 4640e000 r6 fffffd49 r7 4670da18
06-30 14:47:53.311: INFO/DEBUG(9381): r8 a904cf6a r9 0000000a 10 a904cfad fp a904cff0
06-30 14:47:53.311: INFO/DEBUG(9381): ip a9060074 sp 4670d9e0 lr afd11704 pc afd113dc cpsr 20000050
06-30 14:47:53.311: INFO/DEBUG(9381): d0 6472656767756265 d1 0037fff00020000c
06-30 14:47:53.311: INFO/DEBUG(9381): d2 fff5ffd8fff5ffdb d3 ffe0ffd8ffd9ffd8
06-30 14:47:53.311: INFO/DEBUG(9381): d4 fff2ffe50008ffd4 d5 ffdafffafff20000
06-30 14:47:53.311: INFO/DEBUG(9381): d6 fff40003ffcf0003 d7 ffe30013ffe1fffd
06-30 14:47:53.311: INFO/DEBUG(9381): d8 0000000000989680 d9 0000000000000000
06-30 14:47:53.311: INFO/DEBUG(9381): d10 0000000000000000 d11 0000000000000000
06-30 14:47:53.311: INFO/DEBUG(9381): d12 0000000000000000 d13 0000000000000000
06-30 14:47:53.311: INFO/DEBUG(9381): d14 0000000000000000 d15 0000000000000000
06-30 14:47:53.311: INFO/DEBUG(9381): d16 000000c24003a7e0 d17 4000000000000000
06-30 14:47:53.311: INFO/DEBUG(9381): d18 3ff0000000000000 d19 0000000000000000
06-30 14:47:53.311: INFO/DEBUG(9381): d20 b96377ce858a5d48 d21 3929f5135cb87c55
06-30 14:47:53.311: INFO/DEBUG(9381): d22 3e21ee9ebdb4b1c4 d23 bda8fae9be8838d4
06-30 14:47:53.319: INFO/DEBUG(9381): d24 0000000000000000 d25 0000000000000000
06-30 14:47:53.319: INFO/DEBUG(9381): d26 0000000000000000 d27 ffffffffffffffff
06-30 14:47:53.319: INFO/DEBUG(9381): d28 0100010001000100 d29 0100010001000100
06-30 14:47:53.319: INFO/DEBUG(9381): d30 4086800000000000 d31 3ff0000000000000
06-30 14:47:53.319: INFO/DEBUG(9381): scr 60000010
06-30 14:47:53.483: INFO/DEBUG(9381): #00 pc 000113dc /system/lib/libc.so (pthread_mutex_lock)
06-30 14:47:53.483: INFO/DEBUG(9381): #01 pc 00011700 /system/lib/libc.so (__pthread_cond_timedwait_relative)
06-30 14:47:53.483: INFO/DEBUG(9381): #02 pc 0002d658 /system/lib/libmedia.so
06-30 14:47:53.483: INFO/DEBUG(9381): code around pc:
06-30 14:47:53.483: INFO/DEBUG(9381): afd113bc e3a02001 ebfffe82 e1a00005 e8bd87f0
06-30 14:47:53.483: INFO/DEBUG(9381): afd113cc 00036024 e92d47f0 e2504000 0a000019
06-30 14:47:53.483: INFO/DEBUG(9381): afd113dc e5946000 e5947000 e2166903 1a000017
06-30 14:47:53.483: INFO/DEBUG(9381): afd113ec e5945000 e1a02004 e2055a02 e1a00005
06-30 14:47:53.483: INFO/DEBUG(9381): afd113fc e3851001 ebffed7f e3500000 13856002
06-30 14:47:53.483: INFO/DEBUG(9381): code around lr:
06-30 14:47:53.483: INFO/DEBUG(9381): afd116e4 e1a03007 e1a02006 e2011001 e1a00004
06-30 14:47:53.483: INFO/DEBUG(9381): afd116f4 ebfffd9a e1a04000 e1a00005 ebffff32
06-30 14:47:53.483: INFO/DEBUG(9381): afd11704 e374006e 03a0006e 13a00000 e8bd81f0
06-30 14:47:53.483: INFO/DEBUG(9381): afd11714 e304cdd3 e3043240 e92d4010 e341c062
06-30 14:47:53.483: INFO/DEBUG(9381): afd11724 e1a0e002 e24dd008 e340300f e1a0200d
06-30 14:47:53.483: INFO/DEBUG(9381): stack:
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9a0 04000804
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9a4 00000001
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9a8 001c6b58
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9ac 00000262
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9b0 0000ee6b
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9b4 afd0fe34 /system/lib/libc.so
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9b8 001edbb0
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9bc afd13bc1 /system/lib/libc.so
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9c0 001b0470
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9c4 001c6b58
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9c8 00000241
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9cc 3b9aca00
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9d0 00000000
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9d4 00989680
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9d8 df002777
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9dc e3a070ad
06-30 14:47:53.483: INFO/DEBUG(9381): #00 4670d9e0 00000000
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9e4 4640e000
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9e8 fffffd49
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9ec 4670da18
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9f0 a904cf6a /system/lib/libmedia.so
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9f4 0000000a
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9f8 a904cfad /system/lib/libmedia.so
06-30 14:47:53.483: INFO/DEBUG(9381): 4670d9fc afd11704 /system/lib/libc.so
06-30 14:47:53.483: INFO/DEBUG(9381): #01 4670da00 4640e000
06-30 14:47:53.483: INFO/DEBUG(9381): 4670da04 4640e004
06-30 14:47:53.483: INFO/DEBUG(9381): 4670da08 4670da98
06-30 14:47:53.483: INFO/DEBUG(9381): 4670da0c 000000c8
06-30 14:47:53.483: INFO/DEBUG(9381): 4670da10 a904cf6a /system/lib/libmedia.so
06-30 14:47:53.483: INFO/DEBUG(9381): 4670da14 a902d65b /system/lib/libmedia.so
推荐答案
感谢再次指出SIGSEV,我读了一点,因为我不知道它的意思.现在我做:)我同意 CommonsWare 的意见,您应该通知固件的制造商/修改者.但我也认为它不会在有用的时间跨度内进一步帮助你.也许我们会找到一种方法来修改您的代码,从而不再引发错误.
Thanks for pointing out SIGSEV again, i over read it a little because i didn't know its meaning. Now i do :) I agree with CommonsWare that you should inform the manufacturer/modder of the firmware. But i also think it does not help you further in a useful time span. Maybe we find a way to modify your code in a way not to provoke the error anymore.
一般来说,您的代码看起来相当不错.我认为不完全安全和正确的是您停止录音机的方式.
Generally your code looks quite good. What i think is not totally safe and proper is the way you are stopping the recorder.
- 我不使用 isRecording 标志,而是使用 isCancelled 标志.所以你记录 while(!isCancelled).当您想停止录制时,只需将 isCancelled 设置为 true 并调用 recorder.stop().
- 录音停止后,您可以在录音机线程中的 writeAudioDataToFile() 之后立即调用您的逻辑来显示进度对话框和复制文件.我不会为这些事情使用额外的线程,因为我们仍在录音机线程中,并且您的 UI 没有被阻塞.
- 何时调用 recorder.release(),它会释放内存...文档释放原生 AudioRecord 资源".我不知道这是否对问题有影响.在您提供的当前代码中,您调用 recorder.release() 而理论上记录器可以读取(不知道该类是否是线程安全的).也许您也可以在复制所有文件后尝试调用它,即使我认为在记录器真正停止并且您的输出流关闭后应该没问题.
希望我能帮上一点忙,你能找到办法.
Hope i could help a little and you are able to find a way.
这篇关于录制音频时出现Android SIGSEGV错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!