Small utility library for MIDI functions.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

117 lignes
2.7 KiB

  1. #include "midi-utils.h"
  2. #if !defined _WIN32
  3. /**
  4. * Converts a string to lowercase.
  5. * @param dest - The string to convert.
  6. */
  7. void _strlwr(char* dest) {
  8. for (unsigned int i = 0; i < strlen(dest); i += 1) {
  9. if ('A' <= dest[i] && dest[i] <= 'Z') {
  10. dest[i] += 0x20;
  11. }
  12. }
  13. }
  14. #endif
  15. /**
  16. * Gets the name of a MIDI note value.
  17. * @param midi_note - The MIDI note value.
  18. * @note Valid values are from 0-127.
  19. * @return The MIDI note name.
  20. * @see MIDI_GetNoteFromName()
  21. */
  22. char* MIDI_GetNoteName(unsigned char midi_note) {
  23. static const char* pitch_names[] = {
  24. "C",
  25. "C#",
  26. "D",
  27. "D#",
  28. "E",
  29. "F",
  30. "F#",
  31. "G",
  32. "G#",
  33. "A",
  34. "A#",
  35. "B"
  36. };
  37. const unsigned char pitch_class = midi_note % 12;
  38. const unsigned char octave = midi_note / 12;
  39. static char note_name[8];
  40. sprintf(note_name, "%s%u", pitch_names[pitch_class], octave);
  41. return note_name;
  42. }
  43. /**
  44. * Gets the note value from a MIDI note name
  45. * @param name - The MIDI note name.
  46. * @return The MIDI note value, or 255 if an invalid name is passed.
  47. * @see MIDI_GetNoteName()
  48. */
  49. unsigned char MIDI_GetNoteFromName(const char* name) {
  50. if (!name) {
  51. return 255u;
  52. }
  53. char name_copy[8];
  54. strcpy(name_copy, name);
  55. _strlwr(name_copy);
  56. unsigned char octave = 0;
  57. unsigned char has_accidental = name_copy[1] == '#' || name_copy[1] == 'b';
  58. unsigned char octave_start = has_accidental ? 2 : 1;
  59. unsigned char pitch_class;
  60. char octave_offset = 0;
  61. for (unsigned char i = octave_start; '0' <= name_copy[i] && name_copy[i] <= '9'; i += 1) {
  62. octave *= 10;
  63. octave += name_copy[i] - '0';
  64. }
  65. if (strstr(name_copy, "c#") || strstr(name_copy, "db")) {
  66. pitch_class = 1;
  67. } else if (strstr(name_copy, "d#") || strstr(name_copy, "eb")) {
  68. pitch_class = 3;
  69. } else if (strstr(name_copy, "fb")) {
  70. pitch_class = 4;
  71. } else if (strstr(name_copy, "e#")) {
  72. pitch_class = 5;
  73. } else if (strstr(name_copy, "f#") || strstr(name_copy, "gb")) {
  74. pitch_class = 6;
  75. } else if (strstr(name_copy, "g#") || strstr(name_copy, "ab")) {
  76. pitch_class = 8;
  77. } else if (strstr(name_copy, "a#") || strstr(name_copy, "bb")) {
  78. pitch_class = 10;
  79. } else if (strstr(name_copy, "cb")) {
  80. pitch_class = 11;
  81. octave_offset = -1;
  82. } else if (strstr(name_copy, "b#")) {
  83. pitch_class = 0;
  84. octave_offset = 1;
  85. } else if (strstr(name_copy, "c")) {
  86. pitch_class = 0;
  87. } else if (strstr(name_copy, "d")) {
  88. pitch_class = 2;
  89. } else if (strstr(name_copy, "e")) {
  90. pitch_class = 4;
  91. } else if (strstr(name_copy, "f")) {
  92. pitch_class = 5;
  93. } else if (strstr(name_copy, "g")) {
  94. pitch_class = 7;
  95. } else if (strstr(name_copy, "a")) {
  96. pitch_class = 9;
  97. } else if (strstr(name_copy, "b")) {
  98. pitch_class = 11;
  99. } else {
  100. return 255u;
  101. }
  102. if (octave == 0 && octave_offset < 0) {
  103. return 255u;
  104. }
  105. return ((octave * 12) + octave_offset) + pitch_class;
  106. }