Java разделил входной аудиопоток на X потоков по Y секундам - PullRequest
0 голосов
/ 18 июня 2019

Я пытаюсь разделить аудиопоток на фрагменты, каждый из которых имеет длительность 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;
    }
}

По какой-то причине первая итерация цикла приводит к извлечению, которое представляет собой весь входной аудиопоток, а каждая другая итерация приводит к некоторым странным отрицательным числам, когда я печатаю конечный кадр и начальный кадр. Любая помощь очень ценится!

...