2015-12-18 2 views
0

Я пытаюсь сохранить двойное [] массив как .WAV файл, используя этот метод:писать двойной [], как WAV файл в Java

public static void saveWav(String filename, double[] samples) { 

    // assumes 44,100 samples per second 
    // use 16-bit audio, 2 channels, signed PCM, little Endian 
    AudioFormat format = new AudioFormat(SAMPLE_RATE * 2, 16, 1, true, false); 
    byte[] data = new byte[2 * samples.length]; 
    for (int i = 0; i < samples.length; i++) { 
     int temp = (short) (samples[i] * MAX_16_BIT); 
     data[2*i + 0] = (byte) temp; 
     data[2*i + 1] = (byte) (temp >> 8); 
    } 

    // now save the file 
    try { 
     ByteArrayInputStream bais = new ByteArrayInputStream(data); 
     AudioInputStream ais = new AudioInputStream(bais, format, samples.length); 
     if (filename.endsWith(".wav") || filename.endsWith(".WAV")) { 
      AudioSystem.write(ais, AudioFileFormat.Type.WAVE, new File(filename)); 
     } 
     else if (filename.endsWith(".au") || filename.endsWith(".AU")) { 
      AudioSystem.write(ais, AudioFileFormat.Type.AU, new File(filename)); 
     } 
     else { 
      throw new RuntimeException("File format not supported: " + filename); 
     } 
    } 
    catch (IOException e) { 
     System.out.println(e); 
     System.exit(1); 
    } 
} 

но когда я перезагружать файлы, которые я спас, для каждой песни [i], двойное значение отличается от оригинала. Я использую этот метод для чтения WAV файлов:

public static double[] read(String filename) { 
    byte[] data = readByte(filename); 
    int N = data.length; 
    double[] d = new double[N/2]; 
    for (int i = 0; i < N/2; i++) { 
     d[i] = ((short) (((data[2*i+1] & 0xFF) << 8) + (data[2*i] & 0xFF)))/((double) MAX_16_BIT); 
    } 
    return d; 
} 
private static byte[] readByte(String filename) { 
    byte[] data = null; 
    AudioInputStream ais = null; 
    try { 

     // try to read from file 
     File file = new File(filename); 
     if (file.exists()) { 
      ais = AudioSystem.getAudioInputStream(file); 
      data = new byte[ais.available()]; 
      ais.read(data); 
     } 

     // try to read from URL 
     else { 
      URL url = StdAudio.class.getResource(filename); 
      ais = AudioSystem.getAudioInputStream(url); 
      data = new byte[ais.available()]; 
      ais.read(data); 
     } 
    } 
    catch (IOException e) { 
     System.out.println(e.getMessage()); 
     throw new RuntimeException("Could not read " + filename); 
    } 

    catch (UnsupportedAudioFileException e) { 
     System.out.println(e.getMessage()); 
     throw new RuntimeException(filename + " in unsupported audio format"); 
    } 

    return data; 
} 

мне нужно оба двойных [] массивы имеет то же значение, что и это не так. Когда я слышу песню, я не могу сказать разницы, но мне все еще нужны эти исходные значения.

Любая помощь приветствуется.

Guy

+0

Каков диапазон ваших образцов? Выше выполняется 16-битный PCM. –

ответ

0

Двойной требует 64-бит хранения и имеет много точности. Вы не можете просто выбросить 48 бит данных в оба конца и ожидать получить то же самое значение обратно. Это аналогично началу изображения с высоким разрешением, преобразованию его в миниатюру, а затем ожиданию, что вы сможете магически восстановить исходное изображение с высоким разрешением. В реальном мире человеческое ухо не сможет отличить двух. Более высокое разрешение - это, полезно во время процедур вычисления и обработки сигналов, чтобы уменьшить накопление вычислительных ошибок. При этом, если вы хотите сохранить 64-бит, вам нужно будет использовать что-то другое, кроме .WAV. Самое близкое, что вы получите, это 32-битный.