commit ae75b019380c9682ae68d7583f5472c9ef428934 Author: Lauchmelder Date: Fri Apr 8 19:16:55 2022 +0200 initial commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ab3e48b --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +CC := gcc +CFLAGS := -Wall -g +LIBRARIES := -lpthread +TARGET := musicalpi + +SRCS := $(wildcard src/*.c) +OBJS := $(patsubst src/%.c, out/%.o, $(SRCS)) + +ALL: $(TARGET) + +$(TARGET): mkdir $(OBJS) + $(CC) -o out/$@ $(filter-out $<, $^) $(LIBRARIES) + +mkdir: + mkdir -p out + +out/%.o: src/%.c + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + rm -rf $(TARGET) out + +.PHONY: all clean diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..8730e37 --- /dev/null +++ b/src/main.c @@ -0,0 +1,143 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char* devices[] = {"/dev/midi", "/dev/midi2", NULL}; + +typedef struct Note +{ + unsigned char channel; + unsigned char pitch; + unsigned char velocity; +} Note; + +typedef struct Offset +{ + signed char pitch; + signed char velocity +} Offset; + +static const Offset pattern[] = { + { 0, 0 }, + { -5, -11 }, + { -9, -11 }, + { -12, -11 }, + { -9, -11 }, + { -5, -11 }, + { -1, 0 }, + { -5, -11 }, + { -9, -11 }, + { -12, -11 }, + { -9, -11 }, + { -5, -11 }, + { -2, 0 }, + { -5, -11 }, + { -9, -11 }, + { -12, -11 }, + { -9, -11 }, + { -5, -11 }, + { -3, 0 }, + { -5, -11 }, + { -9, -11 }, + { -12, -11 }, + { -9, -11 }, + { -5, -11 } +}; + +static int _Atomic stop = ATOMIC_VAR_INIT(0); +static int _Atomic step = ATOMIC_VAR_INIT(0); +static Note* _Atomic note = ATOMIC_VAR_INIT(NULL); + +void *arpeggio_loop(void* data); + +int main(int argc, char** argv) +{ + unsigned char data[3] = {0, 0, 0}; + int key_down = 0; + Note current_note; + + const char* device; + int fd; + int i = 0; + while((device = devices[i++]) != NULL) + { + printf("Trying %s...", device); + + fd = open(device, O_RDWR, 0); + if(fd < 0) + { + printf("Failed: %s\n", strerror(errno)); + } + else + { + printf("Success!\n"); + break; + } + } + + if(fd < 0) + { + fprintf(stderr, "No MIDI devices detected.\n"); + return -1; + } + + printf("Using MIDI device %s\n", device); + pthread_t arpeggio_thread; + pthread_create(&arpeggio_thread, NULL, arpeggio_loop, (void*)fd); + + for(;;) + { + read(fd, (void*)data, sizeof(data)); + + if(data[0] != 0xfd) + { + if(data[2] > 0) + { + key_down = 1; + note = ¤t_note; + + current_note.channel = 0x90; + current_note.pitch = data[1]; + current_note.velocity = data[2]; + } + else if(data[1] == current_note.pitch) + { + key_down = 0; + note = NULL; + step = 0; + } + } + } + + pthread_join(arpeggio_thread, NULL); + close(fd); + return 0; +} + +void *arpeggio_loop(void* data) +{ + int fd = (int)data; + + while(stop == 0) + { + if(note != NULL) + { + Note out = *note; + out.pitch += pattern[step].pitch; + out.velocity += pattern[step].velocity; + write(fd, &out, sizeof(Note)); + + step++; + if(step >= (sizeof(pattern) / sizeof(Offset))) + step = 0; + + usleep(166666); + } + } +} \ No newline at end of file