I am trying to create an X-Y Oscilloscope in Java and I have gotten stuck. I have read through all the documentation for jFlac, the library i am using to decode my .flac audio file and the free lossless audio codec documentation here. I cannot seem to find the answer to the problem i am having. Please consider the following.
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);
}
}
This is where the sample data from my file is put into the SourceDataLine and is played. After i write the data to the line, i wish to convert the left and right audio into separate integer array variables x[] and y[], respectively.
This is the StreamInfo for the file i am using:
PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian
from the code above, pcm.getLen() returns a value of 16384 and pcm.getData() returns a byte array of length 90112. It's the data in this byte array, if I'm not mistaken, that i need to separate the left and right channels from, and then convert into integer arrays. This is the part that I do not understand how to accomplish.
Edit: I changed the above code to something i ca开发者_StackOverflowme across that i think might be how to get the byte array into an integer array, but i am still clueless to how the left and right channels are arranged.
Looking at the code in http://jflac.cvs.sourceforge.net/viewvc/jflac/jFLAC/src/java/org/kc7bfi/jflac/FLACDecoder.java?revision=1.13&view=markup it appears that the contents of the byte array are: a series of samples, each of which is: a series of channels, each of which is: a series of bytes representing one sample on one channel, least significant byte first. The value of getLen()
is the number of valid bytes in it; there may be more data than that because the same ByteData
object is reused, it may be overallocated to avoid repeated reallocation, etc.
So, you'll want something like:
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;
}
}
(warning: code has not been tested and may consist entirely of syntax errors and bugs, but hopefully the idea is clear enough).
精彩评论