2017-04-23 12 views
1

나는 wav 파일에서 데이터를 얻고 wav에 바이트를 다시 쓰고 싶습니다.android 어떻게 wav 파일에 바이트를 쓸 수 있습니다

난 이미 나는 아래의 코드로 원시 PCM 파일로 변환되어

byte[] soundBytes; 
     try { 
      InputStream inputStream = new FileInputStream(getRealPathFromURI(this,uri)); 
      soundBytes = toByteArray(inputStream); 
      for (int i = 0; i != -1 ; i++) { 

       if(soundBytes[i]<0) { 
        k =soundBytes[i] + 256; 
       } else {k = soundBytes[i];} 
       System.out.println("byte " + i + ": " + k); 
      } 
     } catch(Exception e) { 
      e.printStackTrace(); 
     } 


    } 
} 

public byte[] toByteArray(InputStream in) throws IOException { 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    int read = 0; 
    byte[] buffer = new byte[1024]; 
    while (read != -1) { 
     read = in.read(buffer); 
     if (read != -1) 
      out.write(buffer,0,read); 
    } 
    out.close(); 
    return out.toByteArray(); 
} 
+0

안드로이드가 자바 클래스 인 TargetDataLine을 구현하는지 혼란 스럽습니다. YES이면,이 클래스는 모든 .wav 헤더/포맷을 처리 할 것이므로, 포맷 당 바이트로 변환 된 PCM을 제공하기 만하면됩니다. 하지만 안드로이드가 얼마나 많은 자바 오디오를 사용하는지는 분명하지 않다. –

답변

1

데이터는 44- 0-43 바이트 헤더 알고 및 wav.here에서 바이트 내 코드

이다 가지고있다 원시 파일. 당신이 말했듯이 당신은 당신이 가지고있는 바이트들을 가지고 raw 파일을 생성하고, 그 파일을 다음의 rawToWave() 메소드에 보내거나 rawToWave() 메소드를 조작하여 바이트들을 raw 파일로 직접 변환해야한다.

public void rawToWave(final File rawFile) throws IOException { 

    File waveFile = DirectoryOperations.createDirAndAudioFile("vocal.wav");// creating the empty wav file. 

    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;//following block is converting raw to wav. 
    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, RECORDER_SAMPLERATE); // 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 
     output.write(fullyReadFileToBytes(rawFile)); 

    } finally { 
     if (output != null) { 
      output.close(); 
     } 
    } 
} 

private byte[] fullyReadFileToBytes(File f) throws IOException { 
    int size = (int) f.length(); 
    byte bytes[] = new byte[size]; 
    byte tmpBuff[] = new byte[size]; 
    try (FileInputStream fis = new FileInputStream(f)) { 
     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; 
      } 
     } 
    } 

    return bytes; 
} 

private void writeInt(final DataOutputStream output, final int value) throws IOException { 
    output.write(value); 
    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); 
    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)); 
    } 
} 
+0

레코더 샘플 속도는 무엇이고 RECORDER_SAMPLERATE * 2는 무엇을 의미합니까? –

+0

나는 0-43 바이트 있고 그들은 헤더, 그렇지 않아? 그래서 나는 RIFF WAVE 같은 것들을 쓰지 않아도 될까요? –

+0

@ 陳価基 RECORDER_SAMPLERATE는 오디오 파일의 샘플 속도입니다 (예 : 44100 Hz). Java에서는 byte가 8 비트이고 short가 16 비트이므로 과부하를 방지하려면 2를 곱해야합니다. 파일이 Wav 파일이므로 첫 번째 44 바이트는 헤더입니다. 위 메서드는 원시 파일 용이므로이 메서드를 사용하기 위해 처음 44 바이트를 제거해야하거나 리프 파도를 수행 할 필요가 없다고 말한 것입니다. – ACAkgul