Skip to content

Commit

Permalink
Fix some bugs related to parsing effect parameters
Browse files Browse the repository at this point in the history
Closes #23.

There is still some sus-ness in there, but it's
fine with test tracks, so I'm leaving it for another
day.
  • Loading branch information
YuriSizov committed Nov 11, 2024
1 parent 40f9d6e commit 5726426
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 24 deletions.
1 change: 1 addition & 0 deletions example/gui/TunesView.gd
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func _play_selected() -> void:

var selected_tune := _tunes[selected_items[0]]
Controller.music_player.play_tune(selected_tune.mml_string)

if selected_tune.author.is_empty():
_tune_status.text = "Now Playing: %s" % [ selected_tune.title ]
else:
Expand Down
59 changes: 36 additions & 23 deletions src/effector/si_effect_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,7 @@ int SiEffectStream::process(int p_start_idx, int p_length, bool p_write_in_strea
//

void SiEffectStream::_add_effect(String p_cmd, Vector<double> p_args, int p_argc) {
if (p_argc == 0) {
return;
}
ERR_FAIL_COND_MSG(p_cmd.is_empty(), "SiEffectStream: Trying to add an effect with no name.");

Ref<SiEffectBase> effect = SiEffector::get_effect_instance(p_cmd);
if (effect.is_valid()) {
Expand All @@ -125,15 +123,13 @@ void SiEffectStream::_add_effect(String p_cmd, Vector<double> p_args, int p_argc
}
}

void SiEffectStream::_set_volume(int p_slot, String p_cmd, Vector<double> p_args, int p_argc) {
if (p_argc == 0) {
return;
}
void SiEffectStream::_set_postfix_param(int p_slot, String p_cmd, Vector<double> p_args, int p_argc) {
ERR_FAIL_COND_MSG(p_cmd.is_empty(), vformat("SiEffectStream: Trying to set an effect param with no name in slot %d.", p_slot));

if (p_cmd == "p") {
_pan = (((int)p_args[0]) << 4) - 64;
set_pan((((int)p_args[0]) << 4) - 64);
} else if (p_cmd == "@p") {
_pan = (int)p_args[0];
set_pan((int)p_args[0]);
} else if (p_cmd == "@v") {
double value = ((int)p_args[0]) * 0.0078125;
set_stream_send(0, CLAMP(value, 0, 1));
Expand All @@ -147,28 +143,40 @@ void SiEffectStream::_set_volume(int p_slot, String p_cmd, Vector<double> p_args
value = ((int)p_args[i]) * 0.0078125;
set_stream_send(i + p_slot, CLAMP(value, 0, 1));
}
} else {
ERR_PRINT(vformat("SiEffectStream: Trying to set an unknown effect param (%s) in slot %d.", p_cmd, p_slot));
}
}

void SiEffectStream::parse_mml(int p_slot, String p_mml, String p_postfix) {
const int max_argc = 16;

// SUS: Slot number is only used to set postfix params, but not the effect itself.
// It is possible that the given slot number is incorrect and thus the effect is
// added in a different position than the params are set in.

String command;
int argc = 0;
Vector<double> args;
args.resize_zeroed(max_argc);

#define CLEAR_ARGS() \
command = ""; \
for (int a = 0; a < max_argc; a++) { \
args.write[a] = NAN; \
} \
argc = 0;

#define CONSUME_ARG(m_index) \
if (res->get_string(m_index).is_valid_float()) { \
args.write[argc] = res->get_string(m_index).to_float(); \
} \
argc++;

// Reset and clear everything.
initialize(0);
CLEAR_ARGS();

String command;

Ref<RegEx> re_mml = RegEx::create_from_string("([a-zA-Z_]+|,)\\s*([.\\-\\d]+)?");
Ref<RegEx> re_postfix = RegEx::create_from_string("(p|@p|@v|,)\\s*([.\\-\\d]+)?");

Expand All @@ -179,19 +187,21 @@ void SiEffectStream::parse_mml(int p_slot, String p_mml, String p_postfix) {
Ref<RegExMatch> res = matches[i];

if (res->get_string(1) == ",") {
args.write[argc] = res->get_string(2).to_float();
argc++;
CONSUME_ARG(2);
} else {
_add_effect(command, args, argc);
if (!command.is_empty()) {
_add_effect(command, args, argc);
}
CLEAR_ARGS();

command = res->get_string(1);
args.write[0] = res->get_string(2).to_float();
argc = 1;
CONSUME_ARG(2);
}
}

_add_effect(command, args, argc);
if (!command.is_empty()) {
_add_effect(command, args, argc);
}
CLEAR_ARGS();

// Parse the postfix.
Expand All @@ -201,22 +211,25 @@ void SiEffectStream::parse_mml(int p_slot, String p_mml, String p_postfix) {
Ref<RegExMatch> res = matches[i];

if (res->get_string(1) == ",") {
args.write[argc] = res->get_string(2).to_float();
argc++;
CONSUME_ARG(2);
} else {
_set_volume(p_slot, command, args, argc);
if (!command.is_empty()) {
_set_postfix_param(p_slot, command, args, argc);
}
CLEAR_ARGS();

command = res->get_string(1);
args.write[0] = res->get_string(2).to_float();
argc = 1;
CONSUME_ARG(2);
}
}

_set_volume(p_slot, command, args, argc);
if (!command.is_empty()) {
_set_postfix_param(p_slot, command, args, argc);
}
CLEAR_ARGS();

#undef CLEAR_ARGS
#undef CONSUME_ARG
}

void SiEffectStream::initialize(int p_depth) {
Expand Down
2 changes: 1 addition & 1 deletion src/effector/si_effect_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class SiEffectStream {
Vector<SiOPMStream *> _output_streams;

void _add_effect(String p_cmd, Vector<double> p_args, int p_argc);
void _set_volume(int p_slot, String p_cmd, Vector<double> p_args, int p_argc);
void _set_postfix_param(int p_slot, String p_cmd, Vector<double> p_args, int p_argc);

public:
List<Ref<SiEffectBase>> get_chain() const { return _chain; }
Expand Down

0 comments on commit 5726426

Please sign in to comment.