javaandroidsignal-processingtarsosdsp

How to get PCM 16-bit data from TarsosDSP AudioDispatcher?


I want to get PCM 16-bit data from TarsosDSP AudioDispatcher. I followed this link for the pitch analysis of a real-time audio stream. I am getting the desired results but I also want to get the PCM data from AudioDispatcher.

AudioDispatcher adp = AudioDispatcherFactory.fromDefaultMicrophone(2048, 0);

How can I get the required PCM data from AudioDispatcher or any other technique to pass my data from the android AudioRecord to AudioDispatcher?


Solution

  • You can pass your audioRecorder object to AudioDispatcherFactory by simply creating your own AudioDispatcherFactory.java class with extra argument of AudioRecorder

    Like this:

    package com.example.revertback;
    
    public class AudioDispatcherFactory {
    
    
    public static AudioDispatcher fromDefaultMicrophone(final AudioRecord audioInputStream,final int sampleRate,
                                                        final int audioBufferSize, final int bufferOverlap) {
        int minAudioBufferSize = AudioRecord.getMinBufferSize(sampleRate,
                android.media.AudioFormat.CHANNEL_IN_MONO,
                android.media.AudioFormat.ENCODING_PCM_16BIT);
        int minAudioBufferSizeInSamples =  minAudioBufferSize/2;
        if(minAudioBufferSizeInSamples <= audioBufferSize ){
    
            TarsosDSPAudioFormat format = new TarsosDSPAudioFormat(sampleRate, 16,1, true, false);
    
            TarsosDSPAudioInputStream audioStream = new AndroidAudioInputStream(audioInputStream, format);
            //start recording ! Opens the stream.
            return new AudioDispatcher(audioStream,audioBufferSize,bufferOverlap);
        }else{
            throw new IllegalArgumentException("Buffer size too small should be at least " + (minAudioBufferSize *2));
        }
    }
    
    
    
    public static AudioDispatcher fromPipe(final String source,final int targetSampleRate, final int audioBufferSize,final int bufferOverlap){
        PipedAudioStream f = new PipedAudioStream(source);
        TarsosDSPAudioInputStream audioStream = f.getMonoStream(targetSampleRate,0);
        return new AudioDispatcher(audioStream, audioBufferSize, bufferOverlap);
    }
    }
    

    And in your Activity do some this like this

    AudioRecorder recorder = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION,
                RECORDER_SAMPLERATE, RECORDER_CHANNELS,
                RECORDER_AUDIO_ENCODING, bufferSize);
    
        recorder.startRecording();
      AudioDispatcher dispatcher = com.example.revertback.AudioDispatcherFactory.fromDefaultMicrophone(recorder,22050,1024,0);
    
    
        PitchDetectionHandler pdh = new PitchDetectionHandler() {
            @Override
            public void handlePitch(PitchDetectionResult result, AudioEvent e) {
                final float pitchInHz = result.getPitch();
    
            }
        };
        AudioProcessor p = new PitchProcessor(PitchProcessor.PitchEstimationAlgorithm.FFT_YIN, 22050, 1024, pdh);
        dispatcher.addAudioProcessor(p);
        new Thread(dispatcher,"Audio Dispatcher").start();