模拟音乐的频率公式

背景

昨天在翻阅taiga源代码的时候发现了一个神奇的Windows API Beep函数, 突然想到曾经有人跟我说过可以用Beep播放一首歌曲,
回忆起小时候用计算器的按键音当成各种调子按下,模拟音乐的简单快乐。
于是我便看了这份代码播放的音乐,当点击ICON图标时播放一首orange歌曲。
(猜测应该是这首https://c.y.qq.com/base/fcgi-bin/u?__=9xGuYfR)

代码介绍

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
namespace BeepMusic
{
constexpr std::array<std::pair<int, float>, 32> notes{{
{84, 1 / 2.f}, {84, 1 / 4.f}, {86, 1 / 8.f}, {84, 1 / 4.f},
{82, 1 / 4.f}, {81, 1 / 4.f}, {77, 1 / 8.f}, {79, 1 / 8.f},
{72, 1 / 8.f}, {77, 1 / 2.f}, {76, 1 / 8.f}, {77, 1 / 8.f},
{79, 1 / 8.f}, {81, 1 / 4.f}, {79, 1 / 4.f}, {77, 1 / 4.f},
{79, 1 / 4.f}, {81, 1 / 8.f}, {84, 1 / 2.f}, {84, 1 / 4.f},
{86, 1 / 8.f}, {84, 1 / 4.f}, {82, 1 / 4.f}, {81, 1 / 4.f},
{77, 1 / 8.f}, {79, 1 / 8.f}, {72, 1 / 8.f}, {77, 1 / 2.f},
{76, 1 / 8.f}, {77, 1 / 8.f}, {76, 1 / 8.f}, {74, 1 / 2.f},
}};

void playOrange()
{
constexpr auto get_frequency = [](const int note) {
if (note < 0 || note > 119) return -1.0f;
return 440.0f *
std::pow(2.0f, static_cast<float>(note - 57) / 12.0f);
};

constexpr auto get_duration = [](const float duration) {
return 1600 * duration;
};

for (const auto& [note, duration] : notes)
{
::Beep(static_cast<DWORD>(get_frequency(note)),
static_cast<DWORD>(get_duration(duration)));
}
}
} // namespace BeepMusic

其中有个公式
$$
440 \times 2 ^ {\frac{(x-57)}{12}}
$$
哪来的?

经反复查找资料
MIDI代表乐器数字接口。该标准指定了软件和电子设备可以传输和接收音乐的方式。

另外一个公式在开源项目 audacity
$$
440 \times 2 ^ {\frac{(x-69)}{12}}
$$

这个2个公式本身是什么逻辑,哪里来的,很难猜到,需要了解乐理知识

乐理知识

  • 乐音体系: 有固定音高的音(乐音)的总和,叫做乐音体系。 一般的钢琴 88琴键 $A_2 - C^5$

  • 音级: 在乐音体系中的每个音,就叫做“音级”。音级包括有基本音级和变化音级两种。 自然

  • 音列:将乐音体系中的音,依照音高关系和次序,由低到高(上行)或由高向低(下行)排列起来,叫做“音列”。

  • 半音: 在整个乐音体系中,相邻的两个音级(不论基本音级或变化音级)之间的音高关系就是“半音”,半音是音高关系中的最小单位。用分数1/2来标记。

  • 全音: 在乐音体系中,两个半音相加,就形成了全音。用阿拉伯数字1来标记。

  • 音名: 在乐音体系中,七个具有独立名称的音级叫做基本音级(也叫自然音级) “C D E F G A B” 钢琴白键都是基本音级

  • 变化音级: # 升音级 $^#C$ 升半音 , b 降音级 $^bD$ 降半音 , # 重升音级 $^×E$ 升Q全音 , bb 重降音级 $^{bb}F$ 降半音

  • 大谱钢琴键盘对照表 对照表

标准音

中央C 440Hz 第一国际高音
小字a $a^1 = 435 hz$ 第二国际高音 演奏会音高

音律关系

纯律

西洋乐器

五度相生律

五度相生律又叫“三分损益律”,它是按纯五度的关系向上或向下推算的办法,来找出整个各个音级的精确高度。即是用分音列中第二分音与第三分音之间的音高关系,连续相生而求得出的各个音级的准确音高。 民族乐器。

十二平均律

将纯八度分成十二个均等的部分的音律叫做十二平均律。其中每一个部分就是一个半音,每个半音的距离是相等的,它的最大好处是转调方便。十二平均律多用在钢琴、手风琴、电子琴、风琴。

最终代码公式

1
2
3
4
5
6
float midi[127];
int a = 440; // a is 440 hz...
for (int x = 0; x < 127; ++x)
{
midi[x] = (a / 32) * (2 ^ ((x - 9) / 12));
}

公式
$$
\frac{440}{32} \times 2 ^ {\frac{(x-9)}{12}}
$$

附录

 MIDI                   MIDI                   MIDI
 Note     Frequency      Note   Frequency       Note   Frequency
 C1  0    8.1757989156    12    16.3515978313    24    32.7031956626
 Db  1    8.6619572180    13    17.3239144361    25    34.6478288721
 D   2    9.1770239974    14    18.3540479948    26    36.7080959897
 Eb  3    9.7227182413    15    19.4454364826    27    38.8908729653
 E   4   10.3008611535    16    20.6017223071    28    41.2034446141
 F   5   10.9133822323    17    21.8267644646    29    43.6535289291
 Gb  6   11.5623257097    18    23.1246514195    30    46.2493028390
 G   7   12.2498573744    19    24.4997147489    31    48.9994294977
 Ab  8   12.9782717994    20    25.9565435987    32    51.9130871975
 A   9   13.7500000000    21    27.5000000000    33    55.0000000000
 Bb  10  14.5676175474    22    29.1352350949    34    58.2704701898
 B   11  15.4338531643    23    30.8677063285    35    61.7354126570

 C4  36  65.4063913251    48   130.8127826503    60   261.6255653006
 Db  37  69.2956577442    49   138.5913154884    61   277.1826309769
 D   38  73.4161919794    50   146.8323839587    62   293.6647679174
 Eb  39  77.7817459305    51   155.5634918610    63   311.1269837221
 E   40  82.4068892282    52   164.8137784564    64   329.6275569129
 F   41  87.3070578583    53   174.6141157165    65   349.2282314330
 Gb  42  92.4986056779    54   184.9972113558    66   369.9944227116
 G   43  97.9988589954    55   195.9977179909    67   391.9954359817
 Ab  44  103.8261743950   56   207.6523487900    68   415.3046975799
 A   45  110.0000000000   57   220.0000000000    69   440.0000000000
 Bb  46  116.5409403795   58   233.0818807590    70   466.1637615181
 B   47  123.4708253140   59   246.9416506281    71   493.8833012561

 C7  72  523.2511306012   84  1046.5022612024    96  2093.0045224048
 Db  73  554.3652619537   85  1108.7305239075    97  2217.4610478150
 D   74  587.3295358348   86  1174.6590716696    98  2349.3181433393
 Eb  75  622.2539674442   87  1244.5079348883    99  2489.0158697766
 E   76  659.2551138257   88  1318.5102276515   100  2637.0204553030
 F   77  698.4564628660   89  1396.9129257320   101  2793.8258514640
 Gb  78  739.9888454233   90  1479.9776908465   102  2959.9553816931
 G   79  783.9908719635   91  1567.9817439270   103  3135.9634878540
 Ab  80  830.6093951599   92  1661.2187903198   104  3322.4375806396
 A   81  880.0000000000   93  1760.0000000000   105  3520.0000000000
 Bb  82  932.3275230362   94  1864.6550460724   106  3729.3100921447
 B   83  987.7666025122   95  1975.5332050245   107  3951.0664100490

 C10 108 4186.0090448096  120  8372.0180896192
 Db  109 4434.9220956300  121  8869.8441912599
 D   110 4698.6362866785  122  9397.2725733570
 Eb  111 4978.0317395533  123  9956.0634791066
 E   112 5274.0409106059  124 10548.0818212118
 F   113 5587.6517029281  125 11175.3034058561
 Gb  114 5919.9107633862  126 11839.8215267723
 G   115 6271.9269757080  127 12543.8539514160
 Ab  116 6644.8751612791
 A   117 7040.0000000000
 Bb  118 7458.6201842894
 B   119 7902.1328200980
打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2020-2021 一潭清泓
  • Powered by Hexo Theme Ayer
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信