如何在Android上检测恒定响度的声音的声级
我正在开发一个应用程序,该应用程序应该在某个时刻显示 5 秒时间跨度内用户语音输入的响度。该应用程序用于语音训练,因此用户应该能够始终将声音保持在一定的响度级别。
我使用 MediaRecorder 记录用户的输入,在模拟器上它工作得很好。
但是,当我在外部设备(motorola moto g5s)上运行该应用程序时,该应用程序似乎在 2 秒后将响度下调至非常低的恒定值。
我认为问题可能出在 AudioSource 上,所以我将其从 AudioSource.MIC 切换到 AudioSource.UNPROCESSED 但随后它不允许我在移动设备上录制任何内容(在它正在运行的模拟器上)。
这是由于设备音频硬件中的某些过滤器造成的吗?是否有可能解决这个问题,或者问题可能出在完全不同的地方?
单击按钮时会录制音频:
public void onClick(View view) {
// when record button is clicked MediaRecorder will record for 5 seconds
// the time passed recording is shown to the user in the progress bar under the button
if(view.getId() == R.id.btnRecord){
System.out.println("\n record was clicked \n");
// scale volume to range [0:1]
int max_val = Settings_menu.volumeMax;
float noiseNow_scaled = (float) Settings_menu.noiseNow/max_val;
try {
// recording
mediaRecorder = new MediaRecorder();
nativeSampleRate = Integer.parseInt(am.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE));
System.out.println("\n Native sampling rate: " + nativeSampleRate);
//nativeSampleBufSize = Integer.parseInt(am.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER));
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
path = getRecordingFilePath();
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setAudioSamplingRate(nativeSampleRate);
mediaRecorder.setOutputFile(getRecordingFilePath());
mediaRecorder.prepare();
mediaRecorder.start();
// play pink noise for masking auditory feedback
streamID = soundPool.play(pinknoise,noiseNow_scaled , noiseNow_scaled, 0, 0, 1);
} catch (Exception e){
e.printStackTrace();
}
CountDownTimer timer = new CountDownTimer(5000,LoudnessCalibration.interval) {
// the maximum loudness of the recording within a LoudnessCalibration.interval ms interval is computed
// progress bar loads new progress every LoudnessCalibration.interval ms
// progressbar is filled when 5000 is reached
@Override
public void onTick(long l) {
counter += LoudnessCalibration.interval;
pb.setProgress(counter);
amplitudes.add((float) mediaRecorder.getMaxAmplitude());
length ++;
}
// when 5 seconds are over MediaRecorder has to be released & pink noise stops playing
@Override
public void onFinish() {
mediaRecorder.stop();
mediaRecorder.reset();
mediaRecorder.release();
mediaRecorder = null;
soundPool.stop(streamID);
pb.setProgress(0);
counter = 0;
}
}.start();
{...}
}
感谢您对此的任何想法或想法!
I am developing an app which at some point is supposed to display the loudness of the user's voice input over a time span of 5s. The app is meant for voice training so the user is supposed to be able to hold the sound on a certain loudness level for the whole time.
I used MediaRecorder to record the user's input and on the Emulator it is working completely fine.
However, when I run the app on an external device (motorola moto g5s), the app seems to downregulate the loudness after 2 s to a very low constant value.
I thought that the problem might be the AudioSource so I switched it from AudioSource.MIC to AudioSource.UNPROCESSED but then it didn't let me record anything on the mobile device (on the emulator it was working).
Is this due to some filter in the audio hardware of the device? Is it possible to fix this or might the problem lay somewhere completely different?
The Audio is recorded when a button is clicked:
public void onClick(View view) {
// when record button is clicked MediaRecorder will record for 5 seconds
// the time passed recording is shown to the user in the progress bar under the button
if(view.getId() == R.id.btnRecord){
System.out.println("\n record was clicked \n");
// scale volume to range [0:1]
int max_val = Settings_menu.volumeMax;
float noiseNow_scaled = (float) Settings_menu.noiseNow/max_val;
try {
// recording
mediaRecorder = new MediaRecorder();
nativeSampleRate = Integer.parseInt(am.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE));
System.out.println("\n Native sampling rate: " + nativeSampleRate);
//nativeSampleBufSize = Integer.parseInt(am.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER));
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
path = getRecordingFilePath();
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setAudioSamplingRate(nativeSampleRate);
mediaRecorder.setOutputFile(getRecordingFilePath());
mediaRecorder.prepare();
mediaRecorder.start();
// play pink noise for masking auditory feedback
streamID = soundPool.play(pinknoise,noiseNow_scaled , noiseNow_scaled, 0, 0, 1);
} catch (Exception e){
e.printStackTrace();
}
CountDownTimer timer = new CountDownTimer(5000,LoudnessCalibration.interval) {
// the maximum loudness of the recording within a LoudnessCalibration.interval ms interval is computed
// progress bar loads new progress every LoudnessCalibration.interval ms
// progressbar is filled when 5000 is reached
@Override
public void onTick(long l) {
counter += LoudnessCalibration.interval;
pb.setProgress(counter);
amplitudes.add((float) mediaRecorder.getMaxAmplitude());
length ++;
}
// when 5 seconds are over MediaRecorder has to be released & pink noise stops playing
@Override
public void onFinish() {
mediaRecorder.stop();
mediaRecorder.reset();
mediaRecorder.release();
mediaRecorder = null;
soundPool.stop(streamID);
pb.setProgress(0);
counter = 0;
}
}.start();
{...}
}
Thank you for any ideas or thoughts on this!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论