0

I am trying to run the code from github but my app crash. This code compare take a music input from microphone & compare that audio with database present in app using musicg.

It has two gui button, one start & other stop.

Start- will take input from microphone.

Stop- will stop the recording from mic & compares whether the audio present in it or not.

When I try to run app on my phone & press button, app crashes & give me the error.

Someone can please help me to troubleshoot the problem.

Thanks.:)

Error

java.Iang.NullPointerException:
Attempt to invoke virtual method 'int
com.musicg.wave.WaveHeader.getSampIeRate()' on
a null object reference

at
com.musicg.fingerprint.FingerprintManager.extractFingerprint(FingerprintManager.java:69)

at
com.musicg.wave.Wave.getFingerprint(Wave.java:
329)

at
com.musicg.wave.Wave.getFingerprintSimilarity(Wave.java:335)

at
com.example.tanmay.androidmusicg.MainActivity.co
mpareTempFiIe(MainActivity.java:175)

at
com.example.tanmay.androidmusicg.MainActivity.st
opRecording(MainActivity.java:166)

at
com.example.tanmay.androidmusicg.MainActivity.ac
cess$400(MainActivity.java:26)

at
com.example.tanmay.androidmusichainActivitySZ.
onCIick(MainActivity.java:290)

at android.view.View.performCIick(View.java:6312)

at android.view.View$PerformC|ick.run(View.java:
24811)

at android.os.HandIer.hand|eCa||back(Hand|er.java:
790)

at
android.os.Hand|er.dispatchMessage(Hand|er.java:
99)

at android.os.Looper.|oop(Looper.java:171)

Thanks. :)

Code:-

package com.example.tanmay.androidmusicg;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import com.musicg.fingerprint.FingerprintManager;
import com.musicg.fingerprint.FingerprintSimilarity;
import com.musicg.fingerprint.FingerprintSimilarityComputer;
import com.musicg.wave.Wave;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import se.marteinn.utils.logging.AppLog;

public class MainActivity extends Activity {
private static final int RECORDER_BPP = 16;
private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".wav";
private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
private static final String AUDIO_RECORDER_TEMP_FILE = "record_temp.raw";
private static final int RECORDER_SAMPLERATE = 44100;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private double currentTime;
private AudioRecord recorder = null;
private int bufferSize = 0;
private Thread recordingThread = null;
private boolean isRecording = false;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    setButtonHandlers();
    enableButtons(false);
    bufferSize = AudioRecord.getMinBufferSize(8000,
    AudioFormat.CHANNEL_CONFIGURATION_MONO,
            AudioFormat.ENCODING_PCM_16BIT);

}

private void setButtonHandlers() {
    ((Button)findViewById(R.id.btnStart)).setOnClickListener(btnClick);
    ((Button)findViewById(R.id.btnStop)).setOnClickListener(btnClick);
}

private void enableButton(int id,boolean isEnable){
    ((Button)findViewById(id)).setEnabled(isEnable);
}

private void enableButtons(boolean isRecording) {
    enableButton(R.id.btnStart,!isRecording);
    enableButton(R.id.btnStop,isRecording);
}

private String getFilename(){
    String filepath = Environment.getExternalStorageDirectory().getPath();
    File file = new File(filepath,AUDIO_RECORDER_FOLDER);

    if(!file.exists()){
        file.mkdirs();
    }

    return (file.getAbsolutePath() + "/" + currentTime + AUDIO_RECORDER_FILE_EXT_WAV);
}

private String getTempFilename(){
    String filepath = Environment.getExternalStorageDirectory().getPath();
    File file = new File(filepath,AUDIO_RECORDER_FOLDER);

    if(!file.exists()){
        file.mkdirs();
    }

    File tempFile = new File(filepath,AUDIO_RECORDER_TEMP_FILE);

    if(tempFile.exists())
        tempFile.delete();

    return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE);
}

