2013-06-28 2 views
1

У меня есть некоторые проблемы с выяснением, что я на самом деле read с AudioInputStream. В приведенной ниже программе просто печатается массив байтов, который я получаю, но на самом деле я даже не знаю, если байты на самом деле являются образцами, поэтому байтовый массив является звуком волной.Что именно возвращает метод AudioInputStream.read?

File fileIn; 
AudioInputStream audio_in; 
byte[] audioBytes; 
int numBytesRead; 
int numFramesRead; 
int numBytes; 
int totalFramesRead; 
int bytesPerFrame; 

try { 
     audio_in = AudioSystem.getAudioInputStream(fileIn); 
     bytesPerFrame = audio_in.getFormat().getFrameSize(); 


     if (bytesPerFrame == AudioSystem.NOT_SPECIFIED) { 
      bytesPerFrame = 1; 
     } 

     numBytes = 1024 * bytesPerFrame; 
     audioBytes = new byte[numBytes]; 
     try { 
      numBytesRead = 0; 
      numFramesRead = 0; 
     } catch (Exception ex) { 
      System.out.println("Something went completely wrong"); 
     } 
    } catch (Exception e) { 
     System.out.println("Something went completely wrong"); 
    } 

и в какой-то другой части, я прочитал несколько байт с этим:

try { 
     if ((numBytesRead = audio_in.read(audioBytes)) != -1) {     
       numFramesRead = numBytesRead/bytesPerFrame;     
       totalFramesRead += numFramesRead;    
     } 
    } catch (Exception e) { 
     System.out.println("Had problems reading new content"); 
    } 

Итак, прежде всего, этот код не от меня. Это мой первый раз, читая аудио-файлы, поэтому я получил некоторую помощь от интернет-сайтов. (Найдено по ссылке:. Java - reading, manipulating and writing WAV files StackOverflow, который знал бы

вопрос, каковы байты в audioBytes представляющих Поскольку источник является 44кГц, стерео, там должны быть 2 волны прятались где-то там? , я прав, так как я могу фильтровать важную информацию из этих байтов

// EDIT

так что я добавил эта функция:?

public short[] Get_Sample() { 
    if(samplesRead == 1024) { 
     Read_Buffer(); 
     samplesRead = 4; 
    } else { 
     samplesRead = samplesRead + 4; 
    } 
    short sample[] = new short[2]; 
    sample[0] = (short)(audioBytes[samplesRead-4] + 256*audioBytes[samplesRead-3]); 
    sample[1] = (short)(audioBytes[samplesRead-2] + 256*audioBytes[samplesRead-1]); 
    return sample; 
} 

Whe re Read_Buffer() читает следующие 1024 (или меньше) байтов и загружает их в аудиобайты. образец [0] используется для левой стороны, образец [1] для правой стороны. Но я все еще не уверен, поскольку волны, которые я получаю от этого вида, выглядят довольно «шумными». (Edit: используемый WAV фактически использовал порядок байтов младшего порядка, поэтому мне пришлось изменить расчет.)

+0

* «так как я могу отфильтровать важную информацию из этих байтов?» * Какая точная «важная информация», как вы думаете, на самом деле содержит один кадр потока аудиовхода? –

+0

Фактический образец. Так как это стерео здесь, должно быть 2 значения для каждого образца, я прав? –

+0

* «Так как это стерео здесь, должно быть 2 значения для каждого образца, я прав?» * Да. Но учтите, что если он 16 бит (типичный для стерео с частотой 44,1 кГц), то будет 4 байта на кадр и 2 байта на канал. –

ответ

2

Метод AudioInputStream read() возвращает необработанные аудиоданные. Вы не знаете, что такое «конструкция» данных, прежде чем читать аудиоформат с помощью getFormat(), который возвращает AudioFormat. Из AudioFormat вы можете получитьChannels() и getSampleSizeInBits() и многое другое ... Это потому, что AudioInputStream создан для известного формата.

Если вы вычислили значение выборки, у вас есть разные возможности со знаками и конкретизация данных (в случае 16-разрядного образца). Для того, чтобы сделать более общий код использовать объект AudioFormat вернулся из AudioInputStream, чтобы получить больше информации о буфера данных:

  • кодирования(): PCM_SIGNED, PCM_UNSIGNED ...
  • bigEndian(): правда или ложь

Как вы уже обнаружили, неправильное здание образца может привести к нарушению звука. Если вы работаете с различными файлами, это может привести к проблемам в будущем. Если вы не будете поддерживать поддержку некоторых форматов, просто проверьте, что говорит AudioFormat и генерирует исключение (например, javax.sound.sampled.UnsupportedAudioFileException). Это сэкономит ваше время.

+0

Но он не возвращает данные заголовка или данные дескриптора, верно? поэтому он начинается с (в этом примере) 4 байта для первой части файла, а затем второго образца с 4 байтами и так далее. Итак, все, что мне нужно знать, это байты, принадлежащие стороне, (байт 1 и 2 слева, 3 и 4 справа) и как «объединить» два укуса для сторон. (Я бы просто вычислил sampe = 256 * firstByte + secondByte, правильно?) –

+0

Возможно, это поможет: http://blog.bjornroche.com/2013/05/the-abcs-of-pcm-uncompressed-digital.html –

+0

Да, это помогло. ;) Кажется, я понял это сейчас. –