Java将音频输入流分成Y秒的X个流

时间:2019-06-18 07:48:06

标签: java audio audioinputstream

我正在尝试将音频流拆分成一些持续时间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;
    }
}

出于某种原因,当我打印结束帧和开始帧时,循环的第一次迭代导致提取出的内容是整个音频输入流,而其他每一次迭代都会导致一些奇怪的负数。任何帮助深表感谢!

0 个答案:

没有答案