private void startRecording(){
    recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
            RECORDER_SAMPLERATE, RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING, bufferSize);

    int i = recorder.getState();
    if(i==1)
        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) {
        // TODO Auto-generated catch block
        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();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

private void stopRecording(){
    if(null != recorder){
        isRecording = false;

        int i = recorder.getState();
        if(i==1)
            recorder.stop();
        recorder.release();

        recorder = null;
        recordingThread = null;
    }

    copyWaveFile(getTempFilename(),getFilename());
    compareTempFile();
}

private void compareTempFile() {
    File file = new File(getTempFilename());
    Wave w1 = new Wave(getResources().openRawResource(R.raw.tj));
    Wave w2 = new Wave(file.getPath());
    FingerprintSimilarity fps = w1.getFingerprintSimilarity(w2);
    float score = fps.getScore();
    float sim = fps.getSimilarity();
    AppLog.i(sim+" tj");
}

private void copyWaveFile(String inFilename,String outFilename){
    FileInputStream in = null;
    FileOutputStream out = null;
    long totalAudioLen = 0;
    long totalDataLen = totalAudioLen + 36;
    long longSampleRate = RECORDER_SAMPLERATE;
    int channels = 2;
    long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels/8;

    byte[] data = new byte[bufferSize];

    try {
        in = new FileInputStream(inFilename);
        out = new FileOutputStream(outFilename);
        totalAudioLen = in.getChannel().size();
        totalDataLen = totalAudioLen + 36;

        AppLog.i("File size: ",totalDataLen);

        WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
                longSampleRate, channels, byteRate);

        while(in.read(data) != -1){
            out.write(data);
        }

        in.close();
        out.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void WriteWaveFileHeader(
        FileOutputStream out, long totalAudioLen,
        long totalDataLen, long longSampleRate, int channels,
        long byteRate) throws IOException {

    byte[] header = new byte[44];

    header[0] = 'R';  // RIFF/WAVE header
    header[1] = 'I';
    header[2] = 'F';
    header[3] = 'F';
    header[4] = (byte) (totalDataLen & 0xff);
    header[5] = (byte) ((totalDataLen >> 8) & 0xff);
    header[6] = (byte) ((totalDataLen >> 16) & 0xff);
    header[7] = (byte) ((totalDataLen >> 24) & 0xff);
    header[8] = 'W';
    header[9] = 'A';
    header[10] = 'V';
    header[11] = 'E';
    header[12] = 'f';  // 'fmt ' chunk
    header[13] = 'm';
    header[14] = 't';
    header[15] = ' ';
    header[16] = 16;  // 4 bytes: size of 'fmt ' chunk
    header[17] = 0;
    header[18] = 0;
    header[19] = 0;
    header[20] = 1;  // format = 1
    header[21] = 0;
    header[22] = (byte) channels;
    header[23] = 0;
    header[24] = (byte) (longSampleRate & 0xff);
    header[25] = (byte) ((longSampleRate >> 8) & 0xff);
    header[26] = (byte) ((longSampleRate >> 16) & 0xff);
    header[27] = (byte) ((longSampleRate >> 24) & 0xff);
    header[28] = (byte) (byteRate & 0xff);
    header[29] = (byte) ((byteRate >> 8) & 0xff);
    header[30] = (byte) ((byteRate >> 16) & 0xff);
    header[31] = (byte) ((byteRate >> 24) & 0xff);
    header[32] = (byte) (2 * 16 / 8);  // block align
    header[33] = 0;
    header[34] = RECORDER_BPP;  // bits per sample
    header[35] = 0;
    header[36] = 'd';
    header[37] = 'a';
    header[38] = 't';
    header[39] = 'a';
    header[40] = (byte) (totalAudioLen & 0xff);
    header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
    header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
    header[43] = (byte) ((totalAudioLen >> 24) & 0xff);

    out.write(header, 0, 44);

}

private View.OnClickListener btnClick = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.btnStart:{
                AppLog.i("Start Recording");
                currentTime = System.currentTimeMillis();

                enableButtons(true);
                startRecording();

                break;
            }
            case R.id.btnStop:{

                AppLog.i("Stop Recording");

                enableButtons(false);
                stopRecording();

                break;
            }
        }
    }
};
}
Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
Tanmay Jain
  • 123
  • 1
  • 2
  • 12

1 Answers1

0

It seems that the issue with the getTempFilename() method and directly with these lines:

if(tempFile.exists())
        tempFile.delete();

As you are calling the getTempFilename() method to create a file for AudioRecord object:

    private void writeAudioDataToFile(){
        byte data[] = new byte[bufferSize];
        String filename = getTempFilename();
        FileOutputStream os = null;
        ...

and you are calling the same getTempFilename() method to compare temp files:

private void compareTempFile() {
    File file = new File(getTempFilename());
    Wave w1 = new Wave(getResources().openRawResource(R.raw.tj));
    Wave w2 = new Wave(file.getPath());
    FingerprintSimilarity fps = w1.getFingerprintSimilarity(w2);
    float score = fps.getScore();
    float sim = fps.getSimilarity();
    AppLog.i(sim+" tj");
}

Each time when you call the getTempFilename() method it creates a new file, that is why you got NullPointerException.

Try to refactor your code to create one temp file per one record-compare session.

Oleg Sokolov
  • 1,134
  • 1
  • 12
  • 19
  • Thanks for your help, but sorry am a fresher in android, am in learning phase , can you please correct the code, I tried but not able to resolve the issue. Again Thanks A lot :) – Tanmay Jain Oct 10 '18 at 04:55