mirror of https://github.com/PrimeDecomp/prime.git
Link musyx/runtime/seq
This commit is contained in:
parent
c6ff09fb87
commit
19e9b9791f
15
configure.py
15
configure.py
|
@ -919,13 +919,22 @@ LIBS = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"lib": "musyx",
|
"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",
|
"mw_version": "1.3.2",
|
||||||
"cflags": "$cflags_musyx -DMUSY_VERSION_MAJOR=1 -DMUSY_VERSION_MINOR=5 -DMUSY_VERSION_PATCH=4",
|
"cflags": "$cflags_musyx -DMUSY_VERSION_MAJOR=1 -DMUSY_VERSION_MINOR=5 -DMUSY_VERSION_PATCH=4",
|
||||||
|
|
||||||
"host": False,
|
"host": False,
|
||||||
"objects": [
|
"objects": [
|
||||||
["musyx/runtime/seq", False],
|
["musyx/runtime/seq", True],
|
||||||
["musyx/runtime/synth", False],
|
["musyx/runtime/synth", False],
|
||||||
["musyx/runtime/seq_api", True],
|
["musyx/runtime/seq_api", True],
|
||||||
["musyx/runtime/snd_synthapi", True, {"add_to_all": False}],
|
["musyx/runtime/snd_synthapi", True, {"add_to_all": False}],
|
||||||
|
|
|
@ -58,10 +58,13 @@ typedef struct NOTE_DATA {
|
||||||
} NOTE_DATA;
|
} NOTE_DATA;
|
||||||
|
|
||||||
typedef struct PRG_STATE {
|
typedef struct PRG_STATE {
|
||||||
// total size: 0x4
|
// total size: 0x4 (>=2.0: 0x6)
|
||||||
u16 macId; // offset 0x0, size 0x2
|
u16 macId; // offset 0x0, size 0x2
|
||||||
u8 priority; // offset 0x2, size 0x1
|
u8 priority; // offset 0x2, size 0x1
|
||||||
u8 maxVoices; // offset 0x3, 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;
|
} PRG_STATE;
|
||||||
|
|
||||||
typedef struct SEQ_STREAM {
|
typedef struct SEQ_STREAM {
|
||||||
|
|
|
@ -24,9 +24,12 @@ bool synthFXSetCtrl14(SND_VOICEID vid, u8 ctrl, u16 value);
|
||||||
bool synthSendKeyOff(SND_VOICEID vid);
|
bool synthSendKeyOff(SND_VOICEID vid);
|
||||||
SND_VOICEID synthFXStart(u16 fid, u8 vol, u8 pan, u8 studio, u32 itd);
|
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);
|
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,
|
u32 synthStartSound(u16 id, u8 prio, u8 max,
|
||||||
u8 section, u16 step, u16 trackid, u8 vGroup, s16 prioOffset, u8 studio,
|
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 0)
|
||||||
u32 itd);
|
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);
|
bool synthIsFadeOutActive(u8 vGroup);
|
||||||
|
|
||||||
/* TODO: Move this where it belongs */
|
/* TODO: Move this where it belongs */
|
||||||
|
|
|
@ -5,14 +5,14 @@ static NOTE seqNote[256];
|
||||||
SEQ_INSTANCE seqInstance[8];
|
SEQ_INSTANCE seqInstance[8];
|
||||||
u16 seqMIDIPriority[8][16];
|
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 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* seqFreeRoot = NULL;
|
||||||
struct SEQ_INSTANCE* seqActiveRoot = NULL;
|
|
||||||
struct SEQ_INSTANCE* seqPausedRoot = NULL;
|
struct SEQ_INSTANCE* seqPausedRoot = NULL;
|
||||||
|
struct SEQ_INSTANCE* seqActiveRoot = NULL;
|
||||||
|
|
||||||
static void ClearNotes() {
|
static void ClearNotes() {
|
||||||
NOTE* ln = NULL; // r30
|
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].macId = seq->normtab[prg].macro;
|
||||||
seq->prgState[midi].priority = seq->normtab[prg].prio;
|
seq->prgState[midi].priority = seq->normtab[prg].prio;
|
||||||
seq->prgState[midi].maxVoices = seq->normtab[prg].maxVoices;
|
seq->prgState[midi].maxVoices = seq->normtab[prg].maxVoices;
|
||||||
|
#if MUSY_VERSION >= MUSY_VERSION_CHECK(2, 0, 0)
|
||||||
|
seq->prgState[midi].program = prg;
|
||||||
|
#endif
|
||||||
return;
|
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].macId = seq->drumtab[prg].macro;
|
||||||
seq->prgState[midi].priority = seq->drumtab[prg].prio;
|
seq->prgState[midi].priority = seq->drumtab[prg].prio;
|
||||||
seq->prgState[midi].maxVoices = seq->drumtab[prg].maxVoices;
|
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) {
|
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) {
|
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);
|
tickDelta *= section->speed * (1.f / 256.f);
|
||||||
|
|
||||||
section->tickDelta[section->timeIndex].low = fmodf(tickDelta * 65536.f, 65536.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 ((b1 & 0x80) != 0) {
|
||||||
|
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||||
|
*deltaTime = (((u16)b1 & 0x7f) << 8) | b2;
|
||||||
|
#else
|
||||||
*deltaTime = ((b1 & 0x7f) << 8) | b2;
|
*deltaTime = ((b1 & 0x7f) << 8) | b2;
|
||||||
|
#endif
|
||||||
stream += 2;
|
stream += 2;
|
||||||
} else {
|
} else {
|
||||||
*deltaTime = b1;
|
*deltaTime = b1;
|
||||||
|
@ -875,16 +885,26 @@ static u8* GetStreamValue(u8* stream, u16* deltaTime, s16* deltaData) {
|
||||||
b1 = stream[0];
|
b1 = stream[0];
|
||||||
b2 = stream[1];
|
b2 = stream[1];
|
||||||
if ((b1 & 0x80) != 0) {
|
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 = ((b1 & 0x7f) << 8) | b2;
|
||||||
v <<= 1;
|
v <<= 1;
|
||||||
v >>= 1;
|
v >>= 1;
|
||||||
|
#endif
|
||||||
*deltaData = v;
|
*deltaData = v;
|
||||||
stream += 2;
|
stream += 2;
|
||||||
} else {
|
} else {
|
||||||
|
#if MUSY_VERSION >= MUSY_VERSION_CHECK(1, 5, 4)
|
||||||
|
b1 |= (b1 & 0x40) << 1;
|
||||||
|
*deltaData = (s8)b1;
|
||||||
|
#else
|
||||||
v = b1;
|
v = b1;
|
||||||
v <<= 9;
|
v <<= 9;
|
||||||
v >>= 9;
|
v >>= 9;
|
||||||
*deltaData = v;
|
*deltaData = v;
|
||||||
|
#endif
|
||||||
stream += 1;
|
stream += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1062,6 +1082,8 @@ static SEQ_EVENT* GetGlobalEvent(SEQ_SECTION* section) {
|
||||||
return ev;
|
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) {
|
static SEQ_EVENT* HandleEvent(SEQ_EVENT* event, u8 secIndex, u32* loopFlag) {
|
||||||
CPAT* pa; // r26
|
CPAT* pa; // r26
|
||||||
NOTE_DATA* pe; // r24
|
NOTE_DATA* pe; // r24
|
||||||
|
@ -1137,7 +1159,6 @@ static SEQ_EVENT* HandleEvent(SEQ_EVENT* event, u8 secIndex, u32* loopFlag) {
|
||||||
KeyOffNotes();
|
KeyOffNotes();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// case 0x6b:
|
|
||||||
inpSetMidiCtrl(velocity & 0x7f, midi, curSeqId, key & 0x7f);
|
inpSetMidiCtrl(velocity & 0x7f, midi, curSeqId, key & 0x7f);
|
||||||
break;
|
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 ((cseq->trackMute[event->trackId / 32] & (1 << (event->trackId & 0x1f))) != 0) {
|
||||||
if ((macId = cseq->prgState[midi].macId) != 0xffff) {
|
if ((macId = cseq->prgState[midi].macId) != 0xffff) {
|
||||||
key += pa->patternInfo->transpose;
|
key += pa->patternInfo->transpose;
|
||||||
if (key > 0x7f) {
|
key = Clamp(key, 0, 0x7f);
|
||||||
key = 0x7f;
|
|
||||||
} else if (key < 0) {
|
|
||||||
key = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
velocity += pa->patternInfo->velocityAdd;
|
velocity += pa->patternInfo->velocityAdd;
|
||||||
if (velocity > 0x7f) {
|
velocity = Clamp(velocity, 0, 0x7f);
|
||||||
velocity = 0x7f;
|
|
||||||
} else if (velocity < 0) {
|
|
||||||
velocity = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((note = AllocateNote(event->time + pe->length, secIndex)) != NULL) {
|
if ((note = AllocateNote(event->time + pe->length, secIndex)) != NULL) {
|
||||||
if ((note->id = synthStartSound(
|
if ((note->id = synthStartSound(
|
||||||
macId, cseq->prgState[midi].priority, cseq->prgState[midi].maxVoices, key,
|
macId, cseq->prgState[midi].priority, cseq->prgState[midi].maxVoices,
|
||||||
velocity, 64, midi, curSeqId, secIndex, 0, event->trackId,
|
#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,
|
cseq->trackVolGroup[event->trackId], curFadeOutState ? -1 : 0, cseq->defStudio,
|
||||||
synthITDDefault[cseq->defStudio].music)) == SND_ID_ERROR) {
|
synthITDDefault[cseq->defStudio].music)) == SND_ID_ERROR) {
|
||||||
FreeNote(note);
|
FreeNote(note);
|
||||||
|
|
Loading…
Reference in New Issue