I have a code to compute real-time dB Amplitude of AudioRecord. The code works well for computing dB Amplitude. After recording, I save that it to wav file. Now, I want to playback that file and recompute the dB Amplitude. However, I cannot achieve similar result before. Could you help me to fix it. This is my code to compute dB Amplitude when recording and playback.
1.Compute dB amplitude when recording
bufferSize = AudioRecord.getMinBufferSize(16000, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufferSize);
audioBuffer = new short[bufferSize];
readSize=record.read(audioBuffer, 0, audioBuffer.length);
double amplitude = 0;
double sum=0;
for (int i = 0; i < readSize; i++) {
sum += audioBuffer[i] * audioBuffer[i];
}
amplitude = sum / readSize;
dbAmp=20.0 *Math.log10(amplitude/32767.0);
2.Assume that the file output is ouput.wav. I used MediaPlayer to playback and compute Amplitude
String filePath = Environment.getExternalStorageDirectory().getPath() +"/" +"output.wav";
mPlayer = new MediaPlayer();
mPlayer.setDataSource(filePath);
mPlayer.prepare();
mPlayer.start();
mVisualizerView.link(mPlayer);
In which, mVisualizerView is Visualizer class. The class has link function such as
public void link(MediaPlayer player)
{
// Create the Visualizer object and attach it to our media player.
mVisualizer = new Visualizer(player.getAudioSessionId());
mVisualizer.setScalingMode(Visualizer.SCALING_MODE_NORMALIZED);
mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
// Pass through Visualizer data to VisualizerView
Visualizer.OnDataCaptureListener captureListener = new Visualizer.OnDataCaptureListener()
{
@Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes,
int samplingRate)
{
updateVisualizer(bytes);
}
@Override
public void onFftDataCapture(Visualizer visualizer, byte[] bytes,
int samplingRate)
{
updateVisualizerFFT(bytes);
}
};
mVisualizer.setDataCaptureListener(captureListener,
Visualizer.getMaxCaptureRate() / 2, true, true);
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
{
@Override
public void onCompletion(MediaPlayer mediaPlayer)
{
mVisualizer.setEnabled(false);
}
});
}
As my task, I will recompute dbAmp
from bytes in functions updateVisualizer or updateVisualizerFFT
public void updateVisualizer(byte[] bytes) {
dbAmp = computedbAmp(bytes);
mBytes = bytes;
invalidate();
}
public void updateVisualizerFFT(byte[] bytes) {
dbAmp = computedbAmp(bytes);
mFFTBytes = bytes;
invalidate();
}
public double computedbAmp(byte[] audioData) {
//System.out.println("::::: audioData :::::"+audioData);
double amplitude = 0;
for (int i = 0; i < audioData.length/2; i++) {
double y = (audioData[i*2] | audioData[i*2+1] << 8) / 32768.0;
// depending on your endianness:
// double y = (audioData[i*2]<<8 | audioData[i*2+1]) / 32768.0
amplitude += Math.abs(y);
}
amplitude = amplitude / audioData.length / 2;
return amplitude;
}
Currently, I apply some way to compute dB amplitude from bytes. However, they are not correct. Could you help me to fix it or suggest to me the solution to compute it? Thanks
My expected solution such as Sensor Box for Android