legato
This commit is contained in:
parent
73d2bbc730
commit
9989a52c38
@ -1,84 +1,97 @@
|
||||
#include <stdbool.h>
|
||||
#include "psg.h"
|
||||
#include "sequencer.h"
|
||||
|
||||
|
||||
const t_tone notes[] = {
|
||||
{ .octave = e_O_2, .note = e_G, .length = e_L_1_2 },
|
||||
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4 },
|
||||
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4 },
|
||||
{ .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_D, .length = e_L_1_8, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
|
||||
|
||||
{ .octave = e_O_2, .note = e_F, .length = e_L_1_2 },
|
||||
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4 },
|
||||
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4},
|
||||
{ .octave = e_O_3, .note = e_F, .length = e_L_1_4, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_D, .length = e_L_1_8, .legato = false },
|
||||
|
||||
{ .octave = e_O_2, .note = e_C, .length = e_L_1_2},
|
||||
{ .octave = e_O_2, .note = e_C, .length = e_L_1_4},
|
||||
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4},
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_4, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_8, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
|
||||
|
||||
{ .octave = e_O_2, .note = e_G, .length = e_L_1_2},
|
||||
{ .octave = e_O_2, .note = e_F, .length = e_L_1_4},
|
||||
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4},
|
||||
{ .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_F, .length = e_L_1_8, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
|
||||
|
||||
{ .octave = e_O_2, .note = e_D, .length = e_L_1_2},
|
||||
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4},
|
||||
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4},
|
||||
{ .octave = e_O_3, .note = e_D, .length = e_L_1_4, .legato = true },
|
||||
{ .octave = e_O_3, .note = e_D, .length = e_L_1_8, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
|
||||
|
||||
{ .octave = e_O_2, .note = e_F, .length = e_L_1_2},
|
||||
{ .octave = e_O_2, .note = e_G, .length = e_L_1_2},
|
||||
{ .octave = e_O_3, .note = e_F, .length = e_L_1_4, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = false },
|
||||
|
||||
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_2},
|
||||
{ .octave = e_O_2, .note = e_C, .length = e_L_1_2},
|
||||
{ .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = true },
|
||||
{ .octave = e_O_3, .note = e_Dis, .length = e_L_1_16, .legato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_16, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_8, .legato = true },
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_16, .legato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_16, .legato = false },
|
||||
|
||||
{ .octave = e_O_2, .note = e_C, .length = e_L_1_2},
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_4, .legato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false },
|
||||
|
||||
{ .octave = e_O_2, .note = e_F, .length = e_L_1_4},
|
||||
{ .octave = e_O_2, .note = e_F, .length = e_L_1_4},
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_4},
|
||||
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_2},
|
||||
{ .octave = e_O_2, .note = e_Ais, .length = e_L_1_4},
|
||||
{ .octave = e_O_2, .note = e_Gis, .length = e_L_1_4},
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_8, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_F, .length = e_L_1_8, .legato = true },
|
||||
{ .octave = e_O_3, .note = e_F, .length = e_L_1_8, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_8, .legato = false },
|
||||
|
||||
{ .octave = e_O_2, .note = e_G, .length = e_L_1_2},
|
||||
{ .octave = e_O_2, .note = e_G, .length = e_L_1_4},
|
||||
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4},
|
||||
{ .octave = e_O_4, .note = e_C, .length = e_L_1_4, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_Ais, .length = e_L_1_8, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_Gis, .length = e_L_1_8, .legato = false },
|
||||
|
||||
{ .octave = e_O_2, .note = e_G, .length = e_L_1_2},
|
||||
{ .octave = e_O_2, .note = e_F, .length = e_L_1_4},
|
||||
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4},
|
||||
{ .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = true },
|
||||
{ .octave = e_O_3, .note = e_G, .length = e_L_1_8, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
|
||||
|
||||
{ .octave = e_O_2, .note = e_D, .length = e_L_1_2},
|
||||
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4},
|
||||
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_4},
|
||||
{ .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_F, .length = e_L_1_8, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
|
||||
|
||||
{ .octave = e_O_2, .note = e_F, .length = e_L_1_2},
|
||||
{ .octave = e_O_2, .note = e_G, .length = e_L_1_2},
|
||||
{ .octave = e_O_3, .note = e_D, .length = e_L_1_4, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_D, .length = e_L_1_8, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = false },
|
||||
|
||||
{ .octave = e_O_2, .note = e_Dis, .length = e_L_1_2},
|
||||
{ .octave = e_O_2, .note = e_C, .length = e_L_1_2},
|
||||
{ .octave = e_O_3, .note = e_F, .length = e_L_1_4, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_G, .length = e_L_1_4, .legato = false },
|
||||
|
||||
{ .octave = e_O_2, .note = e_C, .length = e_L_1_2},
|
||||
{ .octave = e_O_3, .note = e_Dis, .length = e_L_1_8, .legato = true },
|
||||
{ .octave = e_O_3, .note = e_Dis, .length = e_L_1_16, .legato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_16, .legato = false },
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_8, .legato = true },
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_16, .legato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_16, .legato = false },
|
||||
|
||||
{ .octave = e_O_2, .note = e_C, .length = e_L_EndMark },
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_4, .legato = false },
|
||||
{ .octave = e_O_Null, .note = e_Pause, .length = e_L_1_4, .legato = false },
|
||||
|
||||
{ .octave = e_O_Null, .note = e_Null, .length = e_L_EndMark, .legato = false },
|
||||
};
|
||||
|
||||
/*
|
||||
const t_tone ladder[16] = {
|
||||
{ .octave = e_O_2, .note = e_C, .length = e_L_1_4 },
|
||||
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4 },
|
||||
{ .octave = e_O_2, .note = e_E, .length = e_L_1_4 },
|
||||
{ .octave = e_O_2, .note = e_F, .length = e_L_1_4 },
|
||||
{ .octave = e_O_2, .note = e_G, .length = e_L_1_4 },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_4 },
|
||||
{ .octave = e_O_2, .note = e_H, .length = e_L_1_4 },
|
||||
{ .octave = e_O_3, .note = e_C, .length = e_L_1_4 },
|
||||
{ .octave = e_O_2, .note = e_H, .length = e_L_1_4 },
|
||||
{ .octave = e_O_2, .note = e_A, .length = e_L_1_4 },
|
||||
{ .octave = e_O_2, .note = e_G, .length = e_L_1_4 },
|
||||
{ .octave = e_O_2, .note = e_F, .length = e_L_1_4 },
|
||||
{ .octave = e_O_2, .note = e_E, .length = e_L_1_4 },
|
||||
{ .octave = e_O_2, .note = e_D, .length = e_L_1_4 },
|
||||
{ .octave = e_O_2, .note = e_H, .length = e_L_EndMark },
|
||||
{ .octave = e_O_3, .note = e_D, .length = e_L_1_4 },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_4 },
|
||||
{ .octave = e_O_3, .note = e_F, .length = e_L_1_4 },
|
||||
{ .octave = e_O_3, .note = e_G, .length = e_L_1_4 },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_4 },
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_4 },
|
||||
{ .octave = e_O_4, .note = e_C, .length = e_L_1_4 },
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_1_4 },
|
||||
{ .octave = e_O_3, .note = e_A, .length = e_L_1_4 },
|
||||
{ .octave = e_O_3, .note = e_G, .length = e_L_1_4 },
|
||||
{ .octave = e_O_3, .note = e_F, .length = e_L_1_4 },
|
||||
{ .octave = e_O_3, .note = e_E, .length = e_L_1_4 },
|
||||
{ .octave = e_O_3, .note = e_D, .length = e_L_1_4 },
|
||||
{ .octave = e_O_3, .note = e_H, .length = e_L_EndMark },
|
||||
};
|
||||
*/
|
||||
|
||||
|
@ -39,6 +39,8 @@ const uint16_t frequencyCodes[8][12] = {
|
||||
#define R14 014
|
||||
#define R15 015
|
||||
|
||||
uint8_t psgShadowRegisters[14];
|
||||
|
||||
inline static void BUS_OP_NACT() {
|
||||
BUS_CTRL_REG &= ~(BDIR | BC1);
|
||||
}
|
||||
@ -61,7 +63,13 @@ asm volatile (
|
||||
);
|
||||
}
|
||||
|
||||
uint8_t psgReadShadow(uint8_t address) {
|
||||
return psgShadowRegisters[address];
|
||||
}
|
||||
|
||||
void psgWrite(uint8_t address, uint8_t data) {
|
||||
psgShadowRegisters[address] = data;
|
||||
|
||||
// according to "State Timing" (p. 15) of datasheet
|
||||
|
||||
// put bus into inactive state
|
||||
@ -92,7 +100,12 @@ void psgWriteFrequency(uint8_t channel, uint16_t frequencyCode) {
|
||||
}
|
||||
|
||||
void psgPlayTone(uint8_t channel, t_octave octave, t_note note) {
|
||||
psgWriteFrequency(channel, frequencyCodes[octave][note]);
|
||||
if (note == e_Pause) {
|
||||
psgWrite(R7, psgReadShadow(R7) | (1 << channel));
|
||||
} else {
|
||||
psgWrite(R7, psgReadShadow(R7) & ~(1 << channel));
|
||||
psgWriteFrequency(channel, frequencyCodes[octave][note]);
|
||||
}
|
||||
}
|
||||
|
||||
void playSomething(void *handle) {
|
||||
|
@ -11,7 +11,8 @@ typedef enum {
|
||||
e_O_5,
|
||||
e_O_6,
|
||||
e_O_7,
|
||||
e_O_8
|
||||
e_O_8,
|
||||
e_O_Null
|
||||
} t_octave;
|
||||
|
||||
typedef enum {
|
||||
@ -26,7 +27,9 @@ typedef enum {
|
||||
e_Gis,
|
||||
e_A,
|
||||
e_Ais,
|
||||
e_H
|
||||
e_H,
|
||||
e_Pause,
|
||||
e_Null
|
||||
} t_note;
|
||||
|
||||
|
||||
@ -34,5 +37,6 @@ void psgInit();
|
||||
void psgPlayTone(uint8_t channel, t_octave octave, t_note note);
|
||||
void psgWriteFrequency(uint8_t channel, uint16_t frequencyCode);
|
||||
void psgWrite(uint8_t address, uint8_t data);
|
||||
uint8_t psgReadShadow(uint8_t address);
|
||||
|
||||
#endif // _PSG_H_
|
||||
|
@ -9,24 +9,38 @@ void sequencerInit() {
|
||||
void sequencerExec(void *handle) {
|
||||
t_melody *melody = (t_melody*) handle;
|
||||
|
||||
if (melody->lengthCnt == 0) {
|
||||
if (melody->tones[melody->idx].length == e_L_EndMark) {
|
||||
melody->idx = 0;
|
||||
}
|
||||
switch (melody->state) {
|
||||
case 0:
|
||||
if (melody->tones[melody->idx].length == e_L_EndMark) {
|
||||
melody->idx = 0;
|
||||
}
|
||||
|
||||
psgPlayTone(melody->channel, melody->tones[melody->idx].octave, melody->tones[melody->idx].note);
|
||||
psgPlayTone(melody->channel, melody->tones[melody->idx].octave, melody->tones[melody->idx].note);
|
||||
|
||||
melody->lengthCnt = melody->tones[melody->idx].length;
|
||||
melody->idx += 1;
|
||||
melody->lengthCnt = melody->tones[melody->idx].length;
|
||||
melody->state = 1;
|
||||
break;
|
||||
case 1:
|
||||
melody->lengthCnt -= 1;
|
||||
if (melody->lengthCnt == 0) {
|
||||
melody->state = 2;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (! (melody->tones[melody->idx].legato)) {
|
||||
psgPlayTone(melody->channel, e_O_Null, e_Pause);
|
||||
}
|
||||
melody->idx += 1;
|
||||
melody->state = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
melody->lengthCnt -= 1;
|
||||
}
|
||||
|
||||
uint8_t sequencerPlayMelody(t_melody *melody) {
|
||||
melody->idx = 0;
|
||||
melody->lengthCnt = 0;
|
||||
schAdd(sequencerExec, (void*) melody, 0, 25);
|
||||
melody->state = 0;
|
||||
schAdd(sequencerExec, (void*) melody, 0, 10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "psg.h"
|
||||
|
||||
typedef enum {
|
||||
@ -18,11 +19,13 @@ typedef struct {
|
||||
t_octave octave;
|
||||
t_note note;
|
||||
t_noteLength length;
|
||||
bool legato;
|
||||
} t_tone;
|
||||
|
||||
typedef struct {
|
||||
uint16_t idx;
|
||||
uint8_t lengthCnt;
|
||||
uint8_t state;
|
||||
uint8_t channel;
|
||||
const t_tone *tones;
|
||||
} t_melody;
|
||||
|
Loading…
x
Reference in New Issue
Block a user