uilleann/tuning.h

131 lines
3.5 KiB
C
Raw Normal View History

2020-11-24 16:56:58 -07:00
#pragma once
#include <stdint.h>
enum TuningSystem {
TUNINGSYSTEM_JUST,
TUNINGSYSTEM_EQUAL,
TUNINGSYSTEM_MAX = TUNINGSYSTEM_EQUAL,
2020-11-24 16:56:58 -07:00
};
2020-11-25 09:28:53 -07:00
// Twelve-Tone Note (one chromatic scale)
#define NOTE_TT(o) NOTE_C##o, NOTE_Cs##o, NOTE_Db##o = NOTE_Cs##o, \
NOTE_D##o, NOTE_Ds##o, NOTE_Eb##o = NOTE_Ds##o, \
NOTE_E##o, \
NOTE_F##o, NOTE_Fs##o, NOTE_Gb##o = NOTE_Fs##o, \
NOTE_G##o, NOTE_Gs##o, NOTE_Ab##o = NOTE_Gs##o, \
NOTE_A##o, NOTE_As##o, NOTE_Bb##o = NOTE_As##o, \
NOTE_B##o
2020-11-24 16:56:58 -07:00
enum Note {
2020-11-25 09:28:53 -07:00
NOTE_TT(0),
NOTE_TT(1),
NOTE_TT(2),
NOTE_TT(3),
NOTE_TT(4),
NOTE_TT(5),
NOTE_TT(6),
NOTE_TT(7),
NOTE_TT(8),
2020-11-24 16:56:58 -07:00
NOTE_ZERO = 0,
NOTE_SEMITONE = 1,
NOTE_WHOLETONE = 2,
NOTE_OCTAVE = NOTE_C1,
NOTE_MAX = NOTE_B8,
};
#define PITCH_CONCERT_C0 16.35
#define PITCH_CONCERT_A4 440.00
2020-11-24 16:56:58 -07:00
#define PITCH_CONCERT_D4 293.66
// Twelvetone Equal Temperament semitone multiplier
// Take any frequency and multiply it by this magic number to get a semitone higher!
// Divide to get a semitone lower!
// This is an approximation of exp(2, 1/12),
// which was worked out in around the 1500s.
#define TET_SEMITONE_MULTIPLIER 1.059463
2020-11-24 16:56:58 -07:00
class Tuning {
public:
// name contains the name of the current tuning system
const char *name;
2020-11-24 16:56:58 -07:00
Tuning(Note base, float pitch, TuningSystem system);
Tuning(Note base, float pitch);
Tuning();
void Setup(Note base, float pitch, TuningSystem system);
void Setup(Note base, float pitch);
void SetTuningSystem(TuningSystem system);
TuningSystem GetTuningSystem();
Note GetBaseNote();
float GetPitch(Note note);
2020-11-24 16:56:58 -07:00
private:
TuningSystem system;
Note baseNote;
float pitches[NOTE_MAX];
2020-11-24 16:56:58 -07:00
void setupOctaves(Note base);
void setupJust(Note base, float pitch);
void setupEqual(Note base, float pitch);
2020-11-24 16:56:58 -07:00
};
// NearestNote returns the note nearest to pitch.
Note NearestNote(float pitch);
2020-11-25 17:13:54 -07:00
// NoteOctave returns which octave the note is in
int NoteOctave(Note note);
// NoteName returns the name of a note (without octave).
2020-11-24 16:56:58 -07:00
const char *NoteName(Note note);
// TuningSystemName returns the name of a tuning system.
const char *TuningSystemName(TuningSystem system);
2020-11-24 16:56:58 -07:00
// Make notes support some arithmetic
inline Note toNote(int a) {
if (a < NOTE_ZERO) {
return NOTE_ZERO;
} else if (a > NOTE_MAX) {
return NOTE_MAX;
} else {
return Note(a);
}
2020-11-24 16:56:58 -07:00
}
2020-11-25 17:13:54 -07:00
inline Note operator+(const Note &a, const int b) {
return toNote(int(a) + b);
}
2020-11-24 16:56:58 -07:00
inline Note operator+(const Note &a, const Note b) {
2020-11-25 17:13:54 -07:00
return a + int(b);
}
inline Note &operator+=(Note &a, const int b) {
return a = a + b;
2020-11-24 16:56:58 -07:00
}
inline Note &operator+=(Note &a, const Note b) {
return a = a + b;
2020-11-24 16:56:58 -07:00
}
inline Note &operator++(Note &a) {
return a += NOTE_SEMITONE;
2020-11-24 16:56:58 -07:00
}
inline Note operator-(const Note a, const Note b) {
return toNote(int(a) - int(b));
2020-11-24 16:56:58 -07:00
}
inline Note &operator-=(Note &a, const Note b) {
return a = a - b;
2020-11-24 16:56:58 -07:00
}
inline Note &operator--(Note &a) {
return a -= NOTE_SEMITONE;
2020-11-24 16:56:58 -07:00
}
inline Note operator*(const Note a, const int b) {
return toNote(int(a) * b);
2020-11-24 16:56:58 -07:00
}
inline int operator/(const Note a, const int b) {
return int(a) / b;
2020-11-24 16:56:58 -07:00
}
inline int operator/(const Note a, const Note b) {
return int(a) / b;
}
inline TuningSystem operator++(TuningSystem &a) {
return a = TuningSystem((int(a) + 1) % int(TUNINGSYSTEM_MAX + 1));
2020-11-24 16:56:58 -07:00
}