All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.dindoffer.yin.pda.lib.impl.concurrent.InfiniteYinWorker Maven / Gradle / Ivy

package eu.dindoffer.yin.pda.lib.impl.concurrent;

import eu.dindoffer.yin.pda.core.api.F0Candidate;
import eu.dindoffer.yin.pda.core.api.YinAlgorithm;
import eu.dindoffer.yin.pda.core.api.YinSettings;
import eu.dindoffer.yin.pda.core.api.YinUtils;
import eu.dindoffer.yin.pda.core.impl.Yin;

/**
 * A persistent worker used for decoding and estimation of unbounded streams.
 *
 * @author Martin Dindoffer
 */
public class InfiniteYinWorker implements Runnable {

    private final YinSettings settings;
    private final int audioHistoryLength;
    private final int minimalIntegrationWindowSize;
    private final LazyYinChunkFeeder taskFeeder;
    private final InfiniteStreamCoordinator coordinator;

    /**
     * Creates a new infinite worker that indefinitely obtains new audio chunks and estimates them.
     *
     * @param settings    parameters of the YIN algorithm
     * @param taskFeeder  feeder to use for obtaining audio chunks for processing
     * @param coordinator coordinator to use for obtaining probing frame numbers and publishing results
     */
    public InfiniteYinWorker(YinSettings settings, LazyYinChunkFeeder taskFeeder, InfiniteStreamCoordinator coordinator) {
        this.settings = settings;
        this.taskFeeder = taskFeeder;
        this.coordinator = coordinator;
        this.audioHistoryLength = settings.getTaumax() / 2;
        this.minimalIntegrationWindowSize = YinUtils.calculateMinimalIntegrationWindowSize(settings.getTaumax());
    }

    @Override
    public void run() {
        while (true) {
            long globalProbingSampleNum = coordinator.getNextProbingFramePosition();
            long decoderStartOffset = globalProbingSampleNum;
            boolean initialChunk = true;
            if (globalProbingSampleNum > audioHistoryLength) {
                decoderStartOffset -= audioHistoryLength;
                initialChunk = false;
            }
            Short[] nextChunk;
            try {
                nextChunk = taskFeeder.getAnotherChunk(decoderStartOffset,
                        globalProbingSampleNum + minimalIntegrationWindowSize);
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
                break;
            }
            if (nextChunk == null) {
                try {
                    coordinator.publishResult(globalProbingSampleNum, new F0Candidate(-1, -1));
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                } finally {
                    break;
                }
            }
            YinAlgorithm yin = new Yin(Util.unBoxArray(nextChunk), settings);
            F0Candidate pitch = yin.calculatePitch(initialChunk ? 0 : audioHistoryLength);
            try {
                coordinator.publishResult(globalProbingSampleNum, pitch);
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
                break;
            }
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy