How to read a recorded audio as a WAV file on Java for audio processing?

Viewed 140

I want to read my recorded wav file and use it for signal processing with the following processing method:

//SIGNAL PROCESSING
private void proccessSignal(double[] signalIN){

    double samplefreq = 44100;
    double[] signal = signalIN;
    Bessel bandpassfilter = new Bessel(signal,samplefreq);
    double[] filteredSignal = bandpassfilter.lowPassFilter(1,150);
    Bessel newsignalfiltered = new Bessel(filteredSignal,samplefreq);
    double[] needsAmplifianceSignal = newsignalfiltered.bandPassFilter(1,200,500);
    double[] amplifiedSignal = needsAmplifianceSignal;
    for (int i=0;i<=needsAmplifianceSignal.length;i++){
        amplifiedSignal[i]=amplifiedSignal[i]*1000;
        amplifiedSignal[i]=amplifiedSignal[i]*amplifiedSignal[i];
    }

    Hilbert h = new Hilbert(amplifiedSignal);
    h.hilbertTransform();
    double[][] analytical_signal = h.getOutput();
    Log.d("Endsignal", "proccessSignal: "+analytical_signal);


    double threshold = 0.0052;
    int apneaCount = 0;

    for (int i=0; i<=analytical_signal.length;i++)
    {
        for (int j=0; j<=analytical_signal.length;j++){
            if (threshold<=analytical_signal[i][j]){

            }else {
                apneaCount++;
                if (apneaCount>=10){
                    apneaview.setText("YOU HAVE APNEA, CONTACT YOUR DOCTOR");
                    break;
                }
            }
        }

    }
    if (apneaCount < 10){
        apneaview.setText("YOU DO NOT HAVE APNEA");
    }
    

}

The recording and everything works but it looks like the signal is always null so it never gets to my processing method, here's my Logcat to get a piece of detailed information about this issue:

  • W/System.err: com.github.psambit9791.wavfile.WavFileException: Invalid Wav Header data, incorrect riff chunk ID
  • W/System.err: at com.github.psambit9791.wavfile.WavFile.openWavFile(WavFile.java:257)
  • W/System.err: at com.github.psambit9791.jdsp.io.Wav.readWav(Wav.java:70)
  • W/System.err: at com.example.appnea.DetailedStat.onCreate(DetailedStat.java:82)

and here's the full activity for better understanding:

// TEST
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_detailed_stat);
    Intent receivedFromList = getIntent();
    name = receivedFromList.getStringExtra("recordName");
    path = receivedFromList.getStringExtra("recordPath");
    nameview = findViewById(R.id.NAME);
    pathview = findViewById(R.id.PATH);
    apneaview = findViewById(R.id.APNEA);


    nameview.setText("Record date: " + name);
    pathview.setText("Record path: " + path);
    apneaview.setText("INITIALISING DATA");


    File audiofile = new File(path);
    double[] signal = new double[0];
    try {
        String mMime = "audio/3gpp";
        MediaCodec codec = MediaCodec.createDecoderByType(mMime);

        /**
         *
         *
         */

        Wav objRead1 = new Wav();
        objRead1.readWav(path);
        Hashtable<String, Long> propsOut = objRead1.getProperties(); // Gets the WAV file properties
        double[][] signal1 = objRead1.getData("int"); // Can be 'int', 'long' 'double'


        try {
            loadFFMpegLibrary();
        } catch (FFmpegNotSupportedException e) {
            e.printStackTrace();
        }


        MediaExtractor mx = new MediaExtractor();

        try {
            mx.setDataSource(path);
        } catch (IOException e) {
            e.printStackTrace();
        }

        /**
         * Finals
         */

        
        MediaFormat mMediaFormat = mx.getTrackFormat(0);

        byte[] bufbytes = new byte[(int) audiofile.length()];

        BufferedInputStream buf = new BufferedInputStream(new FileInputStream(audiofile));

        buf.read(bufbytes, 0, bufbytes.length);
        buf.close();
        mMediaFormat.setByteBuffer("3gp", ByteBuffer.wrap(bufbytes));


        codec.setCallback(new MediaCodec.Callback() {
            @Override
            public void onInputBufferAvailable(@NonNull MediaCodec codec, int index) {

            }

            @Override
            public void onOutputBufferAvailable(@NonNull MediaCodec codec, int index, @NonNull MediaCodec.BufferInfo info) {

            }

            @Override
            public void onError(@NonNull MediaCodec codec, @NonNull MediaCodec.CodecException e) {

            }

            @Override
            public void onOutputFormatChanged(@NonNull MediaCodec codec, @NonNull MediaFormat format) {

            }
        });

        codec.configure(mMediaFormat, null, null, 0);
        codec.start();

        new Thread(() -> {

            MediaCodec.BufferInfo buf_info = new MediaCodec.BufferInfo();
            int outputBufferIndex = codec.dequeueOutputBuffer(buf_info, 0);
            byte[] pcm = new byte[buf_info.size];

            ByteBuffer[] mOutputBuffers = new ByteBuffer[buf_info.size];
            mOutputBuffers[outputBufferIndex].get(pcm, 0, buf_info.size);


        }).start();

        sampleDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "/OfficeRecordings/");
        if (!sampleDir.exists()) {
            sampleDir.mkdirs();
        }

        outputFile =  sampleDir+"/"+"sample_record.3gp";

        finalFile =  sampleDir+"/"+"final_record.wav";

        final String[] cmd = new String[]{"-y", "-i", outputFile, finalFile};


        execFFmpegBinary(cmd);


    } catch (IOException | WavFileException e) {
        e.printStackTrace();
    }
    Log.d("AUDIO", "onCreate: AUDIO FILE EXIST?" + audiofile.exists());





    //proccessSignal(signal);



}


