From d9610e1e0b8f05b4e70d540e0df507994ec0b76b Mon Sep 17 00:00:00 2001 From: spessasus Date: Sat, 27 Apr 2024 11:54:55 +0200 Subject: [PATCH] channel transposition is now relative to synth transposition theoretically improved panning speed --- .../soundfont/chunk/modulators.js | 15 +++-- .../synthetizer/synthetizer.js | 7 +++ .../worklet_utilities/stereo_panner.js | 18 +++++- src/website/css/style.css | 9 +++ src/website/manager.js | 61 ++++++++++++++----- .../ui/synthesizer_ui/synthetizer_ui.js | 6 +- 6 files changed, 91 insertions(+), 25 deletions(-) diff --git a/src/spessasynth_lib/soundfont/chunk/modulators.js b/src/spessasynth_lib/soundfont/chunk/modulators.js index 9c773df8..b089aac3 100644 --- a/src/spessasynth_lib/soundfont/chunk/modulators.js +++ b/src/spessasynth_lib/soundfont/chunk/modulators.js @@ -84,13 +84,16 @@ function getModSourceEnum(curveType, polarity, direction, isCC, index) return (curveType << 10) | (polarity << 9) | (direction << 8) | (isCC << 7) | index; } +const DEFAULT_ATTENUATION_MOD_AMOUNT = 960; +const DEFAULT_ATTENUATION_MOD_CURVE_TYPE = modulatorCurveTypes.concave; + export const defaultModulators = [ // vel to attenuation // FIXME: something is wrong with the volume control, forced to use concave in volume modulators because linear sounds wrong new Modulator({ - srcEnum: getModSourceEnum(modulatorCurveTypes.concave, 0, 1, 0, modulatorSources.noteOnVelocity), + srcEnum: getModSourceEnum(DEFAULT_ATTENUATION_MOD_CURVE_TYPE, 0, 1, 0, modulatorSources.noteOnVelocity), dest: generatorTypes.initialAttenuation, - amt: 960, + amt: DEFAULT_ATTENUATION_MOD_AMOUNT, secSrcEnum: 0x0, transform: 0}), @@ -99,9 +102,9 @@ export const defaultModulators = [ // vol to attenuation new Modulator({ - srcEnum: getModSourceEnum(modulatorCurveTypes.concave, 0, 1, 1, midiControllers.mainVolume), + srcEnum: getModSourceEnum(DEFAULT_ATTENUATION_MOD_CURVE_TYPE, 0, 1, 1, midiControllers.mainVolume), dest: generatorTypes.initialAttenuation, - amt: 960, + amt: DEFAULT_ATTENUATION_MOD_AMOUNT, secSrcEnum: 0x0, transform: 0}), @@ -113,9 +116,9 @@ export const defaultModulators = [ // expression to attenuation new Modulator({ - srcEnum: getModSourceEnum(modulatorCurveTypes.concave, 0, 1, 1, midiControllers.expressionController), + srcEnum: getModSourceEnum(DEFAULT_ATTENUATION_MOD_CURVE_TYPE, 0, 1, 1, midiControllers.expressionController), dest: generatorTypes.initialAttenuation, - amt: 960, + amt: DEFAULT_ATTENUATION_MOD_AMOUNT, secSrcEnum: 0x0, transform: 0}), diff --git a/src/spessasynth_lib/synthetizer/synthetizer.js b/src/spessasynth_lib/synthetizer/synthetizer.js index d6b5b9d4..066cdd54 100644 --- a/src/spessasynth_lib/synthetizer/synthetizer.js +++ b/src/spessasynth_lib/synthetizer/synthetizer.js @@ -110,6 +110,12 @@ export class Synthetizer { */ this.midiChannels = []; + /** + * The synth's transposition, in semitones. + * @type {number} + */ + this.transposition = 0; + for (let i = 0; i < DEFAULT_CHANNEL_COUNT; i++) { this._addChannelInternal(); } @@ -374,6 +380,7 @@ export class Synthetizer { transpose(semitones) { this.midiChannels.forEach(c => c.transposeChannel(semitones)); + this.transposition = semitones; } /** diff --git a/src/spessasynth_lib/synthetizer/worklet_system/worklet_utilities/stereo_panner.js b/src/spessasynth_lib/synthetizer/worklet_system/worklet_utilities/stereo_panner.js index 3adc7776..8b77d807 100644 --- a/src/spessasynth_lib/synthetizer/worklet_system/worklet_utilities/stereo_panner.js +++ b/src/spessasynth_lib/synthetizer/worklet_system/worklet_utilities/stereo_panner.js @@ -49,8 +49,20 @@ export function panVoice(pan, inputBuffer, output, reverb, reverbLevel, chorus, const rightChannel = output[1]; // panLeft *= dryGain; // panRight *= dryGain; - for (let i = 0; i < inputBuffer.length; i++) { - leftChannel[i] += panLeft * inputBuffer[i]; - rightChannel[i] += panRight * inputBuffer[i]; + // for (let i = 0; i < inputBuffer.length; i++) + // { + // leftChannel[i] += panLeft * inputBuffer[i]; + // rightChannel[i] += panRight * inputBuffer[i]; + // } + if(panLeft > 0) + { + for (let i = 0; i < inputBuffer.length; i++) { + leftChannel[i] += panLeft * inputBuffer[i]; + } + } + if(panRight > 0) { + for (let i = 0; i < inputBuffer.length; i++) { + rightChannel[i] += panRight * inputBuffer[i]; + } } } \ No newline at end of file diff --git a/src/website/css/style.css b/src/website/css/style.css index 03140486..4db29289 100644 --- a/src/website/css/style.css +++ b/src/website/css/style.css @@ -54,6 +54,7 @@ a{ align-content: space-around; justify-content: space-around; align-items: center; + z-index: 50; } .top_part_light{ @@ -143,6 +144,7 @@ input[type="file"] { flex: 1; background-size: cover; height: 1px; /*I have absolutely no idea how this works but whatever ¯\_(ツ)_/¯*/ + z-index: 1; } #note_canvas.light_mode{ @@ -161,4 +163,11 @@ button{ .hidden{ display: none !important; +} + +.secret_video{ + position: absolute; + width: 100%; + left: 0; + z-index: 0; } \ No newline at end of file diff --git a/src/website/manager.js b/src/website/manager.js index 5055361e..28eeed85 100644 --- a/src/website/manager.js +++ b/src/website/manager.js @@ -1,16 +1,16 @@ -import {MidiKeyboard} from "./ui/midi_keyboard.js"; -import {Synthetizer} from "../spessasynth_lib/synthetizer/synthetizer.js"; -import {Renderer} from "./ui/renderer.js"; -import {MIDI} from "../spessasynth_lib/midi_parser/midi_loader.js"; - -import {SoundFont2} from "../spessasynth_lib/soundfont/soundfont_parser.js"; -import {SequencerUI} from "./ui/sequencer_ui/sequencer_ui.js"; -import {SynthetizerUI} from "./ui/synthesizer_ui/synthetizer_ui.js"; -import { MIDIDeviceHandler } from '../spessasynth_lib/midi_handler/midi_handler.js'; -import { WebMidiLinkHandler } from '../spessasynth_lib/midi_handler/web_midi_link.js'; -import { Sequencer } from '../spessasynth_lib/sequencer/sequencer.js'; -import { Settings } from './ui/settings_ui/settings.js'; -import { MusicModeUI } from './ui/music_mode_ui.js'; +import { MidiKeyboard } from './ui/midi_keyboard.js' +import { Synthetizer } from '../spessasynth_lib/synthetizer/synthetizer.js' +import { Renderer } from './ui/renderer.js' +import { MIDI } from '../spessasynth_lib/midi_parser/midi_loader.js' + +import { SoundFont2 } from '../spessasynth_lib/soundfont/soundfont_parser.js' +import { SequencerUI } from './ui/sequencer_ui/sequencer_ui.js' +import { SynthetizerUI } from './ui/synthesizer_ui/synthetizer_ui.js' +import { MIDIDeviceHandler } from '../spessasynth_lib/midi_handler/midi_handler.js' +import { WebMidiLinkHandler } from '../spessasynth_lib/midi_handler/web_midi_link.js' +import { Sequencer } from '../spessasynth_lib/sequencer/sequencer.js' +import { Settings } from './ui/settings_ui/settings.js' +import { MusicModeUI } from './ui/music_mode_ui.js' export class Manager { channelColors = [ @@ -105,8 +105,15 @@ export class Manager { switch (e.key.toLowerCase()) { case "c": e.preventDefault(); + if(this.seq) + { + this.seq.pause(); + } const response = window.prompt("Cinematic mode activated!\n Paste the link to the image for canvas (leave blank to disable)", ""); - + if(this.seq) + { + this.seq.play(); + } if (response === null) { return; } @@ -116,6 +123,32 @@ export class Manager { document.body.requestFullscreen().then(); break; + case "v": + e.preventDefault(); + if(this.seq) + { + this.seq.pause(); + } + const videoSource = window.prompt("Video mode!\n Paste the link to the video source (leave blank to disable)\n" + + "Note: the video will be available in console as 'video'", ""); + if (videoSource === null) { + return; + } + const video = document.createElement("video"); + video.src = videoSource; + video.classList.add("secret_video"); + canvas.parentElement.appendChild(video); + video.play(); + window.video = video; + if(this.seq) + { + video.currentTime = parseFloat(window.prompt("Video offset to sync to midi, in seconds.", "0")); + video.play(); + this.seq.currentTime = 0; + } + + break; + case "n": // secret for (let i = 0; i < 16; i++) { diff --git a/src/website/ui/synthesizer_ui/synthetizer_ui.js b/src/website/ui/synthesizer_ui/synthetizer_ui.js index 31a1c5ee..0e68299a 100644 --- a/src/website/ui/synthesizer_ui/synthetizer_ui.js +++ b/src/website/ui/synthesizer_ui/synthetizer_ui.js @@ -414,8 +414,10 @@ export class SynthetizerUI 36, `The pitch tuning applied to channel ${channelNumber + 1}`, true, val => { - val = Math.round(val) - this.synth.midiChannels[channelNumber].transposeChannel(val, true); + val = Math.round(val); + // adjust to synth's transposition + let transposition = this.synth.transposition + val; + this.synth.midiChannels[channelNumber].transposeChannel(transposition, true); transpose.update(val); }); transpose.update(0);