安卓如何在java中逐段读取wav文件
我已经在我的项目(安卓游戏)中实现了Reading wav files in Java,它运行良好。 现在我需要将wav文件读数分解成若干部分,我不知道我做错了什么。 代码运行时,它读取第一部分(共5部分),但当尝试读取以下部分时,FileInputStream返回-1,我不了解其背后的逻辑
以下是我目前掌握的情况:
private List<Float> extractBeats(FileHandle fileHandle) throws Wave.WavFileException, IOException {
List<Float> peaksAppended;
peaksAppended = new ArrayList<Float>();
final FileHandle fileHandleFinal = fileHandle;
for (int i = 0; i < GameSettings.numThreadsAnalyzing; i++) {
final int I = i;
AsyncTask partAnalyzing = new AsyncTask() {
@Override
public List<Float> call() throws Wave.WavFileException, IOException {
final File file = fileHandleFinal.file();
Wave.WavFile wavFile = Wave.WavFile.openWavFile(file);
// Get the number of audio channels in the wav file
final int NUM_CHANNELS = wavFile.getNumChannels();
final int NUM_FRAMES = 1000;
final long totalNumFrames = wavFile.getNumFrames();
final long auxOffset = totalNumFrames / GameSettings.numThreadsAnalyzing;
int offset = (int) auxOffset * I;
if (offset>0){
wavFile.skipFrames(offset);
}
List<Float> peaks;
double[] buffer = new double[NUM_FRAMES * NUM_CHANNELS];
int framesToRead = NUM_FRAMES;
double min = 10;
double max = -10;
// =========================================
// Read file and find out MIN and MAX values
// =========================================
do {
// Read frames into buffer
framesToRead = wavFile.readFrames(buffer, offset, (int) auxOffset, framesToRead);
// Loop through frames and look for minimum and maximum value
for (int s = 0; s < framesToRead * NUM_CHANNELS; s++) {
if (buffer[s] > max) max = buffer[s];
if (buffer[s] < min) min = buffer[s];
}
System.out.println("Buffer_read : " + max + " and min " + min);
}
while (framesToRead != 0);
// Close the wavFile
wavFile.close();
[. . .]//do some other beats extraction stuff
return peaks;
}
};
AsyncExecutor partAnalyzer = new AsyncExecutor(30);
AsyncResult result = partAnalyzer.submit(partAnalyzing);
[. . .]//do some more other beats extraction stuff
}
}
这首歌的第一段很好用。它读取前633000帧。现在我想让它读取接下来的633000帧,但它被困在readSample方法中
下面是从readFrames方法运行的序列
public int readFrames(double[] sampleBuffer, int offset, int partSize, int numFramesToRead) throws IOException, WavFileException {
if (ioState != IOState.READING)
throw new IOException("Cannot read from WavFile instance");
for (int f = 0; f < numFramesToRead; f++) {
if (frameCounter == offset + partSize)
return f;
for (int c = 0; c < numChannels; c++) {
sampleBuffer[offset] = floatOffset + (double) readSample() / floatScale;
offset++;
}
frameCounter++;
}
return numFramesToRead;
}
private long readSample() throws IOException, WavFileException {
long val = 0;
for (int b = 0; b < bytesPerSample; b++) {
if (bufferPointer == bytesRead) {
int read = iStream.read(buffer, 0, BUFFER_SIZE);
if (read == -1) throw new WavFileException("Not enough data available");
bytesRead = read;
bufferPointer = 0;
}
int v = buffer[bufferPointer];
if (b < bytesPerSample - 1 || bytesPerSample == 1) v &= 0xFF;
val += v << (b * 8);
bufferPointer++;
}
return val;
}
我试图使用偏移量并将其传递给FileInputStream(iStream),但也没有成功。然后,我用下面的代码创建了skipFrames方法,但也没有帮助
public void skipFrames(int offset){
frameCounter = offset;
}
若问题解决了,我可以通过阅读wav片段的基本功能来更新主题,这是声音分析的好方法(这就是我正在做的)。 任何帮助都将不胜感激
共 (0) 个答案