Files
tetris/sound-driver/sequencer.c
2024-03-29 13:29:53 +01:00

82 lines
2.4 KiB
C

#include <sys/param.h>
#include "sequencer.h"
#include "scheduler.h"
#include "psg.h"
void sequencerInit() {
}
void sequencerExec(void *handle) {
t_melodies *melodies = (t_melodies*) handle;
for (uint8_t channel = 0; channel < melodies->numOfMelodies; channel++) {
t_melody *melody = &(melodies->melodies[channel]);
switch (melody->state) {
case e_Init:
psgAmplitude(channel, melody->amplitude);
melody->state = e_PlayTone;
break;
case e_PlayTone:
if (melody->tones[melody->idx].length == e_L_SyncMark) {
if (melodies->sync == 0) {
melodies->sync = melodies->numOfMelodies;
}
melodies->sync -= 1;
melody->state = e_Sync;
} else {
if (melody->tones[melody->idx].length == e_L_EndMark) {
melody->idx = 0;
}
psgPlayTone(channel, melody->tones[melody->idx].octave, melody->tones[melody->idx].note);
melody->lengthCnt = (melody->tones[melody->idx].staccato) ? (melody->tones[melody->idx].length / 2) : melody->tones[melody->idx].length;
melody->state = e_HoldTone;
}
break;
case e_Sync:
if (melodies->sync == 0) {
melody->state = e_SeparateTone;
}
break;
case e_HoldTone:
melody->lengthCnt -= 1;
if (melody->lengthCnt == 0) {
melody->state = (melody->tones[melody->idx].staccato) ? e_StaccatoBreak : e_SeparateTone;
}
break;
case e_StaccatoBreak:
psgPlayTone(channel, e_O_Null, e_Pause);
melody->lengthCnt = melody->tones[melody->idx].length / 2;
melody->state = e_HoldStaccatoBreak;
break;
case e_HoldStaccatoBreak:
melody->lengthCnt -= 1;
if (melody->lengthCnt == 0) {
melody->state = e_SeparateTone;
}
break;
case e_SeparateTone:
if (! (melody->tones[melody->idx].legato)) {
psgPlayTone(channel, e_O_Null, e_Pause);
}
melody->idx += 1;
melody->state = e_PlayTone;
break;
}
}
}
uint16_t sequencerPlayMelodies(t_melodies *melodies) {
for (uint8_t i = 0; i < NUM_OF_CHANNELS; i++) {
melodies->melodies[i].idx = 0;
melodies->melodies[i].lengthCnt = 0;
melodies->melodies[i].state = e_Init;
}
melodies->sync = 0;
return schAdd(sequencerExec, (void*) melodies, 0, melodies->pace);
}