Update Simpler device building to use PadSound state and parameters
This commit is contained in:
@@ -343,10 +343,16 @@ async function buildMidiClip(
|
|||||||
return midiClip;
|
return midiClip;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function buildSimplerDevice(koTrack: AblTrack, abletonVersion: AbletonVersion) {
|
async function buildSimplerDevice(
|
||||||
|
koTrack: AblTrack,
|
||||||
|
abletonVersion: AbletonVersion,
|
||||||
|
automatedParameters: ReadonlySet<FaderParam> = new Set(),
|
||||||
|
) {
|
||||||
const simplerTemplate = await loadTemplate<ALSSimpler>('simpler', abletonVersion);
|
const simplerTemplate = await loadTemplate<ALSSimpler>('simpler', abletonVersion);
|
||||||
const device = structuredClone(simplerTemplate.OriginalSimpler);
|
const device = structuredClone(simplerTemplate.OriginalSimpler);
|
||||||
const playbackState = getSimplerPlaybackState(koTrack.playMode);
|
const padSound = getPadSoundState(koTrack);
|
||||||
|
const padEnvelope = getPadEnvelopeState(padSound);
|
||||||
|
const playbackState = getSimplerPlaybackState(padSound.playMode);
|
||||||
const samplePart = device.Player.MultiSampleMap.SampleParts.MultiSamplePart;
|
const samplePart = device.Player.MultiSampleMap.SampleParts.MultiSamplePart;
|
||||||
const loopModulators = device.Player.LoopModulators;
|
const loopModulators = device.Player.LoopModulators;
|
||||||
const simplerFilter = device.Filter.Slot.Value.SimplerFilter;
|
const simplerFilter = device.Filter.Slot.Value.SimplerFilter;
|
||||||
@@ -367,11 +373,13 @@ async function buildSimplerDevice(koTrack: AblTrack, abletonVersion: AbletonVers
|
|||||||
simplerFilter.ModByLfo.Manual['@Value'] = 0;
|
simplerFilter.ModByLfo.Manual['@Value'] = 0;
|
||||||
device.Lfo.IsOn.Manual['@Value'] = 'false';
|
device.Lfo.IsOn.Manual['@Value'] = 'false';
|
||||||
device.Pitch.PitchLfoAmount.Manual['@Value'] = 0;
|
device.Pitch.PitchLfoAmount.Manual['@Value'] = 0;
|
||||||
device.VolumeAndPan.OneShotEnvelope.FadeInTime.Manual['@Value'] = SIMPLER_FADE_IN_MS;
|
device.VolumeAndPan.OneShotEnvelope.FadeInTime.Manual['@Value'] =
|
||||||
device.VolumeAndPan.OneShotEnvelope.FadeOutTime.Manual['@Value'] = SIMPLER_FADE_OUT_MS;
|
padEnvelope.oneShotFadeInMs;
|
||||||
|
device.VolumeAndPan.OneShotEnvelope.FadeOutTime.Manual['@Value'] =
|
||||||
|
padEnvelope.oneShotFadeOutMs;
|
||||||
device.VolumeAndPan.OneShotEnvelope.SustainMode.Manual['@Value'] = 0;
|
device.VolumeAndPan.OneShotEnvelope.SustainMode.Manual['@Value'] = 0;
|
||||||
device.VolumeAndPan.Envelope.AttackTime.Manual['@Value'] = SIMPLER_ATTACK_MS;
|
device.VolumeAndPan.Envelope.AttackTime.Manual['@Value'] = padEnvelope.classicAttackMs;
|
||||||
device.VolumeAndPan.Envelope.ReleaseTime.Manual['@Value'] = SIMPLER_RELEASE_MS;
|
device.VolumeAndPan.Envelope.ReleaseTime.Manual['@Value'] = padEnvelope.classicReleaseMs;
|
||||||
device.Globals.PlaybackMode['@Value'] = playbackState.playbackMode;
|
device.Globals.PlaybackMode['@Value'] = playbackState.playbackMode;
|
||||||
device.Globals.NumVoices['@Value'] = playbackState.voices;
|
device.Globals.NumVoices['@Value'] = playbackState.voices;
|
||||||
device.Globals.RetriggerMode['@Value'] = playbackState.retrigger;
|
device.Globals.RetriggerMode['@Value'] = playbackState.retrigger;
|
||||||
@@ -389,17 +397,17 @@ async function buildSimplerDevice(koTrack: AblTrack, abletonVersion: AbletonVers
|
|||||||
sampleRef.LastModDate['@Value'] = 0;
|
sampleRef.LastModDate['@Value'] = 0;
|
||||||
}
|
}
|
||||||
if (sampleRef.DefaultDuration) {
|
if (sampleRef.DefaultDuration) {
|
||||||
sampleRef.DefaultDuration['@Value'] = Math.round(koTrack.soundLength * koTrack.sampleRate);
|
sampleRef.DefaultDuration['@Value'] = Math.round(padSound.soundLength * koTrack.sampleRate);
|
||||||
}
|
}
|
||||||
if (sampleRef.DefaultSampleRate) {
|
if (sampleRef.DefaultSampleRate) {
|
||||||
sampleRef.DefaultSampleRate['@Value'] = koTrack.sampleRate;
|
sampleRef.DefaultSampleRate['@Value'] = koTrack.sampleRate;
|
||||||
}
|
}
|
||||||
samplePart.Name['@Value'] = koTrack.name;
|
samplePart.Name['@Value'] = koTrack.name;
|
||||||
samplePart.RootKey['@Value'] = koTrack.rootNote;
|
samplePart.RootKey['@Value'] = padSound.rootNote;
|
||||||
samplePart.SampleStart['@Value'] = koTrack.trimLeft;
|
samplePart.SampleStart['@Value'] = padSound.trimStart;
|
||||||
samplePart.SampleEnd['@Value'] = koTrack.trimRight;
|
samplePart.SampleEnd['@Value'] = padSound.trimEnd;
|
||||||
samplePart.SustainLoop.Start['@Value'] = koTrack.trimLeft;
|
samplePart.SustainLoop.Start['@Value'] = padSound.trimStart;
|
||||||
samplePart.SustainLoop.End['@Value'] = koTrack.trimRight;
|
samplePart.SustainLoop.End['@Value'] = padSound.trimEnd;
|
||||||
samplePart.SustainLoop.Mode['@Value'] = 0;
|
samplePart.SustainLoop.Mode['@Value'] = 0;
|
||||||
samplePart.SustainLoop.Crossfade['@Value'] = 0;
|
samplePart.SustainLoop.Crossfade['@Value'] = 0;
|
||||||
samplePart.ReleaseLoop.Start['@Value'] = 0;
|
samplePart.ReleaseLoop.Start['@Value'] = 0;
|
||||||
@@ -414,41 +422,54 @@ async function buildSimplerDevice(koTrack: AblTrack, abletonVersion: AbletonVers
|
|||||||
// setting velocity scaling to 20% to match KO behavior
|
// setting velocity scaling to 20% to match KO behavior
|
||||||
device.VolumeAndPan.VolumeVelScale.Manual['@Value'] = 0.2;
|
device.VolumeAndPan.VolumeVelScale.Manual['@Value'] = 0.2;
|
||||||
|
|
||||||
device.VolumeAndPan.Panorama.Manual['@Value'] = koTrack.pan;
|
device.VolumeAndPan.Panorama.Manual['@Value'] = padSound.pan;
|
||||||
|
|
||||||
let pitch = koTrack.pitch || 0;
|
let pitch = padSound.pitch || 0;
|
||||||
if (koTrack.samplePitch) {
|
if (koTrack.samplePitch) {
|
||||||
pitch += koTrack.samplePitch;
|
pitch += koTrack.samplePitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
// adding PITCH fader param if defined
|
// adding PITCH fader param if defined
|
||||||
if (koTrack.faderParams[FaderParam.PTC] !== -1) {
|
if (koTrack.faderParams[FaderParam.PTC] !== -1) {
|
||||||
const normalized = (koTrack.faderParams[FaderParam.PTC] - 0.5) * 2; // from 0-1 to -1 to +1
|
pitch += Math.round(
|
||||||
pitch += Math.round(normalized * 5);
|
convertGroupFaderValue(FaderParam.PTC, koTrack.faderParams[FaderParam.PTC], {
|
||||||
|
track: koTrack,
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (koTrack.faderParams[FaderParam.TUNE] !== -1) {
|
if (koTrack.faderParams[FaderParam.TUNE] !== -1) {
|
||||||
device.Pitch.TransposeFine.Manual['@Value'] =
|
device.Pitch.TransposeFine.Manual['@Value'] = convertGroupFaderValue(
|
||||||
Math.max(-0.5, Math.min(0.5, koTrack.faderParams[FaderParam.TUNE] - 0.5)) * 100;
|
FaderParam.TUNE,
|
||||||
|
koTrack.faderParams[FaderParam.TUNE],
|
||||||
|
{ track: koTrack },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
device.Pitch.TransposeKey.Manual['@Value'] = pitch;
|
device.Pitch.TransposeKey.Manual['@Value'] = pitch;
|
||||||
|
|
||||||
// adding vibrato from MOD fader param if defined
|
// adding vibrato from MOD fader param if defined
|
||||||
if (koTrack.faderParams[FaderParam.MOD] !== -1) {
|
if (
|
||||||
|
koTrack.faderParams[FaderParam.MOD] !== -1 ||
|
||||||
|
automatedParameters.has(FaderParam.MOD)
|
||||||
|
) {
|
||||||
device.Lfo.IsOn.Manual['@Value'] = 'true';
|
device.Lfo.IsOn.Manual['@Value'] = 'true';
|
||||||
if (!device.Lfo.Slot.Value.SimplerLfo && abletonVersion === '10') {
|
if (!device.Lfo.Slot.Value.SimplerLfo && abletonVersion === '10') {
|
||||||
const simplerLfoTemplate = await loadTemplate<any>('simplerLfo', abletonVersion);
|
const simplerLfoTemplate = await loadTemplate<any>('simplerLfo', abletonVersion);
|
||||||
device.Lfo.Slot.Value.SimplerLfo = structuredClone(simplerLfoTemplate.SimplerLfo);
|
device.Lfo.Slot.Value.SimplerLfo = structuredClone(simplerLfoTemplate.SimplerLfo);
|
||||||
}
|
}
|
||||||
// KO's MOD wheel on 100% is roughly equal to 5% LFO pitch modulation
|
// KO's MOD wheel on 100% is roughly equal to 5% LFO pitch modulation
|
||||||
device.Pitch.PitchLfoAmount.Manual['@Value'] = koTrack.faderParams[FaderParam.MOD] / 20;
|
device.Pitch.PitchLfoAmount.Manual['@Value'] = convertGroupFaderValue(
|
||||||
|
FaderParam.MOD,
|
||||||
|
Math.max(0, koTrack.faderParams[FaderParam.MOD]),
|
||||||
|
{ track: koTrack },
|
||||||
|
);
|
||||||
device.Lfo.Slot.Value.SimplerLfo.RateType.Manual['@Value'] = 1; // tempo synced 1/16
|
device.Lfo.Slot.Value.SimplerLfo.RateType.Manual['@Value'] = 1; // tempo synced 1/16
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add bandpass filter
|
// TODO: add bandpass filter
|
||||||
|
|
||||||
if (koTrack.timeStretch === 'bars') {
|
if (padSound.time.mode === 'bars') {
|
||||||
device.Player.MultiSampleMap.SampleParts.MultiSamplePart.SampleWarpProperties.IsWarped[
|
device.Player.MultiSampleMap.SampleParts.MultiSamplePart.SampleWarpProperties.IsWarped[
|
||||||
'@Value'
|
'@Value'
|
||||||
] = 'true';
|
] = 'true';
|
||||||
@@ -464,18 +485,18 @@ async function buildSimplerDevice(koTrack: AblTrack, abletonVersion: AbletonVers
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
'@Id': 1,
|
'@Id': 1,
|
||||||
'@SecTime': koTrack.soundLength,
|
'@SecTime': padSound.soundLength,
|
||||||
'@BeatTime':
|
'@BeatTime':
|
||||||
koTrack.timeStretchBars *
|
padSound.time.bars *
|
||||||
koTrack.timeSignature.numerator *
|
koTrack.timeSignature.numerator *
|
||||||
(4 / koTrack.timeSignature.denominator), // convert bars to beats
|
(4 / koTrack.timeSignature.denominator), // convert bars to beats
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (koTrack.timeStretch === 'bpm') {
|
if (padSound.time.mode === 'bpm') {
|
||||||
// calculating beat length using koTrack.timeStretchBpm
|
// calculating beat length using koTrack.timeStretchBpm
|
||||||
const beatTime = koTrack.soundLength / (60 / koTrack.timeStretchBpm);
|
const beatTime = padSound.soundLength / (60 / padSound.time.bpm);
|
||||||
|
|
||||||
device.Player.MultiSampleMap.SampleParts.MultiSamplePart.SampleWarpProperties.IsWarped[
|
device.Player.MultiSampleMap.SampleParts.MultiSamplePart.SampleWarpProperties.IsWarped[
|
||||||
'@Value'
|
'@Value'
|
||||||
@@ -492,13 +513,13 @@ async function buildSimplerDevice(koTrack: AblTrack, abletonVersion: AbletonVers
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
'@Id': 1,
|
'@Id': 1,
|
||||||
'@SecTime': koTrack.soundLength,
|
'@SecTime': padSound.soundLength,
|
||||||
'@BeatTime': beatTime,
|
'@BeatTime': beatTime,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (koTrack.timeStretch === 'rev') {
|
if (padSound.time.mode === 'rev') {
|
||||||
device.Player.Reverse.Manual['@Value'] = 'true';
|
device.Player.Reverse.Manual['@Value'] = 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,6 +531,7 @@ async function buildSimplerDevice(koTrack: AblTrack, abletonVersion: AbletonVers
|
|||||||
async function buildFaderFilterDevice(
|
async function buildFaderFilterDevice(
|
||||||
parameter: FaderParam.LPF | FaderParam.HPF,
|
parameter: FaderParam.LPF | FaderParam.HPF,
|
||||||
value: number,
|
value: number,
|
||||||
|
track: AblTrack,
|
||||||
abletonVersion: AbletonVersion,
|
abletonVersion: AbletonVersion,
|
||||||
) {
|
) {
|
||||||
const filterTemplate = await loadTemplate<ALSFilter>('effectFilter', abletonVersion);
|
const filterTemplate = await loadTemplate<ALSFilter>('effectFilter', abletonVersion);
|
||||||
@@ -519,7 +541,7 @@ async function buildFaderFilterDevice(
|
|||||||
filter.FilterType.Manual['@Value'] = highPass ? 1 : 0;
|
filter.FilterType.Manual['@Value'] = highPass ? 1 : 0;
|
||||||
filter.LegacyFilterType.Manual['@Value'] = highPass ? 1 : 0;
|
filter.LegacyFilterType.Manual['@Value'] = highPass ? 1 : 0;
|
||||||
filter.Slope.Manual['@Value'] = highPass ? 'false' : 'true';
|
filter.Slope.Manual['@Value'] = highPass ? 'false' : 'true';
|
||||||
filter.Cutoff.Manual['@Value'] = highPass ? 20 + value * 0.7 * 115 : 20 + value * 0.9 * 115;
|
filter.Cutoff.Manual['@Value'] = convertGroupFaderValue(parameter, value, { track });
|
||||||
return { AutoFilter: filter };
|
return { AutoFilter: filter };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user