From b039ee6c1f09fbd3aa8553c34a192382580cb551 Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 13 Jul 2019 18:18:52 -0400 Subject: [PATCH] Absolute Pitch Shift Addressing #865, we want to be able to shift pitch by either a relative (note space) frequency or an absolute (frequency space) frequency amount. This change is incomplete, and edit this when rebasing but here we do the following 1. Make the pitch parameter allow absolute for pitch_semi_7b 2. Make sure the absolute property saves and restores 3. In SurgeVoice plumb through a note-setter function which will allow us to find the note equivalent to the absolute shift from a base We do not in this change find that note equivalent. So absolute right now is same as pitch = 0 in an oscillator. --- src/common/Parameter.cpp | 6 ++++- src/common/dsp/SurgeVoice.cpp | 43 ++++++++++++++++------------------- src/common/dsp/SurgeVoice.h | 13 +++++++++++ 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/common/Parameter.cpp b/src/common/Parameter.cpp index e6e55131165..cee9a415349 100644 --- a/src/common/Parameter.cpp +++ b/src/common/Parameter.cpp @@ -175,6 +175,7 @@ bool Parameter::can_be_absolute() switch (ctrltype) { case ct_oscspread: + case ct_pitch_semi7bp: return true; } return false; @@ -798,7 +799,10 @@ void Parameter::get_display(char* txt, bool external, float ef) sprintf(txt, "%.2f semitones", f); break; case ct_pitch_semi7bp: - sprintf(txt, "%.2f", get_extended(f)); + if(absolute) + sprintf(txt, "%.1f Hz", 10 * get_extended(f)); + else + sprintf(txt, "%.2f", get_extended(f)); break; default: sprintf(txt, "%.2f", f); diff --git a/src/common/dsp/SurgeVoice.cpp b/src/common/dsp/SurgeVoice.cpp index 84868888981..0e0d1d74a84 100644 --- a/src/common/dsp/SurgeVoice.cpp +++ b/src/common/dsp/SurgeVoice.cpp @@ -490,10 +490,9 @@ bool SurgeVoice::process_block(QuadFilterChainState& Q, int Qe) if (osc3 || ring23 || ((osc1 || osc2) && (FMmode == fm_3to2to1)) || (osc1 && (FMmode == fm_2and3to1))) { - osc[2]->process_block((scene->osc[2].keytrack.val.b ? state.pitch : ktrkroot) + - localcopy[scene->osc[2].pitch.param_id_in_scene].f * - (scene->osc[2].pitch.extend_range ? 12.f : 1.f) + - 12 * scene->osc[2].octave.val.i, + osc[2]->process_block(noteShiftFromPitchParam( (scene->osc[2].keytrack.val.b ? state.pitch : ktrkroot) + + 12 * scene->osc[2].octave.val.i, + 2 ), drift, is_wide); if (osc3) @@ -518,19 +517,18 @@ bool SurgeVoice::process_block(QuadFilterChainState& Q, int Qe) { if (FMmode == fm_3to2to1) { - osc[1]->process_block((scene->osc[1].keytrack.val.b ? state.pitch : ktrkroot) + - localcopy[scene->osc[1].pitch.param_id_in_scene].f * - (scene->osc[1].pitch.extend_range ? 12.f : 1.f) + - 12 * scene->osc[1].octave.val.i, + osc[1]->process_block(noteShiftFromPitchParam((scene->osc[1].keytrack.val.b ? state.pitch : ktrkroot) + + 12 * scene->osc[1].octave.val.i, + 1 ), + drift, is_wide, true, db_to_linear(localcopy[scene->fm_depth.param_id_in_scene].f)); } else { - osc[1]->process_block((scene->osc[1].keytrack.val.b ? state.pitch : ktrkroot) + - localcopy[scene->osc[1].pitch.param_id_in_scene].f * - (scene->osc[1].pitch.extend_range ? 12.f : 1.f) + - 12 * scene->osc[1].octave.val.i, + osc[1]->process_block(noteShiftFromPitchParam((scene->osc[1].keytrack.val.b ? state.pitch : ktrkroot) + + 12 * scene->osc[1].octave.val.i, + 1), drift, is_wide); } if (osc2) @@ -557,28 +555,25 @@ bool SurgeVoice::process_block(QuadFilterChainState& Q, int Qe) if (FMmode == fm_2and3to1) { add_block(osc[1]->output, osc[2]->output, fmbuffer, BLOCK_SIZE_OS_QUAD); - osc[0]->process_block((scene->osc[0].keytrack.val.b ? state.pitch : ktrkroot) + - localcopy[scene->osc[0].pitch.param_id_in_scene].f * - (scene->osc[0].pitch.extend_range ? 12.f : 1.f) + - 12 * scene->osc[0].octave.val.i, + osc[0]->process_block(noteShiftFromPitchParam((scene->osc[0].keytrack.val.b ? state.pitch : ktrkroot) + + 12 * scene->osc[0].octave.val.i, 0 ), drift, is_wide, true, db_to_linear(localcopy[scene->fm_depth.param_id_in_scene].f)); } else if (FMmode) { - osc[0]->process_block((scene->osc[0].keytrack.val.b ? state.pitch : 60) + - localcopy[scene->osc[0].pitch.param_id_in_scene].f * - (scene->osc[0].pitch.extend_range ? 12.f : 1.f) + - 12 * scene->osc[0].octave.val.i, + osc[0]->process_block(noteShiftFromPitchParam((scene->osc[0].keytrack.val.b ? state.pitch : 60) + + 12 * scene->osc[0].octave.val.i, + 0), + drift, is_wide, true, db_to_linear(localcopy[scene->fm_depth.param_id_in_scene].f)); } else { - osc[0]->process_block((scene->osc[0].keytrack.val.b ? state.pitch : ktrkroot) + - localcopy[scene->osc[0].pitch.param_id_in_scene].f * - (scene->osc[0].pitch.extend_range ? 12.f : 1.f) + - 12 * scene->osc[0].octave.val.i, + osc[0]->process_block(noteShiftFromPitchParam((scene->osc[0].keytrack.val.b ? state.pitch : ktrkroot) + + 12 * scene->osc[0].octave.val.i, + 0), drift, is_wide); } if (osc1) diff --git a/src/common/dsp/SurgeVoice.h b/src/common/dsp/SurgeVoice.h index 863552d1924..7b7a1a00b1d 100644 --- a/src/common/dsp/SurgeVoice.h +++ b/src/common/dsp/SurgeVoice.h @@ -50,6 +50,19 @@ class alignas(16) SurgeVoice SurgeVoiceState state; int age, age_release; + inline float noteShiftFromPitchParam( float pitch0 /* the key + octave */, int oscNum /* The osc for pitch diffs */) + { + if( scene->osc[oscNum].pitch.absolute ) + { + return pitch0; + } + else + { + return pitch0 + localcopy[scene->osc[oscNum].pitch.param_id_in_scene].f * + (scene->osc[oscNum].pitch.extend_range ? 12.f : 1.f); + } + } + private: template void calc_ctrldata(QuadFilterChainState*, int); void update_portamento();