Saltar al contenido

¿Cómo convertir un archivo .pcm a .wav o .mp3?

Si encuentras algún detalle que no comprendes puedes comentarlo y te responderemos tan rápido como podamos.

Tienes la mayor parte del código correcto. El único problema que puedo ver es la parte en la que escribe los datos PCM en el archivo WAV. Esto debería ser bastante simple de hacer porque WAV = Metadatos + PCM (en ese orden). Esto debería funcionar:

private void rawToWave(final File rawFile, final File waveFile) throws IOException 

    byte[] rawData = new byte[(int) rawFile.length()];
    DataInputStream input = null;
    try 
        input = new DataInputStream(new FileInputStream(rawFile));
        input.read(rawData);
     finally 
        if (input != null) 
            input.close();
        
    

    DataOutputStream output = null;
    try 
        output = new DataOutputStream(new FileOutputStream(waveFile));
        // WAVE header
        // see http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
        writeString(output, "RIFF"); // chunk id
        writeInt(output, 36 + rawData.length); // chunk size
        writeString(output, "WAVE"); // format
        writeString(output, "fmt "); // subchunk 1 id
        writeInt(output, 16); // subchunk 1 size
        writeShort(output, (short) 1); // audio format (1 = PCM)
        writeShort(output, (short) 1); // number of channels
        writeInt(output, 44100); // sample rate
        writeInt(output, RECORDER_SAMPLERATE * 2); // byte rate
        writeShort(output, (short) 2); // block align
        writeShort(output, (short) 16); // bits per sample
        writeString(output, "data"); // subchunk 2 id
        writeInt(output, rawData.length); // subchunk 2 size
        // Audio data (conversion big endian -> little endian)
        short[] shorts = new short[rawData.length / 2];
        ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
        ByteBuffer bytes = ByteBuffer.allocate(shorts.length * 2);
        for (short s : shorts) 
            bytes.putShort(s);
        

        output.write(fullyReadFileToBytes(rawFile));
     finally 
        if (output != null) 
            output.close();
        
    

    byte[] fullyReadFileToBytes(File f) throws IOException 
    int size = (int) f.length();
    byte bytes[] = new byte[size];
    byte tmpBuff[] = new byte[size];
    FileInputStream fis= new FileInputStream(f);
    try  

        int read = fis.read(bytes, 0, size);
        if (read < size) 
            int remain = size - read;
            while (remain > 0) 
                read = fis.read(tmpBuff, 0, remain);
                System.arraycopy(tmpBuff, 0, bytes, size - remain, read);
                remain -= read;
             
         
      catch (IOException e)
        throw e;
     finally  
        fis.close();
     

    return bytes;
 
private void writeInt(final DataOutputStream output, final int value) throws IOException 
    output.write(value >> 0);
    output.write(value >> 8);
    output.write(value >> 16);
    output.write(value >> 24);


private void writeShort(final DataOutputStream output, final short value) throws IOException 
    output.write(value >> 0);
    output.write(value >> 8);


private void writeString(final DataOutputStream output, final String value) throws IOException 
    for (int i = 0; i < value.length(); i++) 
        output.write(value.charAt(i));
    

Cómo utilizar

Es muy sencillo de utilizar. Solo llámalo así:

  File f1 = new File("/sdcard/44100Sampling-16bit-mono-mic.pcm"); // The location of your PCM file
  File f2 = new File("/sdcard/44100Sampling-16bit-mono-mic.wav"); // The location where you want your WAV file
  try 
    rawToWave(f1, f2);
 catch (IOException e) 
    e.printStackTrace();

Como funciona todo esto

Como puede ver, el encabezado WAV es la única diferencia entre los formatos de archivo WAV y PCM. La suposición es que está grabando audio PCM MONO de 16 bits (que de acuerdo con su código, lo está). La función rawToWave simplemente agrega encabezados al archivo WAV, para que los reproductores de música sepan qué esperar cuando se abre su archivo, y luego, después de los encabezados, simplemente escribe los datos PCM desde el último bit en adelante.

Consejo genial

Si desea cambiar el tono de su voz o crear una aplicación de cambio de voz, todo lo que tiene que hacer es aumentar / disminuir el valor de writeInt(output, 44100); // sample rate en su código. Disminuirlo le dirá al jugador que lo reproduzca a una velocidad diferente, cambiando así el tono de salida. Solo un poco más de "bueno saber". 🙂

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags :

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *