diff options
author | Takamichi Horikawa <takamichiho@gmail.com> | 2017-03-14 19:10:24 +0900 |
---|---|---|
committer | Takamichi Horikawa <takamichiho@gmail.com> | 2017-03-14 19:10:24 +0900 |
commit | 46e2455027537dc1ef56b98b712cf92edf27dca5 (patch) | |
tree | e2a09f9b53274a22c0f9a08a2a56bf3f31cf507e /fmdriver/fmdriver_common.c | |
parent | 16be4100808e09a94e802adb58bc1c79e5eefd65 (diff) |
add initial PMD support
Diffstat (limited to 'fmdriver/fmdriver_common.c')
-rw-r--r-- | fmdriver/fmdriver_common.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/fmdriver/fmdriver_common.c b/fmdriver/fmdriver_common.c new file mode 100644 index 0000000..26e6def --- /dev/null +++ b/fmdriver/fmdriver_common.c @@ -0,0 +1,71 @@ +#include "fmdriver/fmdriver_common.h" + +uint8_t fmdriver_fm_freq2key(uint16_t freq) { + int block = freq >> (8+3); + int f_num = freq & ((1<<(8+3))-1); + if (!f_num) return 0x00; + while (!(f_num & (1<<(8+3-1)))) { + f_num <<= 1; + block--; + } + static const uint16_t freqtab[0xc] = { + 0x042e, // < 9 (a) + 0x046e, + 0x04b1, + 0x04f9, + 0x0544, + 0x0595, + 0x05ea, + 0x0644, + 0x06a3, + 0x0708, + 0x0773, + 0x07e4, + }; + int note = 0; + for (; note < 12; note++) { + if (f_num < freqtab[note]) break; + } + note += 9; + block += (note/12); + note %= 12; + + if (block < 0) return 0x00; + if (block > 8) return 0x8b; + return (block << 4) | note; +} + +uint8_t fmdriver_ssg_freq2key(uint16_t freq) { + if (!freq) return 0x00; + int octave = -5; + while (!(freq & 0x8000)) { + freq <<= 1; + octave++; + } + // 7987200.0 / (64*440*(2**((i+2+0.5)/12))/(1<<8)) + static const uint16_t freqtab[0xc] = { + 0xf57f, // > 0 (c) + 0xe7b8, + 0xdab7, + 0xce70, + 0xc2da, + 0xb7ea, + 0xad98, + 0xa3da, + 0x9aa7, + 0x91f9, + 0x89c8, + 0x820c, + }; + int note = 0; + for (; note < 12; note++) { + if (freq > freqtab[note]) break; + } + note += 11; + octave += (note/12); + note %= 12; + + if (octave < 0) return 0x00; + if (octave > 8) return 0x8b; + return (octave << 4) | note; +} |