Skip to content

Commit

Permalink
Add support for hz offset to base freq. mult. param source
Browse files Browse the repository at this point in the history
  • Loading branch information
Ameobea committed Nov 25, 2024
1 parent 04bbda7 commit 8b70f68
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 12 deletions.
37 changes: 29 additions & 8 deletions engine/wavetable/src/fm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1229,7 +1229,10 @@ pub enum ParamSource {
/// The value of this parameter is determined by the output of a per-voice ADSR that is
/// triggered every time that voice is triggered.
PerVoiceADSR(AdsrState),
BaseFrequencyMultiplier(f32),
BaseFrequencyMultiplier {
multiplier: f32,
offset_hz: f32,
},
MIDIControlValue {
control_index: usize,
scale: f32,
Expand Down Expand Up @@ -1358,7 +1361,10 @@ impl ParamSource {
}) * scale
+ shift
},
ParamSource::BaseFrequencyMultiplier(multiplier) => base_frequency * multiplier,
ParamSource::BaseFrequencyMultiplier {
multiplier,
offset_hz,
} => base_frequency * *multiplier + offset_hz,
ParamSource::MIDIControlValue {
control_index,
scale,
Expand Down Expand Up @@ -1420,7 +1426,10 @@ impl ParamSource {
scale: value_param_float,
shift: value_param_float_2,
}),
3 => ParamSource::BaseFrequencyMultiplier(value_param_float),
3 => ParamSource::BaseFrequencyMultiplier {
multiplier: value_param_float,
offset_hz: value_param_float_2,
},
4 => ParamSource::MIDIControlValue {
control_index: value_param_int,
scale: value_param_float,
Expand Down Expand Up @@ -1482,16 +1491,21 @@ impl ParamSource {
}
}
},
ParamSource::BaseFrequencyMultiplier(multiplier) => {
ParamSource::BaseFrequencyMultiplier {
multiplier,
offset_hz,
} => {
let base_input_ptr = base_frequencies.as_ptr() as *const v128;
let base_output_ptr = output_buf.as_ptr() as *mut v128;
let multiplier = f32x4_splat(*multiplier);
let offset = f32x4_splat(*offset_hz);

for i in 0..FRAME_SIZE / 4 {
unsafe {
let v = v128_load(base_input_ptr.add(i));
let multiplied = f32x4_mul(v, multiplier);
v128_store(base_output_ptr.add(i), multiplied);
let added = f32x4_add(multiplied, offset);
v128_store(base_output_ptr.add(i), added);
}
}
},
Expand Down Expand Up @@ -1612,10 +1626,14 @@ impl ParamSource {
ParamSource::ParamBuffer(buffer_ix) => {
output_buf.clone_from_slice(unsafe { param_buffers.get_unchecked(*buffer_ix) });
},
ParamSource::BaseFrequencyMultiplier(multiplier) =>
ParamSource::BaseFrequencyMultiplier {
multiplier,
offset_hz,
} =>
for i in 0..FRAME_SIZE {
unsafe {
*output_buf.get_unchecked_mut(i) = (*base_frequencies.get_unchecked(i)) * *multiplier;
*output_buf.get_unchecked_mut(i) =
(*base_frequencies.get_unchecked(i)) * *multiplier + *offset_hz;
};
},
ParamSource::PerVoiceADSR(AdsrState {
Expand Down Expand Up @@ -1950,7 +1968,10 @@ pub unsafe extern "C" fn init_fm_synth_ctx() -> *mut FMSynthContext {
.operator_base_frequency_sources
.as_mut_ptr()
.add(i)
.write(ParamSource::BaseFrequencyMultiplier(1.));
.write(ParamSource::BaseFrequencyMultiplier {
multiplier: 1.,
offset_hz: 0.,
});
}
let shared_gain_adsr_rendered_buffer: Box<[f32; RENDERED_BUFFER_SIZE]> =
Box::new([0.242424; RENDERED_BUFFER_SIZE]);
Expand Down
6 changes: 5 additions & 1 deletion src/ViewContextManager/AddModulePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ export const ViewContextDescriptors: ViewContextDescriptor[] = [
{ name: 'sampler', displayName: 'Sampler' },
];

const AddModulePicker: React.FC<{ onClose: () => void }> = ({ onClose }) => {
interface AddModulePickerProps {
onClose: () => void;
}

const AddModulePicker: React.FC<AddModulePickerProps> = ({ onClose }) => {
const [selectedModule, setSelectedModule] = useState(ViewContextDescriptors[0].displayName);

const settings = useMemo(
Expand Down
2 changes: 1 addition & 1 deletion src/ViewContextManager/ViewContextManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@ export const ViewContextManager: React.FC<VCMProps> = ({ engine }) => {

setModulePickerOpen(true);
}}
dangerouslySetInnerHTML={{ __html: PlusIcon }}
>
<div className='svg-wrapper' dangerouslySetInnerHTML={{ __html: PlusIcon }} />
{modulePickerOpen ? <AddModulePicker onClose={() => setModulePickerOpen(false)} /> : null}
</ViewContextIcon>
</div>
Expand Down
8 changes: 8 additions & 0 deletions src/fmSynth/ConfigureParamSource.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ const ConfigureParamSourceInnerInner: React.FC<ConfigureParamSourceInnerProps> =
state={useMemo(
() => ({
...state,
'offset hz': state.type === 'base frequency multiplier' ? state.offsetHz : undefined,
'buffer index':
state.type === 'param buffer' ? state['buffer index'].toString() : undefined,
'output range':
Expand Down Expand Up @@ -267,6 +268,13 @@ const ConfigureParamSourceInnerInner: React.FC<ConfigureParamSourceInnerProps> =
onChange(updateState(state, { multiplier: value }));
break;
}
case 'offset hz': {
if (window.isNaN(value)) {
break;
}
onChange(updateState(state, { offsetHz: value }));
break;
}
case 'enable smoothing': {
onChange(updateState(state, { smoothingCoefficient: value ? 0.99 : 0 }));
break;
Expand Down
11 changes: 9 additions & 2 deletions src/fmSynth/ParamSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export type ParamSource =
| { type: 'param buffer'; 'buffer index': number }
| { type: 'constant'; value: number }
| { type: 'adsr'; 'adsr index': number; scale: number; shift: number }
| { type: 'base frequency multiplier'; multiplier: number }
| { type: 'base frequency multiplier'; multiplier: number; offsetHz?: number }
| {
type: 'midi control';
midiControlIndex: number;
Expand Down Expand Up @@ -110,7 +110,7 @@ export const encodeParamSource = (source: ParamSource | null | undefined): Encod
valueType: 3,
valParamInt: 0,
valParamFloat: source.multiplier,
valParamFloat2: 0,
valParamFloat2: source.offsetHz ?? 0,
valParamFloat3: 0,
};
}
Expand Down Expand Up @@ -293,6 +293,13 @@ export const buildConfigureParamSourceSettings = ({
max: 16,
step: 0.125,
},
{
type: 'range',
label: 'offset hz',
min: -100,
max: 100,
step: 0.1,
},
];
}
case 'midi control': {
Expand Down

0 comments on commit 8b70f68

Please sign in to comment.