sound-experiment-01/sequencer.c

116 lines
2.4 KiB
C
Raw Normal View History

2024-06-06 17:05:17 +02:00
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "scheduler.h"
#include "sequencer.h"
#include "psg.h"
const uint32_t CYCLE_TIME = 5; // ms
typedef enum {
ACTION_RESULT_STAY,
ACTION_RESULT_NEXT,
ACTION_RESULT_REPEAT,
ACTION_RESULT_END
} actionResult_t;
2024-06-11 21:24:54 +02:00
uint16_t taskId;
2024-06-06 17:05:17 +02:00
static actionResult_t _wait(uint32_t wait) {
static bool running = false;
static uint32_t counter = 0;
actionResult_t res;
if (! running) {
2024-06-11 21:24:54 +02:00
running = true;
2024-06-06 17:05:17 +02:00
counter = wait;
res = ACTION_RESULT_STAY;
} else {
if (counter == 0) {
running = false;
res = ACTION_RESULT_NEXT;
} else {
counter -= 1;
res = ACTION_RESULT_STAY;
}
}
return res;
}
static actionResult_t _change_sound(uint16_t frequency_a, uint8_t volume_a, uint16_t frequency_b, uint8_t volume_b) {
// set frequency_a and volume_a to generator 0
2024-06-11 21:24:54 +02:00
psgPlayFrequency(0, 0, volume_a, frequency_a);
2024-06-06 17:05:17 +02:00
// set frequency_b and volume_b to generator 1
2024-06-11 21:24:54 +02:00
psgPlayFrequency(1, 0, volume_b, frequency_b);
2024-06-06 17:05:17 +02:00
return ACTION_RESULT_NEXT;
}
static bool _change_volume(uint8_t volume_a, uint8_t volume_b) {
// set volume_a to generator 0
2024-06-11 21:24:54 +02:00
psgAmplitude(0, 0, volume_a);
2024-06-06 17:05:17 +02:00
// set volume_b to generator 1
2024-06-11 21:24:54 +02:00
psgAmplitude(1, 0, volume_b);
2024-06-06 17:05:17 +02:00
return ACTION_RESULT_NEXT;
}
2024-06-11 21:24:54 +02:00
void sequencerExec(void *handle) {
sequencerAction_t *seq = (sequencerAction_t*) handle;
static uint16_t seqIdx = 0;
sequencerAction_t *action = seq + seqIdx;
actionResult_t res;
switch (action->type) {
case SA_WAIT:
res = _wait(action->u.wait);
break;
case SA_REPEAT:
res = ACTION_RESULT_REPEAT;
break;
case SA_END:
res = ACTION_RESULT_END;
break;
case SA_CHANGE_SOUND:
res = _change_sound(
action->u.cs.frequency_a,
action->u.cs.volume_a,
action->u.cs.frequency_b,
action->u.cs.volume_b);
break;
case SA_CHANGE_VOLUME:
res = _change_volume(
action->u.cs.volume_a,
action->u.cs.volume_b);
break;
default:
break;
}
switch (res) {
case ACTION_RESULT_NEXT:
seqIdx += 1;
break;
case ACTION_RESULT_REPEAT:
seqIdx = 0;
break;
case ACTION_RESULT_STAY:
break;
case ACTION_RESULT_END:
schDel(taskId);
break;
}
2024-06-06 17:05:17 +02:00
}
2024-06-11 21:24:54 +02:00
void sequencerStart(const sequencerAction_t *sequence) {
taskId = schAdd(sequencerExec, (void*) sequence, 0, CYCLE_TIME);
2024-06-06 17:05:17 +02:00
}
void sequencerInit() {
}
2024-06-11 21:24:54 +02:00