up to three melodies will be played by one sequencer instance

This commit is contained in:
2024-03-29 12:41:44 +01:00
parent 97dc6ede70
commit 5a8323bddb
3 changed files with 69 additions and 73 deletions

View File

@ -2,7 +2,8 @@
#include "psg.h" #include "psg.h"
#include "sequencer.h" #include "sequencer.h"
/*
* most simple Tetris from https://de.wikipedia.org/wiki/Korobeiniki
const t_tone notes[] = { const t_tone notes[] = {
{ .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = false, .staccato = false }, { .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = false, .staccato = false },
{ .octave = e_O_3, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false }, { .octave = e_O_3, .note = e_D, .length = e_L_1_8, .legato = false, .staccato = false },
@ -70,8 +71,12 @@ const t_tone notes[] = {
{ .octave = e_O_Null, .note = e_Null, .length = e_L_EndMark, .legato = false, .staccato = false }, { .octave = e_O_Null, .note = e_Null, .length = e_L_EndMark, .legato = false, .staccato = false },
}; };
*/
/*
* drei-stimmiges theme from https://www.gamemusicthemes.com/sheetmusic/gameboy/tetris/themea/Tetris_-_Theme_A_by_Gori_Fater.pdf
*/
const t_tone tetris1[] = { const t_tone tetris1[] = {
// ------- // -------
{ .octave = e_O_5, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false }, { .octave = e_O_5, .note = e_E, .length = e_L_1_4, .legato = false, .staccato = false },
@ -692,38 +697,16 @@ const t_tone tetris3[] = {
{ .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false }, { .octave = e_O_3, .note = e_E, .length = e_L_1_8, .legato = false, .staccato = false },
}; };
t_melody melody = {
.pace = 4,
.amplitude = 3,
.channel = 0,
.tones = notes
};
t_melodies tetrisTheme = {
t_melody melodyTetris1 = { .melodies = { { .amplitude = 3, .tones = tetris1 }, { .amplitude = 3, .tones = tetris2 }, { .amplitude = 3, .tones = tetris3 } },
.pace = 4, .numOfMelodies = 3,
.amplitude = 3, .pace = 4
.channel = 0,
.tones = tetris1
};
t_melody melodyTetris2 = {
.pace = 4,
.amplitude = 3,
.channel = 1,
.tones = tetris2
};
t_melody melodyTetris3 = {
.pace = 4,
.amplitude = 3,
.channel = 1,
.tones = tetris3
}; };
void melodyInit() { void melodyInit() {
sequencerPlayMelody(&melodyTetris1); sequencerPlayMelodies(&tetrisTheme);
sequencerPlayMelody(&melodyTetris2);
sequencerPlayMelody(&melodyTetris3);
} }

View File

@ -1,3 +1,4 @@
#include <sys/param.h>
#include "sequencer.h" #include "sequencer.h"
#include "scheduler.h" #include "scheduler.h"
#include "psg.h" #include "psg.h"
@ -8,18 +9,21 @@ void sequencerInit() {
} }
void sequencerExec(void *handle) { void sequencerExec(void *handle) {
t_melody *melody = (t_melody*) handle; t_melodies *melodies = (t_melodies*) handle;
for (uint8_t channel = 0; channel < MAX(NUM_OF_CHANNELS, melodies->numOfMelodies); channel++) {
t_melody *melody = &(melodies->melodies[channel]);
switch (melody->state) { switch (melody->state) {
case e_Init: case e_Init:
psgAmplitude(melody->channel, melody->amplitude); psgAmplitude(channel, melody->amplitude);
melody->state = e_PlayTone; melody->state = e_PlayTone;
break; break;
case e_PlayTone: case e_PlayTone:
if (melody->tones[melody->idx].length == e_L_EndMark) { if (melody->tones[melody->idx].length == e_L_EndMark) {
melody->idx = 0; melody->idx = 0;
} }
psgPlayTone(melody->channel, melody->tones[melody->idx].octave, melody->tones[melody->idx].note); 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->lengthCnt = (melody->tones[melody->idx].staccato) ? (melody->tones[melody->idx].length / 2) : melody->tones[melody->idx].length;
melody->state = e_HoldTone; melody->state = e_HoldTone;
break; break;
@ -30,7 +34,7 @@ void sequencerExec(void *handle) {
} }
break; break;
case e_StaccatoBreak: case e_StaccatoBreak:
psgPlayTone(melody->channel, e_O_Null, e_Pause); psgPlayTone(channel, e_O_Null, e_Pause);
melody->lengthCnt = melody->tones[melody->idx].length / 2; melody->lengthCnt = melody->tones[melody->idx].length / 2;
melody->state = e_HoldStaccatoBreak; melody->state = e_HoldStaccatoBreak;
break; break;
@ -42,19 +46,22 @@ void sequencerExec(void *handle) {
break; break;
case e_SeparateTone: case e_SeparateTone:
if (! (melody->tones[melody->idx].legato)) { if (! (melody->tones[melody->idx].legato)) {
psgPlayTone(melody->channel, e_O_Null, e_Pause); psgPlayTone(channel, e_O_Null, e_Pause);
} }
melody->idx += 1; melody->idx += 1;
melody->state = e_PlayTone; melody->state = e_PlayTone;
break; break;
} }
} }
}
uint16_t sequencerPlayMelody(t_melody *melody) {
melody->idx = 0; uint16_t sequencerPlayMelodies(t_melodies *melodies) {
melody->lengthCnt = 0; for (uint8_t i = 0; i < NUM_OF_CHANNELS; i++) {
melody->state = e_Init; melodies->melodies[i].idx = 0;
melodies->melodies[i].lengthCnt = 0;
return schAdd(sequencerExec, (void*) melody, 0, melody->pace); melodies->melodies[i].state = e_Init;
}
return schAdd(sequencerExec, (void*) melodies, 0, melodies->pace);
} }

View File

@ -37,14 +37,20 @@ typedef struct {
uint16_t idx; uint16_t idx;
uint8_t lengthCnt; uint8_t lengthCnt;
t_sequencerState state; t_sequencerState state;
uint8_t pace;
uint8_t amplitude; uint8_t amplitude;
uint8_t channel;
const t_tone *tones; const t_tone *tones;
} t_melody; } t_melody;
#define NUM_OF_CHANNELS 3
typedef struct {
uint8_t numOfMelodies;
uint8_t pace;
t_melody melodies[NUM_OF_CHANNELS];
} t_melodies;
void sequencerInit(); void sequencerInit();
uint16_t sequencerPlayMelody(t_melody *melody); uint16_t sequencerPlayMelody(t_melody *melody);
uint16_t sequencerPlayMelodies(t_melodies *melodies);
#endif // _SEQUENCER_H_ #endif // _SEQUENCER_H_