minor changes

This commit is contained in:
Lauchmelder 2022-04-09 19:08:28 +02:00
parent 918d31692f
commit 553a02cc25
5 changed files with 1239 additions and 8 deletions

View file

@ -9,13 +9,11 @@
#include <stdatomic.h>
#include "midi_interface.h"
#include "midi_parser.h"
typedef struct Note
{
unsigned char channel;
unsigned char pitch;
unsigned char velocity;
} Note;
uint32_t time_per_quarter;
uint32_t ticks_per_quarter;
MidiInterface* interface;
typedef struct Offset
{
@ -53,16 +51,37 @@ static const Offset pattern[] = {
static int _Atomic stop = ATOMIC_VAR_INIT(0);
static int _Atomic step = ATOMIC_VAR_INIT(0);
static Note* _Atomic note = ATOMIC_VAR_INIT(NULL);
static int _Atomic playing = ATOMIC_VAR_INIT(0);
void *arpeggio_loop(void* data);
void* arpeggio_loop(void* data);
void* play_track(void* data);
int main(int argc, char** argv)
{
MidiInterface* interface;
MidiParser* parser;
parser = parseMidi("out/pushing_onwards.mid", false, true);
if(!parser)
{
fprintf(stderr, "Failed to read MIDI file\n");
exit(-1);
}
time_per_quarter = ((uint32_t*)(parser->tracks[0].events[2].infos))[0];
ticks_per_quarter = parser->ticks;
int result = open_midi_device(&interface, NULL);
if(result < 0)
exit(result);
pthread_t* threads = (pthread_t*)malloc(parser->nbOfTracks * sizeof(pthread_t));
for(int i = 0; i < parser->nbOfTracks; i++)
{
pthread_create(threads + i, NULL, play_track, parser->tracks + i);
}
playing = 1;
/*
int key_down = 0;
Note current_note;
@ -107,7 +126,15 @@ int main(int argc, char** argv)
pthread_join(arpeggio_thread, NULL);
free_message(message);
*/
for(int i = 0; i < parser->nbOfTracks; i++)
{
pthread_join(threads[i], NULL);
}
free(threads);
close_midi_device(interface);
return 0;
}
@ -140,4 +167,37 @@ void *arpeggio_loop(void* data)
}
free_message(message);
}
void* play_track(void* data)
{
Track* track = (Track*)data;
Message* message;
create_message(&message);
message->channel = 0;
message->length = 2;
int current_event = 0;
while(current_event < track->nbOfEvents)
{
if(!playing)
continue;
Event event = track->events[current_event];
usleep(event.timeToAppear * time_per_quarter / ticks_per_quarter);
if(event.type == MidiNotePressed || event.type == MidiNoteReleased)
{
message->type = (event.type == MidiNotePressed) ? NOTE_ON : NOTE_OFF;
message->data = event.infos + 1;
// printf("Sending %d %d\n", message->data[0], message->data[1]);
int result = write_midi_device(interface, message);
if(result < 0)
fprintf(stderr, "Write err: %s\n", midi_strerror(result));
}
current_event++;
}
}

View file

@ -94,6 +94,11 @@ int write_midi_device(MidiInterface* interface, const Message* buffer)
return MIDI_WRITE_ERROR;
}
int write_midi_device_raw(MidiInterface* interface, const char* buffer)
{
//
}
int try_open_device(const char* device)
{
int fd = open(device, O_RDWR, 0);

View file

@ -17,6 +17,7 @@ int close_midi_device(MidiInterface* interface);
int read_midi_device(MidiInterface* interface, Message* buffer);
int write_midi_device(MidiInterface* interface, const Message* buffer);
int write_midi_device_raw(MidiInterface* interface, const char* buffer);
#endif

1074
src/midi_parser.c Normal file

File diff suppressed because it is too large Load diff

91
src/midi_parser.h Normal file
View file

@ -0,0 +1,91 @@
/**
* https://github.com/Gegel85/midi_parser
*/
#ifndef __LIB_MIDI_PARSER_HEADER_
#define __LIB_MIDI_PARSER_HEADER_
#include <stdbool.h>
typedef enum {
MidiSequenceNumber,
MidiTextEvent,
MidiNewLyric,
MidiNewMarker,
MidiNewCuePoint,
MidiNewChannelPrefix,
MidiPortChange,
MidiTempoChanged,
MidiSMTPEOffset,
MidiNewTimeSignature,
MidiNewKeySignature,
MidiSequencerSpecificEvent,
MidiNoteReleased,
MidiNotePressed,
MidiPolyphonicPressure,
MidiControllerValueChanged,
MidiProgramChanged,
MidiPressureOfChannelChanged,
MidiPitchBendChanged,
} EventType;
typedef struct {
EventType type;
int timeToAppear;
void *infos;
} Event;
typedef struct {
unsigned char numerator;
unsigned char denominator;
unsigned char clockTicksPerMetTick;
unsigned char ticksPerQuarterNote;
} MidiTimeSignature;
typedef struct {
unsigned char channel;
unsigned char pitch;
unsigned char velocity;
} MidiNote;
typedef struct Note {
unsigned char pitch;
unsigned char channel;
unsigned char velocity;
unsigned char fadeOutVelocity;
unsigned long int timeBeforeAppear;
unsigned long int duration;
} Note;
typedef struct {
char *copyright;
char *name;
char *instrumentName;
int nbOfEvents;
int nbOfNotes;
Note *notes;
Event *events;
} Track;
typedef struct NoteList {
Note *note;
struct NoteList *next;
struct NoteList *prev;
} NoteList;
typedef struct {
unsigned short format;
short nbOfTracks;
char fps;
short ticks;
int nbOfNotes;
Track *tracks;
} MidiParser;
bool parseMidiTrack(unsigned char *buffer, int buffLen, Track *track, bool outputDebug, MidiParser *result, int posInFile, bool createNoteArray);
MidiParser *parseMidi(char *path, bool outputDebug, bool createNoteArray);
char *getNoteString(char note);
void deleteTrack(Track *track);
void deleteMidiParserStruct(MidiParser *result);
#endif