Cannot play reverse .wav file using MediaPlayer

I created an application that records audio, saves a sample to an SD card, then plays it using the record and play buttons. I need to cancel this sample. I can do all this, and the reverse sample is saved on the SD card under a different name. The original sample is test.wav , and the same sample that was canceled is saved as revFile.wav . when I try to play revFile.wav , the android says it cannot play this format.

I put the sample in an array and then changed the contents, something tells me that there may be header information at the beginning of the sample, which first requires a strip, any ideas. thanks.

Here is what I still have.

 public class recorder extends Activity { MediaRecorder myRecorder = null; DataInputStream dis = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } public void onClickPlay(View v){ Log.v("onClickplay", "play clicked"); try{ MediaPlayer mp = new MediaPlayer(); mp.setDataSource(Environment.getExternalStorageDirectory().getPath() + "/test.wav"); mp.prepare(); mp.start(); } catch(Exception e3) { e3.printStackTrace(); } TextView text = (TextView)findViewById(R.id.TextView01); text.setText("playing"); } public void onClickRecord(View v){ Log.v("onClickRecord", "record clicked"); File path = Environment.getExternalStorageDirectory(); Log.v("file path", ""+path.getAbsolutePath()); File file = new File(path, "test.wav"); if(file.exists()){ file.delete(); } path.mkdirs(); Log.v("file path", ""+file.getAbsolutePath()); myRecorder = new MediaRecorder(); myRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); myRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); myRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); myRecorder.setOutputFile(file.getAbsolutePath()); Log.i("myrecorder", "about to prepare recording"); try{ myRecorder.prepare(); } catch(Exception e) { e.printStackTrace(); } Log.i("myrecorder", "prepared"); myRecorder.start(); // Recording is now started Log.i("myrecorder", "recording"); TextView text = (TextView)findViewById(R.id.TextView01); text.setText("recording"); } public void onClickStop(View v){ Log.v("onClickStop", "stop clicked"); try{ myRecorder.stop(); myRecorder.reset(); // You can reuse the object by going back to setAudioSource() step myRecorder.release(); // Now the object cannot be reused }catch(Exception e){} TextView text = (TextView)findViewById(R.id.TextView01); text.setText("recording stopped"); } public void onClickReverse(View v){ Log.v("onClickReverse", "reverse clicked"); File f = Environment.getExternalStorageDirectory(); String path = f.getAbsolutePath(); path = path + "/test.wav"; Log.v("path = ", ""+path); Log.v("dir = ", ""+f.getAbsolutePath()); Log.v("test file exists? = ", ""+f.getAbsolutePath()+"/test.wav"); File f2 = new File(path); Log.v("f2 = ", ""+f2.getAbsolutePath()); try { InputStream is = new FileInputStream(f2); BufferedInputStream bis = new BufferedInputStream(is); dis = new DataInputStream(bis); } catch (Exception e) { e.printStackTrace(); } int fileLength = (int)f2.length(); byte[] buffer = new byte[fileLength]; /*File reversedFile = Environment.getExternalStorageDirectory(); File revFile = new File(reversedFile, "reversedFile.wav"); Log.v("reversedfile path", ""+ revFile.getAbsolutePath()); if(revFile.exists()){ revFile.delete(); } reversedFile.mkdirs(); */ byte[] byteArray = new byte[fileLength +1]; Log.v("bytearray size = ", ""+byteArray.length); try { while(dis.read(buffer) != -1 ) { dis.read(buffer); Log.v("about to read buffer", "buffer"); byteArray = buffer; } Log.v(" buffer size = ", ""+ buffer.length); } catch (IOException e) { e.printStackTrace(); } byte[] tempArray = new byte[fileLength]; int j=0; for (int i=byteArray.length-1; i >=0; i--) { tempArray[ j++ ] = byteArray[i]; } File revPath = Environment.getExternalStorageDirectory(); Log.v("revpath path", ""+revPath.getAbsolutePath()); File revFile = new File(revPath, "revFile.wav"); Log.v("revfile path ", ""+revFile.getAbsolutePath()); if(revFile.exists()){ revFile.delete(); } revPath.mkdirs(); try { OutputStream os = new FileOutputStream(revFile); BufferedOutputStream bos = new BufferedOutputStream(os); DataOutputStream dos = new DataOutputStream(bos); Log.v("temparray size = ", ""+ tempArray.length); dos.write(tempArray); dos.flush(); dos.close(); } catch (Exception e) { e.printStackTrace(); } try{ MediaPlayer mp = new MediaPlayer(); mp.setDataSource(Environment.getExternalStorageDirectory().getPath() +"/revFile.wav"); mp.prepare(); mp.start(); } catch(Exception e3) { e3.printStackTrace(); } TextView text = (TextView)findViewById(R.id.TextView01); text.setText("playing reversed file"); } }// end of onclickrev 
+4
source share
3 answers

There is a good description of the .WAV header in the link text

Also note that all the data in the file is stored as the order of Little Endian (the low byte of 1 byte byte is stored with the lowest address ....), so you cannot just cancel the bytes. you need to see how many bytes in width of each sample (usually 16, but check the header) and discard them in chunks of that size

+3
source

The WAV file format includes a 44-byte header piece. Most WAV files consist of this 44-byte header followed by the actual sample data. So, to cancel the WAV file, you must first copy the 44-byte header from the source file, and then copy the inverted sample data from the original after the header. If you simply reorder the entire byte order of the source file, it definitely won't work. It will also not work if you copy the header and then change the byte order of the rest of the file (in fact it will be some kind of work, besides what you get will be just noise). You really need to change the framework where the frame size depends on the bytes per sample and whether the file is stereo or mono (for example, if the file is stereo and 2 bytes per sample, then each frame is 4 bytes).

Please note that not all WAV files are β€œcanonical”. WAV files are actually variants of RIFF files, so technically you need much more complex code to search for different parts of the header and sample data in the source file. However, most WAV files are just the heading followed by samples (and this will certainly be true if you record the sound yourself), in which case you can save a lot of work.

Joe Cullity Link is a good description of the WAV file format.

+3
source

I am sure that you are right, and the problem is that you cannot just cancel the bytes in the file to change the waveform, because you are destroying the header information. You should try to see if there is a good library there, because I have little experience with .wav files.

+1
source

Source: https://habr.com/ru/post/1336641/


All Articles