added instrument mapping

This commit is contained in:
Lauchmelder 2022-04-17 20:18:20 +02:00
parent ae5c0cd3ec
commit 20a8edc67a
4 changed files with 97 additions and 9 deletions

View file

@ -8,14 +8,16 @@
#include "midi_interface.h"
#include "midi_parser.h"
#include "mapping.h"
typedef struct
{
const char* midi_file;
const char* mapping_file;
char* midi_file;
char* mapping_file;
} CommandArguments;
MidiInterface* interface;
uint8_t* map;
static int _Atomic playing = ATOMIC_VAR_INIT(0);
static uint32_t _Atomic time_per_quarter = ATOMIC_VAR_INIT(1);
@ -30,9 +32,14 @@ int main(int argc, char** argv)
{
CommandArguments args = parse_command_args(argc, argv);
if(args.mapping_file)
map = load_program_map(args.mapping_file);
else
map = get_default_map();
printf("Loading MIDI file...\n");
MidiParser* parser;
parser = parseMidi(argv[1], false, true);
parser = parseMidi(args.midi_file, false, true);
if(!parser)
{
fprintf(stderr, "Failed to read MIDI file\n");
@ -63,7 +70,8 @@ int main(int argc, char** argv)
}
free(threads);
close_midi_device(interface);
free(map);
return 0;
}
@ -133,12 +141,15 @@ void* play_track(void* data)
case MidiProgramChanged:
message->type = PROGRAM_CHANGE;
// printf("ch %u mapped %u to %u\n", message->channel, message->data[0], map[message->data[0]]);
message->data[0] = map[message->data[0]];
break;
default:
break;
}
// printf("Sending %d %d\n", message->data[0], message->data[1]);
// printf("ch %u\n", message->channel);
int result = write_midi_device(interface, message);
if(result < 0)
fprintf(stderr, "Write err: %s\n", midi_strerror(result));
@ -166,21 +177,26 @@ CommandArguments parse_command_args(int argc, char** argv)
case 'm':
{
size_t len = strlen(optarg);
parsed_args.mapping_file = (const char*)malloc(len);
parsed_args.mapping_file = (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);
default:
exit(EXIT_FAILURE);
break;
}
}
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);
parsed_args.midi_file = (char*)malloc(len + 1);
strcpy(parsed_args.midi_file, argv[optind]);
}
if(parsed_args.midi_file == NULL)

63
src/mapping.c Normal file
View file

@ -0,0 +1,63 @@
#include "mapping.h"
#include <stdio.h>
#include <stdlib.h>
uint8_t* load_program_map(const char* filename)
{
FILE* fp = fopen(filename, "r");
if(fp == NULL)
{
fprintf(stderr, "Failed to open mapping file %s\n", filename);
exit(EXIT_FAILURE);
}
uint8_t* map = (uint8_t*)calloc(1, 127);
size_t read;
size_t current_line = 0;
size_t len = 0;
char* line = NULL;
while((read = getline(&line, &len, fp)) != -1)
{
current_line++;
if(read == 1)
continue;
size_t colon_pos = 0;
do
{
if(line[colon_pos] == '\0')
{
fprintf(stderr, "Invalid syntax in mapping file at line %u. Ignoring.\n", current_line);
continue;
}
} while(line[++colon_pos] != ':');
line[colon_pos] = '\0';
int from = atoi(line);
int to = atoi(line + colon_pos + 1);
if(from < 0 || 127 < from)
{
fprintf(stderr, "Invalid MIDI program ID in line %u. Ignoring\n", current_line);
continue;
}
map[from & 0xFF] = to & 0xFF;
}
fclose(fp);
return map;
}
uint8_t* get_default_map()
{
uint8_t* map = (uint8_t*)malloc(127);
for(int i = 1; i < 128; i++)
{
map[i] = i;
}
return map;
}

9
src/mapping.h Normal file
View file

@ -0,0 +1,9 @@
#ifndef _MAPPING_H_
#define _MAPPING_H_
#include <stdint.h>
uint8_t* load_program_map(const char* filename);
uint8_t* get_default_map();
#endif

View file

@ -94,6 +94,6 @@ int encode_status_byte(const Message* message, uint8_t* status)
default:
return MIDI_UNKNOWN_STATUS_BYTE;
}
return 0;
}