initial commit
This commit is contained in:
commit
ae75b01938
23
Makefile
Normal file
23
Makefile
Normal file
|
@ -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
|
143
src/main.c
Normal file
143
src/main.c
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
#include <linux/soundcard.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdatomic.h>
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue