From 4176e60993f05f9168fd41a2bce048c22f76bb43 Mon Sep 17 00:00:00 2001 From: Starg Date: Thu, 5 Sep 2019 13:30:02 +0900 Subject: [PATCH] Implement random selection --- timidity/instrum.c | 16 ++++++++++++++++ timidity/instrum.h | 5 +++++ timidity/mt19937ar.h | 1 + timidity/playmidi.c | 14 ++++++++++++++ timidity/sfz.cpp | 19 +++++++++++++++++++ timidity/smplfile.c | 3 +++ timidity/timidity.c | 4 ++++ 7 files changed, 62 insertions(+) diff --git a/timidity/instrum.c b/timidity/instrum.c index 245388f6..d451521d 100644 --- a/timidity/instrum.c +++ b/timidity/instrum.c @@ -948,6 +948,20 @@ static void apply_bank_parameter(Instrument *ip, ToneBankElement *tone) for (i = 0; i < ip->samples; i++) { ip->sample[i].seq_position = tone->seq_position; } + if (tone->lorand >= 0 || tone->hirand >= 0) + for (i = 0; i < ip->samples; i++) { + sp = &ip->sample[i]; + if (sp->enable_rand) { + if (tone->lorand >= 0 && sp->lorand < tone->lorand) + sp->lorand = tone->lorand; + if (tone->hirand >= 0 && tone->hirand < sp->hirand) + sp->hirand = tone->hirand; + } else { + sp->enable_rand = 1; + sp->lorand = (tone->lorand >= 0 ? tone->lorand : 0); + sp->hirand = (tone->hirand >= 0 ? tone->hirand : 1); + } + } } #define READ_CHAR(thing) { \ @@ -2468,6 +2482,8 @@ static void init_tone_bank_element(ToneBankElement *tone) tone->vfxe_num = 0; tone->seq_length = 0; tone->seq_position = 0; + tone->lorand = -1; + tone->hirand = -1; } ///r diff --git a/timidity/instrum.h b/timidity/instrum.h index 9cb200ba..7753fbac 100644 --- a/timidity/instrum.h +++ b/timidity/instrum.h @@ -81,6 +81,9 @@ typedef struct _Sample { int32 seq_length; /* length of the round robin, 0 == disabled */ int32 seq_position; /* 1-based position within the round robin, 0 == disabled */ + int8 enable_rand; + FLOAT_T lorand; + FLOAT_T hirand; } Sample; ///r @@ -208,6 +211,8 @@ typedef struct { int sample_pan, sample_width; int32 seq_length; int32 seq_position; + FLOAT_T lorand; + FLOAT_T hirand; } ToneBankElement; #define MAGIC_ERROR_INSTRUMENT ((Instrument *)(-1)) diff --git a/timidity/mt19937ar.h b/timidity/mt19937ar.h index a53211fe..14f0f4c5 100755 --- a/timidity/mt19937ar.h +++ b/timidity/mt19937ar.h @@ -7,5 +7,6 @@ extern void init_by_array(unsigned long [], unsigned long); extern unsigned long genrand_int32(void); extern long genrand_int31(void); extern double genrand_real1(void); +extern double genrand_real2(void); #endif /* ___MT19937AR_H_ */ diff --git a/timidity/playmidi.c b/timidity/playmidi.c index 9884aa39..aaabc5be 100644 --- a/timidity/playmidi.c +++ b/timidity/playmidi.c @@ -66,6 +66,7 @@ #include "resample.h" #include "thread.h" #include "sndfontini.h" +#include "mt19937ar.h" extern int convert_mod_to_midi_file(MidiEvent * ev); @@ -3367,10 +3368,23 @@ static int select_play_sample(Sample *splist, ƒTƒ“ƒvƒ‹Žw’è‚Í ƒm[ƒiƒ“ƒo[,ƒxƒƒVƒeƒB ‚ªŠeƒŒƒ“ƒW“à‚É‚ ‚é‚à‚Ì‘S‚Ä ŽŸ‚ÉŽw’è‚̃Tƒ“ƒvƒ‹Ý’è(scale_factor)‚ðŒ³‚ÉÄ¶Žü”g”‚ðŽw’è */ + int rand_calculated = 0; + FLOAT_T rand_val; + for (i = 0, sp = splist; i < nsp; i++, sp++) { if (((sp->low_key <= *note && sp->high_key >= *note)) && sp->low_vel <= vel && sp->high_vel >= vel) { + if (sp->enable_rand) { + if (!rand_calculated) { + rand_val = genrand_real2(); + rand_calculated = 1; + } + + if (rand_val < sp->lorand || sp->hirand <= rand_val) + continue; + } + if (sp->seq_length > 0) { int32 seq_count = channel[ch].seq_counters[elm][i]; channel[ch].seq_counters[elm][i]++; diff --git a/timidity/sfz.cpp b/timidity/sfz.cpp index 50682d3a..31b8d7f8 100644 --- a/timidity/sfz.cpp +++ b/timidity/sfz.cpp @@ -816,11 +816,13 @@ enum class OpCodeKind AmpVelTrack, DefaultPath, HiKey, + HiRand, HiVelocity, LoKey, LoopEnd, LoopMode, LoopStart, + LoRand, LoVelocity, Offset, Key, @@ -985,9 +987,11 @@ public: case OpCodeKind::AmpEG_Sustain: case OpCodeKind::AmpKeyTrack: case OpCodeKind::AmpVelTrack: + case OpCodeKind::HiRand: case OpCodeKind::HiVelocity: case OpCodeKind::LoopEnd: case OpCodeKind::LoopStart: + case OpCodeKind::LoRand: case OpCodeKind::LoVelocity: case OpCodeKind::Offset: case OpCodeKind::Pan: @@ -1129,12 +1133,14 @@ private: {"amp_veltrack"sv, OpCodeKind::AmpVelTrack}, {"default_path"sv, OpCodeKind::DefaultPath}, {"hikey"sv, OpCodeKind::HiKey}, + {"hirand"sv, OpCodeKind::HiRand}, {"hivel"sv, OpCodeKind::HiVelocity}, {"key"sv, OpCodeKind::Key}, {"lokey"sv, OpCodeKind::LoKey}, {"loop_end"sv, OpCodeKind::LoopEnd}, {"loop_mode"sv, OpCodeKind::LoopMode}, {"loop_start"sv, OpCodeKind::LoopStart}, + {"lorand"sv, OpCodeKind::LoRand}, {"lovel"sv, OpCodeKind::LoVelocity}, {"offset"sv, OpCodeKind::Offset}, {"pan"sv, OpCodeKind::Pan}, @@ -1659,6 +1665,19 @@ private: loc.Line ); } + + if (auto loRand = flatSection.GetAs(OpCodeKind::LoRand)) + { + s.enable_rand = 1; + s.lorand = std::clamp(loRand.value(), 0.0, 1.0); + s.hirand = std::clamp(flatSection.GetAs(OpCodeKind::HiRand).value_or(1.0), 0.0, 1.0); + } + else if (auto hiRand = flatSection.GetAs(OpCodeKind::HiRand)) + { + s.enable_rand = 1; + s.lorand = 0.0; + s.hirand = std::clamp(hiRand.value(), 0.0, 1.0); + } } return pSampleInstrument; diff --git a/timidity/smplfile.c b/timidity/smplfile.c index 7f0cdf5a..05a19ef5 100644 --- a/timidity/smplfile.c +++ b/timidity/smplfile.c @@ -1499,6 +1499,9 @@ static void initialize_sample(Instrument *inst, int frames, int sample_bits, int sample->seq_length = 0; sample->seq_position = 0; + sample->enable_rand = 0; + sample->lorand = -1; + sample->hirand = -1; } if (samples <= 6 && (panning = gen_pan_list[samples - 1]) != NULL) { diff --git a/timidity/timidity.c b/timidity/timidity.c index cb0c4930..e20465d0 100644 --- a/timidity/timidity.c +++ b/timidity/timidity.c @@ -1709,6 +1709,10 @@ static int set_gus_patchconf_opts(const char *name, tone->seq_length = atoi(cp); else if (! strcmp(opts, "seqpos")) tone->seq_position = atoi(cp); + else if (! strcmp(opts, "lorand")) + tone->lorand = atof(cp); + else if (! strcmp(opts, "hirand")) + tone->hirand = atof(cp); else if (! strcmp(opts, "hpf")){ /* hpf */ if(tone->hpfnum) free_ptr_list(tone->hpf, tone->hpfnum); -- 2.11.0