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