private void execFFmpegBinary(final String[] command) {

    FFmpeg ffmpeg = FFmpeg.getInstance(this);
    try {
        ffmpeg.loadBinary(new LoadBinaryResponseHandler() {

            @Override
            public void onStart() {
                Log.d("audio", "starting to load binary");
            }

            @Override
            public void onFailure() {
                Log.d("audio", "failed to load binary");
            }

            @Override
            public void onSuccess() {
                Log.d("audio", "loaded binary");
                try {

                    ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {

                        @Override
                        public void onStart() {
                            Log.d("audio", " starting to get audio " + "");

                        }

                        @Override
                        public void onProgress(String message) {
                            Log.d("audio", " progress getting audio from ");

                        }

                        @Override
                        public void onFailure(String message) {
                            Log.d("audio", " failed to get audio ");

                        }

                        @Override
                        public void onSuccess(String message) {
                            Log.d("audio", " success getting audio from video");
                        }

                        @Override
                        public void onFinish() {


                        }
                    });
                } catch (FFmpegCommandAlreadyRunningException e) {

                    e.printStackTrace();
                }
            }

            @Override
            public void onFinish() {
            }
        });
    } catch (FFmpegNotSupportedException e) {
        // Handle if FFmpeg is not supported by device
    }
}

// TRYING THE FFMPEG METHOD
public void loadFFMpegLibrary() throws FFmpegNotSupportedException {
    if (fFmpeg == null)
        fFmpeg = FFmpeg.getInstance(this);

    fFmpeg.loadBinary(new FFmpegLoadBinaryResponseHandler() {
        @Override
        public void onFailure() {
            Toast.makeText(getApplicationContext(), "Library failed to load", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onSuccess() {
            Toast.makeText(getApplicationContext(), "Library loaded successfully", Toast.LENGTH_LONG).show();

        }

        @Override
        public void onStart() {

        }

        @Override
        public void onFinish() {

        }
    });

}
public  void executeCommand(final String[] command) throws FFmpegCommandAlreadyRunningException {
    fFmpeg.execute(command, new ExecuteBinaryResponseHandler() {
        @Override
        public void onSuccess(String message) {

        }

        @Override
        public void onProgress(String message) {

        }

        @Override
        public void onFailure(String message) {

        }

        @Override
        public void onStart() {

        }

        @Override
        public void onFinish() {

        }
    });
}


//CONVERTING TO DOUBLE ARRAY FROM BYTEARRAY
public static double[] toDoubleArray(byte[] byteArray){
    int times = Double.SIZE / Byte.SIZE;
    double[] doubles = new double[byteArray.length / times];
    for(int i=0;i<doubles.length;i++){
        doubles[i] = ByteBuffer.wrap(byteArray, i*times, times).getDouble();
    }
    return doubles;
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[1024];
    int read;
    while((read = in.read(buffer)) != -1){
        out.write(buffer, 0, read);
    }
}

//SIGNAL PROCESSING
private void proccessSignal(double[] signalIN){

    double samplefreq = 44100;
    double[] signal = signalIN;
    Bessel bandpassfilter = new Bessel(signal,samplefreq);
    double[] filteredSignal = bandpassfilter.lowPassFilter(1,150);
    Bessel newsignalfiltered = new Bessel(filteredSignal,samplefreq);
    double[] needsAmplifianceSignal = newsignalfiltered.bandPassFilter(1,200,500);
    double[] amplifiedSignal = needsAmplifianceSignal;
    for (int i=0;i<=needsAmplifianceSignal.length;i++){
        amplifiedSignal[i]=amplifiedSignal[i]*1000;
        amplifiedSignal[i]=amplifiedSignal[i]*amplifiedSignal[i];
    }

    Hilbert h = new Hilbert(amplifiedSignal);
    h.hilbertTransform();
    double[][] analytical_signal = h.getOutput();
    Log.d("Endsignal", "proccessSignal: "+analytical_signal);


    double threshold = 0.0052;
    int apneaCount = 0;

    for (int i=0; i<=analytical_signal.length;i++)
    {
        for (int j=0; j<=analytical_signal.length;j++){
            if (threshold<=analytical_signal[i][j]){

            }else {
                apneaCount++;
                if (apneaCount>=10){
                    apneaview.setText("YOU HAVE APNEA, CONTACT YOUR DOCTOR");
                    break;
                }
            }
        }

    }
    if (apneaCount < 10){
        apneaview.setText("YOU DO NOT HAVE APNEA");
    }
    

}

}

Thank you so much for your time, I really appreciate it. Please let me know if you need any other information!

0 Answers
Related