added commandline parsing

This commit is contained in:
Lauchmelder 2022-04-17 18:31:19 +02:00
parent 6244999b08
commit ae5c0cd3ec
3 changed files with 76 additions and 12 deletions

View file

@ -1,33 +1,34 @@
#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 <string.h>
#include <stdatomic.h>
#include <sys/time.h>
#include "midi_interface.h"
#include "midi_parser.h"
typedef struct
{
const char* midi_file;
const char* mapping_file;
} CommandArguments;
MidiInterface* interface;
static int _Atomic playing = ATOMIC_VAR_INIT(0);
static uint32_t _Atomic time_per_quarter = ATOMIC_VAR_INIT(1);
static uint32_t _Atomic current_tick = ATOMIC_VAR_INIT(0);
CommandArguments parse_command_args(int argc, char** argv);
void* play_track(void* data);
void* advance_counter(void* data);
int main(int argc, char** argv)
{
if(argc != 2)
{
fprintf(stderr, "Usage: musicalpi <midi file>");
exit(-1);
}
CommandArguments args = parse_command_args(argc, argv);
printf("Loading MIDI file...\n");
MidiParser* parser;
@ -106,7 +107,12 @@ void* play_track(void* data)
{
time_per_quarter = ((uint32_t*)(event.infos))[0];
}
else if(event.type == MidiNotePressed || event.type == MidiNoteReleased || event.type == MidiControllerValueChanged)
else if(
event.type == MidiNotePressed ||
event.type == MidiNoteReleased ||
event.type == MidiControllerValueChanged ||
event.type == MidiProgramChanged
)
{
message->channel = (((uint8_t*)(event.infos))[0] & 0xF);
message->data = event.infos + 1;
@ -124,6 +130,13 @@ void* play_track(void* data)
case MidiControllerValueChanged:
message->type = CONTROLLER_CHANGE;
break;
case MidiProgramChanged:
message->type = PROGRAM_CHANGE;
break;
default:
break;
}
// printf("Sending %d %d\n", message->data[0], message->data[1]);
int result = write_midi_device(interface, message);
@ -134,4 +147,47 @@ void* play_track(void* data)
current_event++;
tick_of_last_event += event.timeToAppear;
}
return NULL;
}
CommandArguments parse_command_args(int argc, char** argv)
{
CommandArguments parsed_args;
parsed_args.midi_file = NULL;
parsed_args.mapping_file = NULL;
int opt;
while ((opt = getopt(argc, argv, "hm:")) != -1)
{
switch(opt)
{
case 'm':
{
size_t len = strlen(optarg);
parsed_args.mapping_file = (const char*)malloc(len);
memcpy((void*)parsed_args.mapping_file, (void*)optarg, len);
} break;
case 'h':
fprintf(stderr, "Usage: %s [-m mapping_file] midi_file\n", argv[0]);
exit(EXIT_SUCCESS);
}
}
if(optind < argc)
{
size_t len = strlen(argv[optind]);
parsed_args.midi_file = (const char*)malloc(len);
memcpy((void*)parsed_args.midi_file, (void*)argv[optind], len);
}
if(parsed_args.midi_file == NULL)
{
fprintf(stderr, "A MIDI file is required\n");
exit(EXIT_FAILURE);
}
return parsed_args;
}

View file

@ -23,6 +23,7 @@ int data_length(MessageType type)
case NOTE_ON: return 2;
case NOTE_OFF: return 2;
case CONTROLLER_CHANGE: return 2;
case PROGRAM_CHANGE: return 1;
case SYSTEM_EXCLUSIVE: return 0;
}
@ -48,6 +49,10 @@ int decode_status_byte(Message* message, uint8_t status)
message->type = CONTROLLER_CHANGE;
break;
case 0xC0:
message->type = PROGRAM_CHANGE;
break;
case 0xF0:
message->type = SYSTEM_EXCLUSIVE;
break;
@ -78,6 +83,10 @@ int encode_status_byte(const Message* message, uint8_t* status)
*status |= 0xB0;
break;
case PROGRAM_CHANGE:
*status |= 0xC0;
break;
case SYSTEM_EXCLUSIVE:
*status |= 0xF0;
break;

View file

@ -5,8 +5,7 @@
typedef enum MessageType
{
NOTE_OFF, NOTE_ON, CONTROLLER_CHANGE,
SYSTEM_EXCLUSIVE
NOTE_OFF, NOTE_ON, CONTROLLER_CHANGE, PROGRAM_CHANGE, SYSTEM_EXCLUSIVE
} MessageType;
typedef struct Message