Optimized pattern drawing in MkModPlayer

This commit is contained in:
Vavency 2024-02-21 16:17:13 +00:00 committed by Amelia Yukii
parent 78975ddcc8
commit 897bc631f7
2 changed files with 386 additions and 124 deletions

View file

@ -150,6 +150,27 @@ ChiptuneJsPlayer.prototype.getRow = function () {
return 0;
};
ChiptuneJsPlayer.prototype.getNumPatterns = function () {
if (this.currentPlayingNode && this.currentPlayingNode.modulePtr) {
return libopenmpt._openmpt_module_get_num_patterns(this.currentPlayingNode.modulePtr);
}
return 0;
};
ChiptuneJsPlayer.prototype.getCurrentSpeed = function () {
if (this.currentPlayingNode && this.currentPlayingNode.modulePtr) {
return libopenmpt._openmpt_module_get_current_speed(this.currentPlayingNode.modulePtr);
}
return 0;
};
ChiptuneJsPlayer.prototype.getCurrentTempo = function () {
if (this.currentPlayingNode && this.currentPlayingNode.modulePtr) {
return libopenmpt._openmpt_module_get_current_tempo(this.currentPlayingNode.modulePtr);
}
return 0;
};
ChiptuneJsPlayer.prototype.getPatternNumRows = function (pattern: number) {
if (this.currentPlayingNode && this.currentPlayingNode.modulePtr) {
return libopenmpt._openmpt_module_get_pattern_num_rows(this.currentPlayingNode.modulePtr, pattern);
@ -164,6 +185,20 @@ ChiptuneJsPlayer.prototype.getPatternRowChannel = function (pattern: number, row
return '';
};
ChiptuneJsPlayer.prototype.getCtls = function () {
if (this.currentPlayingNode && this.currentPlayingNode.modulePtr) {
return libopenmpt._openmpt_module_get_ctls(this.currentPlayingNode.modulePtr);
}
return 0;
};
ChiptuneJsPlayer.prototype.version = function () {
if (this.currentPlayingNode && this.currentPlayingNode.modulePtr) {
return libopenmpt._openmpt_get_library_version();
}
return 0;
};
ChiptuneJsPlayer.prototype.createLibopenmptNode = function (buffer, config: object) {
const maxFramesPerChunk = 4096;
const processNode = this.audioContext.createScriptProcessor(2048, 0, 2);
@ -178,6 +213,7 @@ ChiptuneJsPlayer.prototype.createLibopenmptNode = function (buffer, config: obje
processNode.paused = false;
processNode.leftBufferPtr = libopenmpt._malloc(4 * maxFramesPerChunk);
processNode.rightBufferPtr = libopenmpt._malloc(4 * maxFramesPerChunk);
processNode.perf = { 'current': 0, 'max': 0 };
processNode.cleanup = function () {
if (this.modulePtr !== 0) {
libopenmpt._openmpt_module_destroy(this.modulePtr);
@ -205,7 +241,13 @@ ChiptuneJsPlayer.prototype.createLibopenmptNode = function (buffer, config: obje
processNode.togglePause = function () {
this.paused = !this.paused;
};
processNode.getProcessTime = function() {
const max = this.perf.max;
this.perf.max = 0;
return { 'current': this.perf.current, 'max': max };
};
processNode.onaudioprocess = function (e) {
let startTimeP1 = performance.now();
const outputL = e.outputBuffer.getChannelData(0);
const outputR = e.outputBuffer.getChannelData(1);
let framesToRender = outputL.length;
@ -231,11 +273,13 @@ ChiptuneJsPlayer.prototype.createLibopenmptNode = function (buffer, config: obje
const currentPattern = libopenmpt._openmpt_module_get_current_pattern(this.modulePtr);
const currentRow = libopenmpt._openmpt_module_get_current_row(this.modulePtr);
startTimeP1 = startTimeP1 - performance.now();
if (currentPattern !== this.patternIndex) {
processNode.player.fireEvent('onPatternChange');
}
processNode.player.fireEvent('onRowChange', { index: currentRow });
const startTimeP2 = performance.now();
while (framesToRender > 0) {
const framesPerChunk = Math.min(framesToRender, maxFramesPerChunk);
const actualFramesPerChunk = libopenmpt._openmpt_module_read_float_stereo(this.modulePtr, this.context.sampleRate, framesPerChunk, this.leftBufferPtr, this.rightBufferPtr);
@ -262,6 +306,8 @@ ChiptuneJsPlayer.prototype.createLibopenmptNode = function (buffer, config: obje
this.cleanup();
error ? processNode.player.fireEvent('onError', { type: 'openmpt' }) : processNode.player.fireEvent('onEnded');
}
this.perf.current = performance.now() - startTimeP2 + startTimeP1;
if (this.perf.current > this.perf.max) this.perf.max = this.perf.current;
};
return processNode;
};