Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stereo Chorus #120

Merged
merged 2 commits into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,8 @@ typedef enum SyncLevel_ {
#define MOD_FX_TYPE_FLANGER 1
#define MOD_FX_TYPE_CHORUS 2
#define MOD_FX_TYPE_PHASER 3
#define NUM_MOD_FX_TYPES 4
#define MOD_FX_TYPE_CHORUS_STEREO 4
#define NUM_MOD_FX_TYPES 5

#define SAMPLE_MAX_TRANSPOSE 24
#define SAMPLE_MIN_TRANSPOSE (-96)
Expand Down
10 changes: 6 additions & 4 deletions src/deluge/gui/ui/sound_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1208,7 +1208,7 @@ class MenuItemModFXType : public MenuItemSelection {
}
}
char const** getOptions() {
static char const* options[] = {"OFF", "FLANGER", "CHORUS", "PHASER", NULL};
static char const* options[] = {"OFF", "FLANGER", "CHORUS", "PHASER", "STEREO CHORUS", NULL};
return options;
}
int getNumOptions() { return NUM_MOD_FX_TYPES; }
Expand All @@ -1229,16 +1229,18 @@ class MenuItemModFXDepth final : public MenuItemPatchedParamInteger {
public:
MenuItemModFXDepth(char const* newName = 0, int newP = 0) : MenuItemPatchedParamInteger(newName, newP) {}
bool isRelevant(Sound* sound, int whichThing) {
return (sound->modFXType == MOD_FX_TYPE_CHORUS || sound->modFXType == MOD_FX_TYPE_PHASER);
return (sound->modFXType == MOD_FX_TYPE_CHORUS || sound->modFXType == MOD_FX_TYPE_CHORUS_STEREO
|| sound->modFXType == MOD_FX_TYPE_PHASER);
}
} modFXDepthMenu;

class MenuItemModFXOffset final : public MenuItemUnpatchedParam {
public:
MenuItemModFXOffset(char const* newName = 0, int newP = 0) : MenuItemUnpatchedParam(newName, newP) {}
bool isRelevant(Sound* sound, int whichThing) {
return (!sound
|| sound->modFXType == MOD_FX_TYPE_CHORUS); // TODO: really want to receive a ModControllableAudio here!
return (!sound || sound->modFXType == MOD_FX_TYPE_CHORUS
|| sound->modFXType
== MOD_FX_TYPE_CHORUS_STEREO); // TODO: really want to receive a ModControllableAudio here!
}
} modFXOffsetMenu;

