如何在java中读取片段中的wav文件

时间:2015-10-19 16:05:31

标签: java android audio libgdx wav

我已经在我的项目(Android游戏)中实现了Reading wav files in Java,它运行正常。 现在我需要将wav文件分解成碎片,我不知道我做错了什么。 代码运行,它读取第一部分(总共5个),但是当尝试阅读以下部分时,FileInputStream返回-1并且我没有得到它背后的逻辑。

这是我到目前为止所拥有的:

-H, --proxyHost <argument>
    Set a proxy server for JMeter to use
-P, --proxyPort <argument>
    Set proxy server port for JMeter to use
-N, --nonProxyHosts <argument>
    Set nonproxy host list (e.g. *.apache.org|localhost)
-u, --username <argument>
    Set username for proxy server that JMeter is to use
-a, --password <argument>

这对于第一首歌来说效果很好。它读取前633000帧。现在我想让它读取下一个633000帧,但它会陷入readSample方法。

这是从readFrames方法运行的序列。

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
    }
}

我尝试使用偏移并将其传递给FileInputStream(iStream),但也没有工作。然后,我使用以下代码创建了方法skipFrames,但也没有帮助。

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;
    }

如果解决了,我可以用一个基本的功能读取wav来更新主题,这是一个很好的声音分析方法(这就是我正在做的事情)。 任何帮助将不胜感激。

0 个答案:

没有答案