Java: отображение левого и правого каналов аудиофайла .flac на сетке XY.(Осциллограф) - PullRequest
1 голос
/ 21 марта 2011

Я пытаюсь создать осциллограф XY на Java, и я застрял.Я прочитал всю документацию для jFlac, библиотеку, которую я использую для декодирования моего аудиофайла .flac, и бесплатную документацию по аудиокодекам без потерь здесь .Кажется, я не могу найти ответ на свою проблему.Пожалуйста, примите во внимание следующее.

public void processPCM(ByteData pcm) {
    byte[] temp = pcm.getData();
    line.write(temp, 0, pcm.getLen());
    leftAndRight = new int[pcm.getData().length];
    for(int i = 0; i < temp.length; i+=2){
        leftAndRight[i/2] = (temp[i + 1]<<8) + (temp[i] & 0xff);
    }
}

Здесь образцы данных из моего файла помещаются в SourceDataLine и воспроизводятся.После того, как я записал данные в строку, я хочу преобразовать левый и правый аудио в отдельные переменные целочисленного массива x [] и y [] соответственно.

Это StreamInfo для файла, который я использую:

PCM_SIGNED 44100,0 Гц, 16 бит, стерео, 4 байта / кадр, порядковый номер с прямым порядком байтов

из вышеприведенного кода, pcm.getLen () возвращает значение 16384и pcm.getData () возвращает байтовый массив длины 90112. Это данные в этом байтовом массиве, если я не ошибаюсь, что мне нужно отделить левый и правый каналы от, а затем преобразовать в целочисленные массивы.Это та часть, которую я не понимаю, как это сделать.

Редактировать: я изменил приведенный выше код на что-то, с чем я столкнулся, я думаю, может быть, как получить массив байтов в массив целых чисел, но явсе еще не понимает, как устроены левый и правый каналы.

1 Ответ

1 голос
/ 21 марта 2011

Глядя на код в http://jflac.cvs.sourceforge.net/viewvc/jflac/jFLAC/src/java/org/kc7bfi/jflac/FLACDecoder.java?revision=1.13&view=markup, выясняется, что содержимое байтового массива представляет собой: серию выборок, каждая из которых представляет собой: серию каналов, каждый из которых представляет собой: серию байтов, представляющиходна выборка на один канал, младший байт первый.Значение getLen() - это количество действительных байтов в нем;может быть больше данных, чем это, потому что один и тот же объект ByteData используется повторно, он может быть перераспределен, чтобы избежать повторного перераспределения и т. д.

Итак, вам нужно что-то вроде:

byte[] data = pcm.getData();
int n_bytes = pcm.getLen();
int n_samples = n_bytes / (n_channels*bytes_per_sample);
int k=0;
for (int i=0; i<n_samples; ++i) {
  for (int j=0; j<n_channels; ++j) {
    output[j][i] = data[k] + (data[k+1)<<8);
    k += 2;
  }
}

(предупреждение: код не был проверен и может состоять исключительно из синтаксических ошибок и ошибок, но, надеюсь, идея достаточно ясна).

...