Expand Down
11 changes: 8 additions & 3 deletions src/deluge/model/global_effectable/global_effectable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ bool GlobalEffectable::modEncoderButtonAction(uint8_t whichModEncoder, bool on,
case MOD_FX_TYPE_CHORUS:
displayText = "CHORUS";
break;

case MOD_FX_TYPE_CHORUS_STEREO:
displayText = "STEREO CHORUS";
break;
}
numericDriver.displayPopup(displayText);
ensureModFXParamIsValid();
Expand Down Expand Up @@ -312,12 +316,12 @@ void GlobalEffectable::ensureModFXParamIsValid() {
}
}
else if (currentModFXParam == MOD_FX_PARAM_OFFSET) {
if (modFXType != MOD_FX_TYPE_CHORUS) {
if (modFXType != MOD_FX_TYPE_CHORUS && modFXType != MOD_FX_TYPE_CHORUS_STEREO) {
goto ohNo;
}
}
else { // MOD_FX_PARAM_FEEDBACK
if (modFXType == MOD_FX_TYPE_CHORUS) {
if (modFXType == MOD_FX_TYPE_CHORUS || modFXType == MOD_FX_TYPE_CHORUS_STEREO) {
goto ohNo;
}
}
Expand Down Expand Up @@ -688,7 +692,8 @@ void GlobalEffectable::processFXForGlobalEffectable(StereoSample* inputBuffer, i

// For GlobalEffectables, mod FX buffer memory is allocated here in the rendering routine - this might seem strange, but
// it's because unlike for Sounds, the effect can be switched on and off by changing a parameter like "depth".
if (modFXTypeNow == MOD_FX_TYPE_FLANGER || modFXTypeNow == MOD_FX_TYPE_CHORUS) {
if (modFXTypeNow == MOD_FX_TYPE_FLANGER || modFXTypeNow == MOD_FX_TYPE_CHORUS
|| modFXTypeNow == MOD_FX_TYPE_CHORUS_STEREO) {
if (!modFXBuffer) {
modFXBuffer =
(StereoSample*)generalMemoryAllocator.alloc(modFXBufferSize * sizeof(StereoSample), NULL, false, true);
Expand Down
11 changes: 9 additions & 2 deletions src/deluge/model/mod_controllable/mod_controllable_audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ void ModControllableAudio::processFX(StereoSample* buffer, int numSamples, int m
modFXLFOWaveType = OSC_TYPE_SINE;
}
}
else if (modFXType == MOD_FX_TYPE_CHORUS) {
else if (modFXType == MOD_FX_TYPE_CHORUS || modFXType == MOD_FX_TYPE_CHORUS_STEREO) {
modFXDelayOffset = multiply_32x32_rshift32(
modFXMaxDelay, (unpatchedParams->getValue(PARAM_UNPATCHED_MOD_FX_OFFSET) >> 1) + 1073741824);
thisModFXDelayDepth = multiply_32x32_rshift32(modFXDelayOffset, modFXDepth) << 2;
Expand Down Expand Up @@ -209,6 +209,13 @@ void ModControllableAudio::processFX(StereoSample* buffer, int numSamples, int m
multiply_32x32_rshift32_rounded(modFXBuffer[(sample1Pos - 1) & modFXBufferIndexMask].l, strength2);
int32_t modFXOutputL = scaledValue1L + scaledValue2L;

if (modFXType == MOD_FX_TYPE_CHORUS_STEREO) {
delayTime = multiply_32x32_rshift32(lfoOutput, -thisModFXDelayDepth) + modFXDelayOffset;
strength2 = (delayTime & 65535) << 15;
strength1 = (65535 << 15) - strength2;
sample1Pos = modFXBufferWriteIndex - ((delayTime) >> 16);
}

int32_t scaledValue1R =
multiply_32x32_rshift32_rounded(modFXBuffer[sample1Pos & modFXBufferIndexMask].r, strength1);
int32_t scaledValue2R =
Expand Down Expand Up @@ -1535,7 +1542,7 @@ void ModControllableAudio::wontBeRenderedForAWhile() {
}

void ModControllableAudio::clearModFXMemory() {
if (modFXType == MOD_FX_TYPE_FLANGER || modFXType == MOD_FX_TYPE_CHORUS) {
if (modFXType == MOD_FX_TYPE_FLANGER || modFXType == MOD_FX_TYPE_CHORUS || modFXType == MOD_FX_TYPE_CHORUS_STEREO) {
if (modFXBuffer) {
memset(modFXBuffer, 0, modFXBufferSize * sizeof(StereoSample));
}
Expand Down
4 changes: 2 additions & 2 deletions src/deluge/processing/sound/sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ void Sound::setupAsBlankSynth(ParamManager* paramManager) {

// Returns false if not enough ram
bool Sound::setModFXType(int newType) {
if (newType == MOD_FX_TYPE_FLANGER || newType == MOD_FX_TYPE_CHORUS) {
if (newType == MOD_FX_TYPE_FLANGER || newType == MOD_FX_TYPE_CHORUS || newType == MOD_FX_TYPE_CHORUS_STEREO) {
if (!modFXBuffer) {
// TODO: should give an error here if no free ram
modFXBuffer =
Expand Down Expand Up @@ -1718,7 +1718,7 @@ void Sound::reassessRenderSkippingStatus(ModelStackWithSoundFlags* modelStack, b
}

int waitSamples =
(modFXType == MOD_FX_TYPE_CHORUS)
(modFXType == MOD_FX_TYPE_CHORUS || modFXType == MOD_FX_TYPE_CHORUS_STEREO)
? (20 * 44)
: (90
* 441); // 20 and 900 mS respectively. Lots is required for feeding-back flanger or phaser
Expand Down
4 changes: 4 additions & 0 deletions src/deluge/util/functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,9 @@ char const* fxTypeToString(int fxType) {
case MOD_FX_TYPE_CHORUS:
return "chorus";

case MOD_FX_TYPE_CHORUS_STEREO:
return "StereoChorus";

case MOD_FX_TYPE_PHASER:
return "phaser";

Expand All @@ -984,6 +987,7 @@ char const* fxTypeToString(int fxType) {
int stringToFXType(char const* string) {
if (!strcmp(string, "flanger")) return MOD_FX_TYPE_FLANGER;
else if (!strcmp(string, "chorus")) return MOD_FX_TYPE_CHORUS;
else if (!strcmp(string, "StereoChorus")) return MOD_FX_TYPE_CHORUS_STEREO;
else if (!strcmp(string, "phaser")) return MOD_FX_TYPE_PHASER;
else return MOD_FX_TYPE_NONE;
}
Expand Down