minor changes
This commit is contained in:
parent
918d31692f
commit
553a02cc25
76
src/main.c
76
src/main.c
|
@ -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++;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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
1074
src/midi_parser.c
Normal file
File diff suppressed because it is too large
Load diff
91
src/midi_parser.h
Normal file
91
src/midi_parser.h
Normal 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
|
Loading…
Reference in a new issue