No se puede reproducir un archivo .wav invertido con MediaPlayer

He creado una aplicación que graba audio, guarda la muestra en la tarjeta sd y luego la reproduce utilizando los botones de grabación y reproducción. Necesito revertir esta muestra. Puedo hacer todo esto y la muestra invertida se guarda en la tarjeta SD con un nombre diferente. La muestra original es test.wav y la misma muestra invertida se guarda como revFile.wav . Cuando intento jugar revFile.wav android dice que no puede reproducir este formato.

He litterally poner la muestra en una matriz, a continuación, invertido el contenido, algo me está diciendo que podría haber información de cabecera en el inicio de la muestra que necesita rayas en primer lugar, cualquier idea. Gracias.

Esto es lo que tengo hasta ahora.

 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 

Hay una buena descripción de la cabecera .WAV en el texto del enlace

También tenga en cuenta que todos los datos del archivo se almacenan como orden de Little Endian (byte de orden inferior de 1 número de byte múltiple se almacena en la dirección más baja ….) por lo que no puede invertir los bytes. Usted necesita ver cuántos bytes de ancho cada muestra es, (generalmente 16, pero compruebe el encabezado) y los invierte en trozos de ese tamaño

El formato de archivo WAV incluye un fragmento de encabezado de 44 bytes. La mayoría de los archivos WAV consisten en este encabezado de 44 bytes, seguido de los datos reales de la muestra. Por lo tanto, para invertir un archivo WAV, primero debe copiar el encabezado de 44 bytes del archivo original y, a continuación, copiar los datos de la muestra invertida del original después del encabezado. Si acaba de invertir la orden de bytes del archivo original completo, definitivamente no funcionará. También no funcionará si copias el encabezado y luego inviertes el orden de bytes del resto del archivo (en realidad funcionará, excepto que lo que obtengas será solo ruido). De hecho, es necesario invertir los fotogramas , donde el tamaño del fotograma depende de los bytes por muestra y si el archivo es estéreo o mono (por ejemplo, si el archivo es estéreo y 2 bytes por muestra, cada fotograma tiene 4 bytes ).

Tenga en cuenta que no todos los archivos WAV son "canónicos" como este. Los archivos WAV son en realidad una variante de archivos RIFF, por lo que técnicamente se necesita código mucho más complicado para encontrar las distintas partes del encabezado y los datos de muestra dentro del archivo original. Sin embargo, la mayoría de los archivos WAV son sólo el encabezado seguido por las muestras (y esto sin duda será cierto si está grabando el audio usted mismo), en cuyo caso puede ahorrarse mucho trabajo.

El enlace de Joe Cullity es una buena descripción del formato de archivo WAV.

Estoy bastante seguro de que tiene razón y que el problema es que no puede invertir los bytes en el archivo para invertir la forma de onda porque está destruyendo la información del encabezado. Usted debe tratar de ver si hay una buena biblioteca por ahí para hacer esto, ya que tengo poca experiencia trabajando con archivos .wav.

  • Codificar wav a AAC en Android
  • Comparar voz wav en android o etiqueta de voz (comandos de voz) API
  • Archivo de audio inverso en Android
  • Cómo codificar un WAV a un mp3 en un dispositivo Android
  • MediaPlayer onCompletion no se llama con precisión
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.