我正在尝试将音频流拆分成一些持续时间X的提取,并将每个提取传递给进行一些计算。我已经对代码进行了广泛的注释,所以这就是我所拥有的:
public class Test {
// how long the splits should be
private static final int EXTRACT_DURATION = 5;
private AudioFormat format;
private AudioInputStream entireAIS;
public Test(AudioInputStream ais) {
format = ais.getFormat();
entireAIS = ais;
}
public void splitAndCompute() {
// get the length of the entire stream in seconds
float duration = getDurationInSeconds(entireAIS);
// loop and pass extracts for computation
for(int i = 0; i < duration; i += EXTRACT_DURATION) {
// get an extract starting from the i-th second
AudioInputStream extract = getExtract(i);
// pass for some computation
Object computationResult = SomeClass.compute(extract);
}
}
private AudioInputStream getExtract(int start) {
// extract the bytes per second of the stream
float bytesPerSecond = format.getFrameSize() * format.getFrameRate();
AudioInputStream extract = null;
try {
// copy the entire ais file as init of the extract
extract = AudioSystem.getAudioInputStream(format, entireAIS);
// get the starting byte - start (second) * bytes per second
long startFrame = (long) (start * bytesPerSecond);
// skip that many bytes, taking into account channels
int coef = 1;
if(format.getChannels() == 2) coef = 2;
long skipped = extract.skip(startFrame * coef);
System.out.println("skipped bytes: " + skipped);
// get the end frame by taking the
// (start + extract duration) (second) * bytes per second
long endFrame = (long) ((start + EXTRACT_DURATION) * bytesPerSecond);
// edge case if it is less time left in the stream
if (endFrame > entireAIS.available()) endFrame = entireAIS.available();
// get the extract
extract = new AudioInputStream(extract, format, endFrame - startFrame);
// this will print the duration of the extract
getDurationInSeconds(extract);
} catch (Exception e) {
e.printStackTrace();
}
return extract;
}
private float getDurationInSeconds(AudioInputStream stream) {
long audioFileLength = 0;
try {
audioFileLength = stream.available();
} catch (IOException e) {
e.printStackTrace();
}
int frameSize = format.getFrameSize();
float frameRate = format.getFrameRate();
float durationInSeconds = (audioFileLength / (frameSize * frameRate));
System.out.println("duration: " + durationInSeconds);
return durationInSeconds;
}
}
出于某种原因,当我打印结束帧和开始帧时,循环的第一次迭代导致提取出的内容是整个音频输入流,而其他每一次迭代都会导致一些奇怪的负数。任何帮助深表感谢!