Ứng dụng Java Android của tôi cần ghi lại dữ liệu âm thanh vào RAM và xử lý nó. Đây là lý do tại sao tôi sử dụng lớp "AudioRecord" chứ không phải "MediaRecorder" (chỉ ghi vào tệp).Android: AudioRecord Class Sự cố: Gọi lại không bao giờ được gọi là
Cho đến bây giờ, tôi đã sử dụng cuộc gọi vòng lặp bận với "read()" cho dữ liệu âm thanh. điều này đã được làm việc cho đến nay, nhưng nó peggs CPU quá nhiều. Giữa hai cuộc thăm dò ý kiến, tôi đặt chỉ vào giấc ngủ để tránh sử dụng CPU 100%. Tuy nhiên, đây không thực sự là giải pháp sạch, vì thời gian ngủ là không được đảm bảo và bạn phải trừ thời gian bảo mật để không bị mất âm thanh đoạn trích. Đây không phải là CPU tối ưu. Tôi cần càng nhiều chu kỳ CPU miễn phí càng tốt cho một luồng chạy song song.
Bây giờ tôi đã triển khai bản ghi bằng cách sử dụng "OnRecordPositionUpdateListener". Điều này có vẻ rất hứa hẹn và đúng cách để làm điều đó theo SDK Tài liệu. Mọi thứ dường như hoạt động (mở thiết bị âm thanh, đọc() ing dữ liệu, v.v.) nhưng Trình nghe không bao giờ được gọi.
Có ai biết tại sao không?
Thông tin: Tôi đang làm việc với một Thiết bị thực, không phải trong Trình giả lập. Việc ghi âm bằng cách sử dụng một Busy Loop cơ bản hoạt động (tuy nhiên không satifiying). Chỉ có Trình nghe gọi lại không bao giờ được gọi.
Dưới đây là một đoạn trích từ sourcecode của tôi:
public class myApplication extends Activity {
/* audio recording */
private static final int AUDIO_SAMPLE_FREQ = 16000;
private static final int AUDIO_BUFFER_BYTESIZE = AUDIO_SAMPLE_FREQ * 2 * 3; // = 3000ms
private static final int AUDIO_BUFFER_SAMPLEREAD_SIZE = AUDIO_SAMPLE_FREQ/10 * 2; // = 200ms
private short[] mAudioBuffer = null; // audio buffer
private int mSamplesRead; // how many samples are recently read
private AudioRecord mAudioRecorder; // Audio Recorder
...
private OnRecordPositionUpdateListener mRecordListener = new OnRecordPositionUpdateListener() {
public void onPeriodicNotification(AudioRecord recorder) {
mSamplesRead = recorder.read(mAudioBuffer, 0, AUDIO_BUFFER_SAMPLEREAD_SIZE);
if (mSamplesRead > 0) {
// do something here...
}
}
public void onMarkerReached(AudioRecord recorder) {
Error("What? Hu!? Where am I?");
}
};
...
public void onCreate(Bundle savedInstanceState) {
try {
mAudioRecorder = new AudioRecord(
android.media.MediaRecorder.AudioSource.MIC,
AUDIO_SAMPLE_FREQ,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
AUDIO_BUFFER_BYTESIZE);
} catch (Exception e) {
Error("Unable to init audio recording!");
}
mAudioBuffer = new short[AUDIO_BUFFER_SAMPLEREAD_SIZE];
mAudioRecorder.setPositionNotificationPeriod(AUDIO_BUFFER_SAMPLEREAD_SIZE);
mAudioRecorder.setRecordPositionUpdateListener(mRecordListener);
mAudioRecorder.startRecording();
/* test if I can read anything at all... (and yes, this here works!) */
mSamplesRead = mAudioRecorder.read(mAudioBuffer, 0, AUDIO_BUFFER_SAMPLEREAD_SIZE);
}
}
Cảm ơn bạn - bạn đã giải thích rõ điều này. – chaimp
câu trả lời của bạn rất hữu ích. Tôi đánh giá cao nếu bạn có thể khai sáng cho tôi cách đọc đúng luồng đầu vào trực tiếp từ micrô. Một vòng lặp liên tục trong khi có vẻ không thích hợp vì nó sẽ chặn toàn bộ quá trình, đúng không? Tôi nghĩ rằng các callbacks đã có như một giải pháp, nhưng đánh giá bởi câu trả lời của bạn, họ không. Cảm ơn bạn. – Tom
Vòng lặp liên tục để đọc dữ liệu âm thanh phải nằm trong một chuỗi riêng biệt. Bạn chắc chắn không thể sử dụng chủ đề chính để đọc âm thanh. Các cuộc gọi lại sẽ kích hoạt khi thu thập một lượng dữ liệu âm thanh phù hợp. Bạn có thể đặt logic xử lý vào vòng lặp đọc hoặc bạn có thể sử dụng các cuộc gọi lại để kích hoạt xử lý trên bộ đệm mà bạn vừa đọc.Khối đọc nhưng chỉ trong chuỗi đó, vì vậy bạn sẽ không sao. –