Просмотр исходного кода

Initial commit

Add files with test program.
master
TheoryOfNekomata 1 год назад
Сommit
dc3396c806
7 измененных файлов: 190 добавлений и 0 удалений
  1. +2
    -0
      .gitattributes
  2. +8
    -0
      .gitignore
  3. +19
    -0
      CMakeLists.txt
  4. +36
    -0
      cases.txt
  5. +81
    -0
      midi-utils.c
  6. +18
    -0
      midi-utils.h
  7. +26
    -0
      test-note-names.c

+ 2
- 0
.gitattributes Просмотреть файл

@@ -0,0 +1,2 @@
# This makes the repo play nice with git on Windows
* text=auto

+ 8
- 0
.gitignore Просмотреть файл

@@ -0,0 +1,8 @@
cmake-build-debug
*.o
CMakeFiles/
CMakeCache.txt
Makefile
cmake_install.cmake
example
.idea/

+ 19
- 0
CMakeLists.txt Просмотреть файл

@@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 3.24)
project(midi_note_id_utils C)

set(CMAKE_C_STANDARD 11)

include_directories(.)

add_executable(test-note-names
test-note-names.c
midi-utils.c
midi-utils.h)


add_custom_command(
TARGET test-note-names POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"${CMAKE_HOME_DIRECTORY}/cases.txt"
$<TARGET_FILE_DIR:test-note-names>
)

+ 36
- 0
cases.txt Просмотреть файл

@@ -0,0 +1,36 @@
C0 0
C#0 1
D0 2
D#0 3
E0 4
F0 5
F#0 6
G0 7
G#0 8
A0 9
A#0 10
B0 11
C1 12
C2 24
C3 36
C4 48
C5 60
A5 69
C6 72
C7 84
C8 96
C9 108
C10 120
G10 127
C11 132
C12 144
C13 156
C14 168
C15 180
C16 192
C17 204
C18 216
C19 228
C20 240
C21 252
D#21 255

+ 81
- 0
midi-utils.c Просмотреть файл

@@ -0,0 +1,81 @@
#include "midi-utils.h"

char* MIDI_GetNoteName(unsigned char midi_note) {
static const char* pitch_names[] = {
"C",
"C#",
"D",
"D#",
"E",
"F",
"F#",
"G",
"G#",
"A",
"A#",
"B"
};

const unsigned char pitch_class = midi_note % 12;
const unsigned char octave = midi_note / 12;
static char note_name[8];
sprintf(note_name, "%s%u", pitch_names[pitch_class], octave);
return note_name;
}

unsigned char MIDI_GetNoteFromName(const char* name) {
char name_copy[8];
strcpy(name_copy, name);
_strlwr(name_copy);

unsigned char octave = 0;
unsigned char has_accidental = name_copy[1] == '#' || name_copy[1] == 'b';
unsigned char octave_start = has_accidental ? 2 : 1;
unsigned char pitch_class;
char octave_offset = 0;

for (unsigned char i = octave_start; '0' <= name_copy[i] && name_copy[i] <= '9'; i += 1) {
octave *= 10;
octave += name_copy[i] - '0';
}

if (strstr(name_copy, "c#") || strstr(name_copy, "db")) {
pitch_class = 1;
} else if (strstr(name_copy, "d#") || strstr(name_copy, "eb")) {
pitch_class = 3;
} else if (strstr(name_copy, "fb")) {
pitch_class = 4;
} else if (strstr(name_copy, "e#")) {
pitch_class = 5;
} else if (strstr(name_copy, "f#") || strstr(name_copy, "gb")) {
pitch_class = 6;
} else if (strstr(name_copy, "g#") || strstr(name_copy, "ab")) {
pitch_class = 8;
} else if (strstr(name_copy, "a#") || strstr(name_copy, "bb")) {
pitch_class = 10;
} else if (strstr(name_copy, "cb")) {
pitch_class = 11;
octave_offset = -1;
} else if (strstr(name_copy, "b#")) {
pitch_class = 0;
octave_offset = 1;
} else if (strstr(name_copy, "c")) {
pitch_class = 0;
} else if (strstr(name_copy, "d")) {
pitch_class = 2;
} else if (strstr(name_copy, "e")) {
pitch_class = 4;
} else if (strstr(name_copy, "f")) {
pitch_class = 5;
} else if (strstr(name_copy, "g")) {
pitch_class = 7;
} else if (strstr(name_copy, "a")) {
pitch_class = 9;
} else if (strstr(name_copy, "b")) {
pitch_class = 11;
} else {
return 255u;
}

return ((octave * 12) + octave_offset) + pitch_class;
}

+ 18
- 0
midi-utils.h Просмотреть файл

@@ -0,0 +1,18 @@
#ifndef MIDI_UTILS_H
#define MIDI_UTILS_H

#include <stdio.h>
#include <string.h>

#define MIDI_MESSAGE_NOTEON 0x90u
#define MIDI_MESSAGE_NOTEOFF 0x80u

#define MIDI_CC_SUSTAIN 0x40u
#define MIDI_CC_SOSTENUTO 0x42u
#define MIDI_CC_UNACORDA 0x43u

char* MIDI_GetNoteName(unsigned char);

unsigned char MIDI_GetNoteFromName(const char*);

#endif

+ 26
- 0
test-note-names.c Просмотреть файл

@@ -0,0 +1,26 @@
#include <stdio.h>
#include <assert.h>
#include "midi-utils.h"

int main(void) {
FILE* f = fopen("cases.txt", "r");
if (!f) {
return -1;
}
char read_note_name[255] = "";
unsigned int read_note_value;
while (!feof(f)) {
fscanf(f, "%s %d\n", read_note_name, &read_note_value);
unsigned int actual_note_value = MIDI_GetNoteFromName(read_note_name);
printf("MIDI_GetNoteFromName(\"%s\")...", read_note_name);
assert(read_note_value == actual_note_value);
printf("OK!\n");

printf("MIDI_GetNoteName(%d)...", read_note_value);
assert(!strcmp(MIDI_GetNoteName(read_note_value), read_note_name));
printf("OK!\n");
}

fclose(f);
return 0;
}

Загрузка…
Отмена
Сохранить