diff --git a/configure.py b/configure.py index f32819a6..efc9117d 100755 --- a/configure.py +++ b/configure.py @@ -919,13 +919,22 @@ LIBS = [ }, { "lib": "musyx", - #"mw_version": "1.2.5", - #"cflags": "-proc gecko -fp hard -nodefaults -nosyspath -i include -i libc -g -sym on -D_DEBUG=1 -enum int -DMUSY_VERSION_MAJOR=1 -DMUSY_VERSION_MINOR=5 -DMUSY_VERSION_PATCH=3", + + ### MusyX 1.5.3 (debug) + # "mw_version": "1.2.5", + # "cflags": "-proc gecko -fp hard -nodefaults -nosyspath -i include -i libc -g -sym on -D_DEBUG=1 -enum int -DMUSY_VERSION_MAJOR=1 -DMUSY_VERSION_MINOR=5 -DMUSY_VERSION_PATCH=3", + + ### MusyX 2.0.3 (debug) + # "mw_version": "1.3.2", + # "cflags": "-proc gecko -fp hard -nodefaults -nosyspath -i include -i libc -g -sym on -D_DEBUG=1 -enum int -DMUSY_VERSION_MAJOR=2 -DMUSY_VERSION_MINOR=0 -DMUSY_VERSION_PATCH=3", + + ### MusyX 1.5.4 (release) "mw_version": "1.3.2", "cflags": "$cflags_musyx -DMUSY_VERSION_MAJOR=1 -DMUSY_VERSION_MINOR=5 -DMUSY_VERSION_PATCH=4", + "host": False, "objects": [ - ["musyx/runtime/seq", False], + ["musyx/runtime/seq", True], ["musyx/runtime/synth", False], ["musyx/runtime/seq_api", True], ["musyx/runtime/snd_synthapi", True, {"add_to_all": False}], diff --git a/include/musyx/seq.h b/include/musyx/seq.h index e16224ad..67a1308f 100644 --- a/include/musyx/seq.h +++ b/include/musyx/seq.h @@ -58,10 +58,13 @@ typedef struct NOTE_DATA { } NOTE_DATA; typedef struct PRG_STATE { - // total size: 0x4 + // total size: 0x4 (>=2.0: 0x6) u16 macId; // offset 0x0, size 0x2 u8 priority; // offset 0x2, size 0x1 u8 maxVoices; // offset 0x3, size 0x1 +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 0) + u8 program; // offset 0x4, size 0x1 +#endif } PRG_STATE; typedef struct SEQ_STREAM { @@ -103,7 +106,7 @@ typedef struct SEQ_EVENT { typedef struct MTRACK_DATA { // total size: 0x8 volatile u32 time; // offset 0x0, size 0x4 - u32 bpm; // offset 0x4, size 0x4 + u32 bpm; // offset 0x4, size 0x4 } MTRACK_DATA; typedef struct MTRACK { diff --git a/include/musyx/synth.h b/include/musyx/synth.h index 7ed2bffc..4c82d366 100644 --- a/include/musyx/synth.h +++ b/include/musyx/synth.h @@ -24,9 +24,12 @@ bool synthFXSetCtrl14(SND_VOICEID vid, u8 ctrl, u16 value); bool synthSendKeyOff(SND_VOICEID vid); SND_VOICEID synthFXStart(u16 fid, u8 vol, u8 pan, u8 studio, u32 itd); void synthVolume(u8 volume, u16 time, u8 vGroup, u8 seqMode, u32 seqId); -u32 synthStartSound(u16 id, u8 prio, u8 max, u8 key, u8 vol, u8 panning, u8 midi, u8 midiSet, - u8 section, u16 step, u16 trackid, u8 vGroup, s16 prioOffset, u8 studio, - u32 itd); +u32 synthStartSound(u16 id, u8 prio, u8 max, +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 0) + unsigned long sourceID, +#endif + u8 key, u8 vol, u8 panning, u8 midi, u8 midiSet, u8 section, u16 step, + u16 trackid, u8 vGroup, s16 prioOffset, u8 studio, u32 itd); bool synthIsFadeOutActive(u8 vGroup); /* TODO: Move this where it belongs */ diff --git a/src/musyx/runtime/seq.c b/src/musyx/runtime/seq.c index 62938c34..a9c6fb9d 100644 --- a/src/musyx/runtime/seq.c +++ b/src/musyx/runtime/seq.c @@ -5,14 +5,14 @@ static NOTE seqNote[256]; SEQ_INSTANCE seqInstance[8]; u16 seqMIDIPriority[8][16]; -static SEQ_INSTANCE* cseq = NULL; -static NOTE* noteFree = NULL; -static u32 curSeqId = 0; -static bool8 curFadeOutState = 0; static u32 seq_next_id = 0; +static bool8 curFadeOutState = 0; +static u32 curSeqId = 0; +static NOTE* noteFree = NULL; +static SEQ_INSTANCE* cseq = NULL; struct SEQ_INSTANCE* seqFreeRoot = NULL; -struct SEQ_INSTANCE* seqActiveRoot = NULL; struct SEQ_INSTANCE* seqPausedRoot = NULL; +struct SEQ_INSTANCE* seqActiveRoot = NULL; static void ClearNotes() { NOTE* ln = NULL; // r30 @@ -288,6 +288,9 @@ static void DoPrgChange(SEQ_INSTANCE* seq, u8 prg, u8 midi) { seq->prgState[midi].macId = seq->normtab[prg].macro; seq->prgState[midi].priority = seq->normtab[prg].prio; seq->prgState[midi].maxVoices = seq->normtab[prg].maxVoices; +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 0) + seq->prgState[midi].program = prg; +#endif return; } @@ -299,6 +302,9 @@ static void DoPrgChange(SEQ_INSTANCE* seq, u8 prg, u8 midi) { seq->prgState[midi].macId = seq->drumtab[prg].macro; seq->prgState[midi].priority = seq->drumtab[prg].prio; seq->prgState[midi].maxVoices = seq->drumtab[prg].maxVoices; +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 0) + seq->prgState[midi].program = prg; +#endif } static void BuildTransTab(u8* tab, PAGE* page) { @@ -488,7 +494,7 @@ u32 seqStartPlay(PAGE* norm, PAGE* drum, MIDISETUP* midiSetup, u32* song, SND_PL } static void SetTickDelta(SEQ_SECTION* section, u32 deltaTime) { - float tickDelta = (float)section->bpm * (float)deltaTime * (1.f / 4096.f); + float tickDelta = (float)section->bpm * (float)deltaTime * (1.f / (40960000.f)); tickDelta *= section->speed * (1.f / 256.f); section->tickDelta[section->timeIndex].low = fmodf(tickDelta * 65536.f, 65536.f); @@ -865,7 +871,11 @@ static u8* GetStreamValue(u8* stream, u16* deltaTime, s16* deltaData) { } if ((b1 & 0x80) != 0) { +#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4) + *deltaTime = (((u16)b1 & 0x7f) << 8) | b2; +#else *deltaTime = ((b1 & 0x7f) << 8) | b2; +#endif stream += 2; } else { *deltaTime = b1; @@ -875,16 +885,26 @@ static u8* GetStreamValue(u8* stream, u16* deltaTime, s16* deltaData) { b1 = stream[0]; b2 = stream[1]; if ((b1 & 0x80) != 0) { +#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4) + v = (((u16)b1 & 0x7f) << 8) | b2; + v |= (v & 0x4000) << 1; +#else v = ((b1 & 0x7f) << 8) | b2; v <<= 1; v >>= 1; +#endif *deltaData = v; stream += 2; } else { +#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4) + b1 |= (b1 & 0x40) << 1; + *deltaData = (s8)b1; +#else v = b1; v <<= 9; v >>= 9; *deltaData = v; +#endif stream += 1; } @@ -1062,6 +1082,8 @@ static SEQ_EVENT* GetGlobalEvent(SEQ_SECTION* section) { return ev; } +#define Clamp(value, min, max) ((value) > (max) ? (max) : (value) < (min) ? (min) : (value)) + static SEQ_EVENT* HandleEvent(SEQ_EVENT* event, u8 secIndex, u32* loopFlag) { CPAT* pa; // r26 NOTE_DATA* pe; // r24 @@ -1137,7 +1159,6 @@ static SEQ_EVENT* HandleEvent(SEQ_EVENT* event, u8 secIndex, u32* loopFlag) { KeyOffNotes(); break; default: - // case 0x6b: inpSetMidiCtrl(velocity & 0x7f, midi, curSeqId, key & 0x7f); break; } @@ -1148,23 +1169,19 @@ static SEQ_EVENT* HandleEvent(SEQ_EVENT* event, u8 secIndex, u32* loopFlag) { if ((cseq->trackMute[event->trackId / 32] & (1 << (event->trackId & 0x1f))) != 0) { if ((macId = cseq->prgState[midi].macId) != 0xffff) { key += pa->patternInfo->transpose; - if (key > 0x7f) { - key = 0x7f; - } else if (key < 0) { - key = 0; - } + key = Clamp(key, 0, 0x7f); velocity += pa->patternInfo->velocityAdd; - if (velocity > 0x7f) { - velocity = 0x7f; - } else if (velocity < 0) { - velocity = 0; - } + velocity = Clamp(velocity, 0, 0x7f); if ((note = AllocateNote(event->time + pe->length, secIndex)) != NULL) { if ((note->id = synthStartSound( - macId, cseq->prgState[midi].priority, cseq->prgState[midi].maxVoices, key, - velocity, 64, midi, curSeqId, secIndex, 0, event->trackId, + macId, cseq->prgState[midi].priority, cseq->prgState[midi].maxVoices, +#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 0) + cseq->groupID | (cseq->prgState[midi].program << 16) | + ((midi == 9 ? 1 : 0) << 24), +#endif + key, velocity, 64, midi, curSeqId, secIndex, 0, event->trackId, cseq->trackVolGroup[event->trackId], curFadeOutState ? -1 : 0, cseq->defStudio, synthITDDefault[cseq->defStudio].music)) == SND_ID_ERROR) { FreeNote(note);