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!