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
Post a Comment