java - Visualize while recording using AudioRecord and Visualizer in Android Studio -
i creating android application records , saves wave file , plays back. have visualizer working when .wav file being played back. however, application visualize while recording user getting feedback , knows recording working. techniques have tried either cause program crash or don't work. appreciated.
in following iteration, problem occurs when try , set visualizer while recording using recorder.getaudiosessionid(); in "setuprecordervisualizerfxandui()" method. makes program crash when hit record button. same technique works flawlessly on playback using mplayer.getaudiosessionid(); in setupplaybackvisualizerfxandui() method.
the following main activity:
package beebros.androidaudiovisualizer; import android.content.pm.packagemanager; import android.graphics.canvas; import android.graphics.color; import android.media.audioformat; import android.media.audiorecord; import android.media.audiotrack; import android.media.mediarecorder; import android.net.uri; import android.os.environment; import android.os.parcel; import android.support.annotation.nonnull; import android.support.v7.app.actionbaractivity; import android.os.bundle; import android.view.menu; import android.view.menuitem; import android.support.v7.app.actionbaractivity; import android.media.audiomanager; import android.media.mediaplayer; import android.media.audiofx.visualizer; import android.os.bundle; import android.view.view; import android.widget.button; import android.app.activity; import android.media.audioformat; import android.media.audiorecord; import android.media.mediarecorder; import android.os.bundle; import android.os.environment; import java.io.file; import java.io.fileinputstream; import java.io.filenotfoundexception; import java.io.fileoutputstream; import java.io.ioexception; import java.io.ioexception; import java.util.list; public class mainactivity extends actionbaractivity { visualizerview mvisualizerview; private visualizer mvisualizer; private static mediarecorder mrecorder; private static mediaplayer mplayer; private static string audiofilepath; private static string audiofilepathtemp; private static button stopbutton; private static button playbutton; private static button recordbutton; private boolean isrecording = false; private static final int recorder_bpp = 16; private static final string audio_recorder_file_ext_wav = ".wav"; private static final string audio_recorder_folder = "audiorecorder"; 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_stereo; private static final int recorder_audio_encoding = audioformat.encoding_pcm_16bit; private audiorecord recorder = null; private int buffersize = 0; private thread recordingthread = null; string fileplace; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); mvisualizerview = (visualizerview) findviewbyid(r.id.myvisualizerview); //reference visualizer in xml //identifies location of sd card, recording stored //should check first if phone has sdcard audiofilepath = environment.getexternalstoragedirectory().getabsolutepath() + "myaudio.wav";//"/myaudio.3gp"; //gets references buttons recordbutton = (button) findviewbyid(r.id.recordbutton); playbutton = (button) findviewbyid(r.id.playbutton); stopbutton = (button) findviewbyid(r.id.stopbutton); //check if there microphone if (!hasmicrophone()) { //turns off buttons if no microphone stopbutton.setenabled(false); playbutton.setenabled(false); recordbutton.setenabled(false); } else { playbutton.setenabled(false); stopbutton.setenabled(false); } buffersize = audiorecord.getminbuffersize(recorder_samplerate, recorder_channels, recorder_audio_encoding); } public void recordaudio(view view) throws ioexception { isrecording = true; //enables/disables appropriate buttons stopbutton.setenabled(true); playbutton.setenabled(false); recordbutton.setenabled(false); recorder = new audiorecord(mediarecorder.audiosource.mic, recorder_samplerate, recorder_channels,recorder_audio_encoding, buffersize); recorder.startrecording(); isrecording = true; recordingthread = new thread(new runnable() { @override public void run() { writeaudiodatatofile(); } },"audiorecorder thread"); recordingthread.start(); setuprecordervisualizerfxandui();//method sets visualizer while recording , causes crash try { mvisualizer.setenabled(true); //enabling visualizer makes crash //calling setuprecordervisualizerfxandui(); alone not crash } catch (exception e){ log.e(tag,log.getstacktracestring(e)); } } public void stopaudio(view view) { playbutton.setenabled(true); if(null != recorder){ isrecording = false; recorder.stop(); recorder.release(); recorder = null; recordingthread = null; } recordbutton.setenabled(true); // fileplace = getfilename(); copywavefile(gettempfilename(),getfilename());//copies latest recording permanent folder. deletetempfile(); mvisualizer.setenabled(false); } //plays audio , visuals public void playaudio(view view) throws ioexception { //enables/diables appt. buttons playbutton.setenabled(false); recordbutton.setenabled(false); stopbutton.setenabled(true); string filepath = environment.getexternalstoragedirectory().getpath(); file file = new file(filepath,audio_recorder_folder); setvolumecontrolstream(audiomanager.stream_music); mplayer = mediaplayer.create(this, uri.parse(file.getabsolutepath() + "/" + "1426282058997" + audio_recorder_file_ext_wav)); //plays specific file saved on phone testing setupplaybackvisualizerfxandui(); // make sure visualizer enabled when want // receive data, , when makes sense receive data. mvisualizer.setenabled(true); // when stream ends, don't need collect more data. // don't in setupvisualizerfxandui because want have more, // non-visualizer related code in callback. mplayer .setoncompletionlistener(new mediaplayer.oncompletionlistener() { public void oncompletion(mediaplayer mediaplayer) { mvisualizer.setenabled(false); } }); mplayer.start(); } //method check presence of microphone protected boolean hasmicrophone() { packagemanager pmanager = this.getpackagemanager(); return pmanager.hassystemfeature(packagemanager.feature_microphone); } @override protected void onpause() { super.onpause(); if (isfinishing() && mplayer != null) { //d mvisualizer.release(); mplayer.release(); //d mplayer = null; //d } } private void setupplaybackvisualizerfxandui() { // create visualizer object , attach our media player. mvisualizer = new visualizer(mplayer.getaudiosessionid()); mvisualizer.setcapturesize(visualizer.getcapturesizerange()[1]); mvisualizer.setdatacapturelistener( new visualizer.ondatacapturelistener() { public void onwaveformdatacapture(visualizer visualizer, byte[] bytes, int samplingrate) { mvisualizerview.updatevisualizer(bytes); } public void onfftdatacapture(visualizer visualizer, byte[] bytes, int samplingrate) { } }, visualizer.getmaxcapturerate() / 2, true, false); } private void setuprecordervisualizerfxandui() { // create visualizer object , attach our media player. mvisualizer = new visualizer(recorder.getaudiosessionid());//calling recorder.getaudiosessionid causes application crash. mvisualizer.setcapturesize(visualizer.getcapturesizerange()[1]); mvisualizer.setdatacapturelistener( new visualizer.ondatacapturelistener() { public void onwaveformdatacapture(visualizer visualizer, byte[] bytes, int samplingrate) { mvisualizerview.updatevisualizer(bytes); } public void onfftdatacapture(visualizer visualizer, byte[] bytes, int samplingrate) { } }, visualizer.getmaxcapturerate() / 2, true, false); } private void writeaudiodatatofile(){ byte data[] = new byte[buffersize]; string filename = gettempfilename(); fileoutputstream os = null; try { os = new fileoutputstream(filename); } catch (filenotfoundexception e) { // todo auto-generated catch block e.printstacktrace(); } int read = 0; if(null != os){ while(isrecording){ read = recorder.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 string getfilename(){ string filepath = environment.getexternalstoragedirectory().getpath(); file file = new file(filepath,audio_recorder_folder); if(!file.exists()){ file.mkdirs(); } return (file.getabsolutepath() + "/" + "myaudiofile" + audio_recorder_file_ext_wav); } private string gettempfilename(){ string filepath = environment.getexternalstoragedirectory().getpath(); file file = new file(filepath,audio_recorder_folder); if(!file.exists()){ file.mkdirs(); } file tempfile = new file(filepath,audio_recorder_temp_file); if(tempfile.exists()) tempfile.delete(); return (file.getabsolutepath() + "/" + audio_recorder_temp_file); } 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 = 2; 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; //applog.logstring("file size: " + totaldatalen); 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'; // riff/wave header header[1] = 'i'; header[2] = 'f'; header[3] = 'f'; 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'; // 'fmt ' chunk header[13] = 'm'; header[14] = 't'; header[15] = ' '; header[16] = 16; // 4 bytes: size of 'fmt ' chunk header[17] = 0; header[18] = 0; header[19] = 0; header[20] = 1; // format = 1 header[21] = 0; header[22] = (byte) channels; header[23] = 0; 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); // block align header[33] = 0; header[34] = recorder_bpp; // bits per sample 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); out.write(header, 0, 44); } }
i can provide code .xml , androidvisualizer.java opon request.
thank you!
logcat:
03-21 14:09:00.475 2351-2351/beebros.androidaudiovisualizer e/audioeffect﹕ set(): audioflinger not create effect, status: -22 03-21 14:09:00.475 2351-2351/beebros.androidaudiovisualizer e/visualizers-jni﹕ visualizer initcheck failed -4 03-21 14:09:00.475 2351-2351/beebros.androidaudiovisualizer e/visualizer-java﹕ error code -4 when initializing visualizer. 03-21 14:09:00.475 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ java.lang.runtimeexception: cannot initialize visualizer engine, error: -4 03-21 14:09:00.475 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ android.media.audiofx.visualizer.<init>(visualizer.java:217) 03-21 14:09:00.475 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ beebros.androidaudiovisualizer.mainactivity.setuprecordervisualizerfxandui(mainactivity.java:233) 03-21 14:09:00.475 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ beebros.androidaudiovisualizer.mainactivity.recordaudio(mainactivity.java:132) 03-21 14:09:00.475 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ java.lang.reflect.method.invokenative(native method) 03-21 14:09:00.475 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ java.lang.reflect.method.invoke(method.java:515) 03-21 14:09:00.475 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ android.view.view$1.onclick(view.java:3978) 03-21 14:09:00.475 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ android.view.view.performclick(view.java:4654) 03-21 14:09:00.475 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ android.view.view$performclick.run(view.java:19438) 03-21 14:09:00.475 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ android.os.handler.handlecallback(handler.java:733) 03-21 14:09:00.475 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ android.os.handler.dispatchmessage(handler.java:95) 03-21 14:09:00.485 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ android.os.looper.loop(looper.java:146) 03-21 14:09:00.485 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ android.app.activitythread.main(activitythread.java:5487) 03-21 14:09:00.485 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ java.lang.reflect.method.invokenative(native method) 03-21 14:09:00.485 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ java.lang.reflect.method.invoke(method.java:515) 03-21 14:09:00.485 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:1283) 03-21 14:09:00.485 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ com.android.internal.os.zygoteinit.main(zygoteinit.java:1099) 03-21 14:09:00.485 2351-2351/beebros.androidaudiovisualizer w/system.err﹕ @ dalvik.system.nativestart.main(native method) 03-21 14:09:00.485 2351-2351/beebros.androidaudiovisualizer e/messed up﹕ java.lang.nullpointerexception @ beebros.androidaudiovisualizer.mainactivity.recordaudio(mainactivity.java:134) @ java.lang.reflect.method.invokenative(native method) @ java.lang.reflect.method.invoke(method.java:515) @ android.view.view$1.onclick(view.java:3978) @ android.view.view.performclick(view.java:4654) @ android.view.view$performclick.run(view.java:19438) @ android.os.handler.handlecallback(handler.java:733) @ android.os.handler.dispatchmessage(handler.java:95) @ android.os.looper.loop(looper.java:146) @ android.app.activitythread.main(activitythread.java:5487) @ java.lang.reflect.method.invokenative(native method) @ java.lang.reflect.method.invoke(method.java:515) @ com.android.internal.os.zygoteinit$methodandargscaller.run(zygoteinit.java:1283) @ com.android.internal.os.zygoteinit.main(zygoteinit.java:1099) @ dalvik.system.nativestart.main(native method)
Comments
Post a Comment