java - stream from microphone, add effect and save to wav file using tarsos android library -




notes: i'm using android studio , i'm using latest tarsos audio library supposed compatible android, , in fact have added library android studio project. tried using jtransforms , minim libraries no luck. edited 8/23/17: found , fixed bugs, reposted current code, still made no progress actual problem summarized below:

summary: in 5th code block have posted, on line 15 commented out, need know how line work , not throw compile error

what i'm trying record microphone, , while recording use dsp bandpass filter tarsos library , output results .wav file. can stream microphone .wav file following this tutorial using android.media imports, doesn't allow me add bandpass filter, , using tarsos imports functions don't allow me use save .wav methods that tutorial has, know i'm missing and/or doing wrong, i've been googling week , haven't found working solution, i've found links java files inside library isn't helpful couldn't find tutorials on how correctly use them. doing wrong? here relevant code tarsos method i'm trying use:

the related imports , 'global' variables

import android.media.audiorecord; import android.media.mediarecorder; import android.media.audioformat; import android.media.audiotrack;  import be.tarsos.dsp.audiodispatcher; import be.tarsos.dsp.audioprocessor; import be.tarsos.dsp.filters.bandpass; import be.tarsos.dsp.io.android.audiodispatcherfactory;  //start class   audiorecord alteredrecord = null; audiodispatcher dispatcher; float freqchange; float tollerance; private static final int recorder_bpp = 16; private static final string audio_recorder_folder = "crowd_speech"; 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_mono; private static final int recorder_audio_encoding = audioformat.encoding_pcm_16bit; private int buffersize = 1024; private thread recordingthread = null;  //set min buffer size in oncreate event buffersize = audiorecord.getminbuffersize(recorder_samplerate,  recorder_channels, recorder_audio_encoding)*4; 

this starts mic recording inside onclick method, , commenting/uncommenting 1 of 2 'running' variable values can switch between filter or no filter (android or tarsos functions) when startrecording method called

if(crowdfilter && running==0 && set==0){//crowd speech mode, start talking     icons(2,"");     running=4;//start recording mic, apply bandpass filter , save wave file using tarsos import     //running=5;//start recording mic, no filter, save wav file using android media import     freqchange = globals.minfr[globals.curuser];     tollerance = 40;     set=1;     startrecording(); } 

the start recording method:

private void startrecording() {      if (running == 5) {//start recording mic, no filter, save wav file using android media library         alteredrecord = new audiorecord(mediarecorder.audiosource.mic, recorder_samplerate, recorder_channels,recorder_audio_encoding, buffersize);             alteredrecord.startrecording();             isrecording = true;             recordingthread = new thread(new runnable() {                 @override                 public void run() {                     writeaudiodatatofile();                 }             }, "crowd_speech thread");             recordingthread.start();     }      if (running == 4) {//start recording mic, apply bandpass filter , save wave file using tarsos library         dispatcher = audiodispatcherfactory.fromdefaultmicrophone(recorder_samplerate, buffersize, 0);         audioprocessor p = new bandpass(freqchange, tollerance, recorder_samplerate);         dispatcher.addaudioprocessor(p);             isrecording = true;             dispatcher.run();             recordingthread = new thread(new runnable() {                 @override                 public void run() {                     writeaudiodatatofile();                 }             }, "crowd_speech thread");             recordingthread.start();     } } 

stop recording button inside onclick method

if(crowdfilter && (running==4 || running==5) && set==0) {//crowd speech finished talking     icons(1, "");     stoprecording();     set = 1; } 

both cases fine until point, if running==4 (tarsos dsp filter applied) program crashes. if use running==5 (the android.media way no filter) whole rest of works fine , saves file, no bandpass effect applied. if try swapping out alteredrecord = new audiorecord... tarsos dispatcher = audiodispatcherfactory... ( such dispatcher = new audiorecord...) incompatible , not think of compiling. (that's why line 15 in following method commented out)

private void writeaudiodatatofile(){     byte data[] = new byte[buffersize];     string filename = gettempfilename();     fileoutputstream os = null;     try {         os = new fileoutputstream(filename);     } catch (filenotfoundexception e) {         e.printstacktrace();     }     int read = 0;     if(null != os){         while(isrecording){             if(running==4)             {                 //read = dispatcher.(data, 0, buffersize);             }             if(running==5)             {                 read = alteredrecord.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 != alteredrecord) {         isrecording = false;         int = alteredrecord.getstate();         if (i == 1) {             running = 0;             alteredrecord.stop();             alteredrecord.release();             alteredrecord = null;             recordingthread = null;         }     }         if(null !=dispatcher){             isrecording = false;             running = 0;             dispatcher.stop();             recordingthread = null;         }     copywavefile(gettempfilename(),getfilename());     deletetempfile(); }  private void deletetempfile() {     file file = new file(gettempfilename());     file.delete(); }  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 = 1;     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;         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';header[1] = 'i'; header[2] = 'f';header[3] = 'f';// riff/wave header     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';header[13] = 'm';header[14] = 't';header[15] = ' ';// 'fmt ' chunk     header[16] = 16;header[17] = 0;header[18] = 0;header[19] = 0;// 4 bytes: size of 'fmt ' chunk     header[20] = 1;header[21] = 0;header[22] = (byte) channels;header[23] = 0;// format = 1     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);header[33] = 0;// block align     header[34] = recorder_bpp;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);// bits per sample     out.write(header, 0, 44); } 

solved, need use writer function, , not bother of methods needed save wav file android.media import functions, working code segment startrecording method changed:

if (running == 4) {//start recording mic, apply bandpass filter , save wave file using tarsos library         dispatcher = audiodispatcherfactory.fromdefaultmicrophone(recorder_samplerate, buffersize, 0);         audioprocessor p = new bandpass(freqchange, tollerance, recorder_samplerate);         dispatcher.addaudioprocessor(p);         isrecording = true;         // output         randomaccessfile outputfile = new randomaccessfile(getfilename(), "rw");         tarsosdspaudioformat outputformat = new tarsosdspaudioformat(44100, 16, 1, true, false);         writerprocessor writer = new writerprocessor(outputformat, outputfile);         dispatcher.addaudioprocessor(writer);         recordingthread = new thread(new runnable() {             @override             public void run() {                 dispatcher.run();             }         }, "crowd_speech thread");         recordingthread.start();     } 




wiki

Comments

Popular posts from this blog

Asterisk AGI Python Script to Dialplan does not work -

python - Read npy file directly from S3 StreamingBody -

kotlin - Out-projected type in generic interface prohibits the use of metod with generic parameter -