arngment/note.c

66 lines
1.2 KiB
C

/*
* arngment - random music generator
*
* Written in 2020 by Lucas
*
* To the extent possible under law, the author(s) have dedicated all
* copyright and related and neighboring rights to this software to the
* public domain worldwide. This software is distributed without any
* warranty.
*
* You should have received a copy of the CC0 Public Domain Dedication
* along with this software. If not, see
* <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <math.h>
#include "note.h"
static int
midi(struct note n)
{
/* C0 is MIDI note 12 */
return 12 * (n.octave + 1) + n.offset + n.accident;
}
double
note_pitch(struct note n)
{
int m = midi(n);
return 440.0 * pow(2.0, (m - 69) / 12.0);
}
int
note_parse(struct note *note, const char *s)
{
/* Semitones from C, starting at A */
static int offsets[] = {9, 11, 0, 2, 4, 5, 7};
struct note n;
if (*s < 'A' || *s > 'G')
return 0;
n.offset = offsets[*s - 'A'];
s++;
if (*s == 'b') {
n.accident = ACCIDENT_FLAT;
s++;
} else if (*s == '#') {
n.accident = ACCIDENT_SHARP;
s++;
} else
n.accident = ACCIDENT_NATURAL;
if (*s < '0' || *s > '9')
return 0;
n.octave = *s - '0';
s++;
if (*s != '\0')
return 0;
*note = n;
return 1;
}