androidaudiosignal-processingavconvtarsosdsp

TARSOS DSP for Android: retrieving SpectralPeaks


I'm using Tarsos Dsp for android for retrieving spectral peaks from an audiofile. Since version 2, TarsosDSP doesn't use javax which should make everything a lot easier.

What is bugging me is that my code is working fine but android is struggling deconding the audiofile: this seems to be made with avconv.

    PipedAudioStream localPipedAudioStream = new PipedAudioStream(fileName);
    TarsosDSPAudioInputStream localTarsosDSPAudioInputStream1 = localPipedAudioStream.getMonoStream(this.sampleRate);

How the decoder is created:

public PipeDecoder(){
        //Use sensible defaults depending on the platform
        if(System.getProperty("os.name").indexOf("indows") > 0 ){
            pipeEnvironment = "cmd.exe";
            pipeArgument = "/C";
        }else{
            pipeEnvironment = "/bin/bash";
            pipeArgument = "-c";
        }
        pipeCommand = "avconv -i \"%resource%\" -vn -ar %sample_rate% -ac %channels% -sample_fmt s16 -f s16le pipe:1";
        //pipeLogFile = new File("decoder_log.txt");
        pipeBuffer = 10000;
    }

Are avconv libraries missing, or is it android who can't deal with these commands?

this is the error output:

4651/com.example.giuseppe.tsptest I/PipeDecoder﹕ Starting piped decoding process for /sdcard/sample.wav
4651/com.example.giuseppe.tsptest W/PipeDecoder﹕ IO exception while decoding audio via sub process.Error running exec(). Command: [/bin/bash, -c, avconv -i "/sdcard/sample.wav" -vn -ar 44100 -ac 1 -sample_fmt s16 -f s16le pipe:1] Working Directory: null Environment: [ANDROID_ROOT=/system, EMULATED_STORAGE_SOURCE=/mnt/shell/emulated, LOOP_MOUNTPOINT=/mnt/obb, LD_PRELOAD=libsigchain.so, ANDROID_BOOTLOGO=1, EMULATED_STORAGE_TARGET=/storage/emulated, EXTERNAL_STORAGE=/storage/emulated/legacy, SYSTEMSERVERCLASSPATH=/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar, ANDROID_SOCKET_zygote=10, PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin, ANDROID_DATA=/data, ANDROID_ASSETS=/system/app, ASEC_MOUNTPOINT=/mnt/asec, BOOTCLASSPATH=/system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/mms-common.jar:/system/framework/android.policy.jar:/system/framework/apache-xml.jar, ANDROID_PROPERTY_WORKSPACE=9,0, ANDROID_STORAGE=/storage]
    02-20 17:53:54.020    4651-4651/com.example.giuseppe.tsptest W/System.err﹕ java.io.IOException: Error running exec(). Command: [/bin/bash, -c, avconv -i "/sdcard/sample.wav" -vn -ar 44100 -ac 1 -sample_fmt s16 -f s16le pipe:1] Working Directory: null Environment: [ANDROID_ROOT=/system, EMULATED_STORAGE_SOURCE=/mnt/shell/emulated, LOOP_MOUNTPOINT=/mnt/obb, LD_PRELOAD=libsigchain.so, ANDROID_BOOTLOGO=1, EMULATED_STORAGE_TARGET=/storage/emulated, EXTERNAL_STORAGE=/storage/emulated/legacy, SYSTEMSERVERCLASSPATH=/system/framework/services.jar:/system/framework/ethernet-service.jar:/system/framework/wifi-service.jar, ANDROID_SOCKET_zygote=10, PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin, ANDROID_DATA=/data, ANDROID_ASSETS=/system/app, ASEC_MOUNTPOINT=/mnt/asec, BOOTCLASSPATH=/system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/mms-common.jar:/system/framework/android.policy.jar:/system/framework/apache-xml.jar, ANDROID_PROPERTY_WORKSPACE=9,0, ANDROID_STORAGE=/storage]
    [...]
        --------- beginning of crash
    02-20 17:53:54.033    4651-4651/com.example.giuseppe.tsptest E/AndroidRuntime﹕ FATAL EXCEPTION: main
        Process: com.example.giuseppe.tsptest, PID: 4651
        java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.read(byte[], int, int)' on a null object reference
                at be.tarsos.dsp.io.UniversalAudioInputStream.read(Unknown Source)
                at be.tarsos.dsp.AudioDispatcher.processFirstBuffer(Unknown Source)
                at be.tarsos.dsp.AudioDispatcher.runSourcedDispatcher(Unknown Source)
                at be.tarsos.dsp.AudioDispatcher.run(Unknown Source)   [...]

Solution

  • The PipeDecoder is indeed platform specific. It only works on a machine (UNIX, Windows) with the avconv executable present. It works by calling this executable with e.g. an MP3 sampled at 44.1kHz and it returns, via a pipe, decoded PCM samples at the requested sample rate. ´avconv´ can be replaced by any executable that can decode, resample and stream audio via a pipe (e.g. ffmpeg and SoX).

    Since Android is essentialy Unix this could in principle work on Android, but in practice it is (as far as I know) hard to install avconv on Android. The solution is to look for the platform specific audio decoders or Java libraries that offer this functionality (e.g. jlayer).

    Once you have pcm samples these can enter the TarsosDSP audio pipeline easily.