[toc]

C语言在Windows中播放乐谱

1.C语言在Windows中通过音符相关函数播放一秒432HZ的声音

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
#include <stdio.h>
#include <windows.h>
#include <math.h>

#pragma comment(lib, "winmm.lib")

void PlayTone(double frequency, int duration) {
HMIDIOUT handle;
midiOutOpen(&handle, 0, 0, 0, CALLBACK_NULL);

int volume = 0x7f; // 最大音量
int sleep = duration; // 每个音符的持续时间

// 计算432Hz对应的MIDI音符
int midiNote = (int)(69 + 12 * log2(frequency / 440.0));

// 发送音符消息
int voice = (volume << 16) + ((midiNote) << 8) + 0x90; // 按下音符
midiOutShortMsg(handle, voice); // 发送音符
Sleep(sleep); // 等待
midiOutShortMsg(handle, (volume << 16) + ((midiNote) << 8) + 0x80); // 发送音符释放消息

midiOutClose(handle);
}

int main() {
PlayTone(432.0, 1000); // 播放432Hz音调,持续1秒
return 0;
}

2.C语言在Windows中通过音符相关函数播放八秒432-440HZ的声音

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
#include <stdio.h>
#include <windows.h>
#include <math.h>

#pragma comment(lib, "winmm.lib")

void PlayTone(double frequency, int duration) {
HMIDIOUT handle;
midiOutOpen(&handle, 0, 0, 0, CALLBACK_NULL);

int volume = 0x7f; // 最大音量

// 计算当前频率对应的MIDI音符
int midiNote = (int)(69 + 12 * log2(frequency / 440.0));

// 发送音符消息
int voice = (volume << 16) + ((midiNote) << 8) + 0x90; // 按下音符
midiOutShortMsg(handle, voice); // 发送音符
Sleep(duration); // 等待
midiOutShortMsg(handle, (volume << 16) + ((midiNote) << 8) + 0x80); // 发送音符释放消息

midiOutClose(handle);
}

int main() {
for (int i = 423; i <= 430; i++) {
PlayTone((double)i, 1000); // 播放423Hz到430Hz的音调,每个音调持续1秒
}
return 0;
}

3.音调是什么,音调与频率的关系,简单记录几个关于音律的概念

  • 国际标准将乐器演奏中央区的A音符基频设为了440Hz。

  • 三和弦指的是三个音同时发出的声音,在钢琴中隔一按一。

1. 简谱

  • 简谱是指数字简谱,用1、2、3、4、5、6、7代表音阶中的7个基本级,读音为do、re、mi、fa、sol、la、ti(中国为si)。英文由C、D、E、F、G、A、B表示,休止以0表示。
  • 简谱使用五度相生法计算出来的
  • 八度指的是将440HZ到880HZ之间的频率分为了八个。1、2、3、4、5、6、7、1。

2.五线谱

五线谱 (Musical Notation) 目前世界上通用的记谱法。在5根等距离的平行横线上,标以不同时值的音符及其他记号来记载音乐的一种方法。

3.五音

  • 五声音阶,或称为五声调式,5个音依次定名为角jué徵zhǐ
  • 五音使用三分损易法

4.十二平均律

现代很多乐器都采用了十二平均律,例如钢琴。

  • 钢琴共有88个键位,中间的C1为基准调,通常为440HZ。
  • 钢琴里的八度指的是将440HZ-880HZ之间的频率平均分为了十二个。分别为C,#C,D,#D,E,F,#F,G,#G,A,#A,B。每个键位之间隔了半度。

5.音高频率表


频率,单位为赫兹。括号内为距离中央C(261.63赫兹)的半音距离。
八度→ 音名↓ 0 1 2 3 4 5 6 7 8 9
C 16.352(−48) 32.703(−36) 65.406(−24) 130.81(−12) 261.63(0) 523.25(+12) 1046.5(+24) 2093.0(+36) 4186.0(+48) 8372.0(+60)
C♯/D♭ 17.324(−47) 34.648(−35) 69.296(−23) 138.59(−11) 277.18(+1) 554.37(+13) 1108.7(+25) 2217.5(+37) 4434.9(+49) 8869.8(+61)
D 18.354(−46) 36.708(−34) 73.416(−22) 146.83(−10) 293.66(+2) 587.33(+14) 1174.7(+26) 2349.3(+38) 4698.6(+50) 9397.3(+62)
D♯/E♭ 19.445(−45) 38.891(−33) 77.782(−21) 155.56(−9) 311.13(+3) 622.25(+15) 1244.5(+27) 2489.0(+39) 4978.0(+51) 9956.1(+63)
E 20.602(−44) 41.203(−32) 82.407(−20) 164.81(−8) 329.63(+4) 659.26(+16) 1318.5(+28) 2637.0(+40) 5274.0(+52) 10548(+64)
F 21.827(−43) 43.654(−31) 87.307(−19) 174.61(−7) 349.23(+5) 698.46(+17) 1396.9(+29) 2793.8(+41) 5587.7(+53) 11175(+65)
F♯/G♭ 23.125(−42) 46.249(−30) 92.499(−18) 185.00(−6) 369.99(+6) 739.99(+18) 1480.0(+30) 2960.0(+42) 5919.9(+54) 11840(+66)
G 24.500(−41) 48.999(−29) 97.999(−17) 196.00(−5) 392.00(+7) 783.99(+19) 1568.0(+31) 3136.0(+43) 6271.9(+55) 12544(+67)
G♯/A♭ 25.957(−40) 51.913(−28) 103.83(−16) 207.65(−4) 415.30(+8) 830.61(+20) 1661.2(+32) 3322.4(+44) 6644.9(+56) 13290(+68)
A 27.500(−39) 55.000(−27) 110.00(−15) 220.00(−3) 440.00(+9) 880.00(+21) 1760.0(+33) 3520.0(+45) 7040.0(+57) 14080(+69)
A♯/B♭ 29.135(−38) 58.270(−26) 116.54(−14) 233.08(−2) 466.16(+10) 932.33(+22) 1864.7(+34) 3729.3(+46) 7458.6(+58) 14917(+70)
B 30.868(−37) 61.735(−25) 123.47(−13) 246.94(−1) 493.88(+11) 987.77(+23) 1975.5(+35) 3951.1(+47) 7902.1(+59) 15804(+71)

4. C语言通过音符相关函数播放’do re mi fa so la ti do’

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>
#include <windows.h>

#pragma comment(lib, "winmm.lib")

enum Scale {
Rest = 0, C8 = 108, B7 = 107, A7s = 106, A7 = 105, G7s = 104, G7 = 103, F7s = 102, F7 = 101, E7 = 100,
D7s = 99, D7 = 98, C7s = 97, C7 = 96, B6 = 95, A6s = 94, A6 = 93, G6s = 92, G6 = 91, F6s = 90, F6 = 89,
E6 = 88, D6s = 87, D6 = 86, C6s = 85, C6 = 84, B5 = 83, A5s = 82, A5 = 81, G5s = 80, G5 = 79, F5s = 78,
F5 = 77, E5 = 76, D5s = 75, D5 = 74, C5s = 73, C5 = 72, B4 = 71, A4s = 70, A4 = 69, G4s = 68, G4 = 67,
F4s = 66, F4 = 65, E4 = 64, D4s = 63, D4 = 62, C4s = 61, C4 = 60, B3 = 59, A3s = 58, A3 = 57, G3s = 56,
G3 = 55, F3s = 54, F3 = 53, E3 = 52, D3s = 51, D3 = 50, C3s = 49, C3 = 48, B2 = 47, A2s = 46, A2 = 45,
G2s = 44, G2 = 43, F2s = 42, F2 = 41, E2 = 40, D2s = 39, D2 = 38, C2s = 37, C2 = 36, B1 = 35, A1s = 34,
A1 = 33, G1s = 32, G1 = 31, F1s = 30, F1 = 29, E1 = 28, D1s = 27, D1 = 26, C1s = 25, C1 = 24, B0 = 23,
A0s = 22, A0 = 21
};

void PlayScale() {
HMIDIOUT handle;
midiOutOpen(&handle, 0, 0, 0, CALLBACK_NULL);

int volume = 0x7f; // 最大音量
int sleep = 500; // 每个音符的持续时间

// "dou rou mi fa so la ti dou" 对应的 MIDI 音符
int melody[] = {
60, 62, 64, 65, 67, 69, 71, 72 // C4, D4, E4, F4, G4, A4, B4, C5
};

int melodyLength = sizeof(melody) / sizeof(melody[0]);

for (int i = 0; i < melodyLength; i++) {
int note = melody[i];
int voice = (volume << 16) + ((note) << 8) + 0x90; // 构造 MIDI 消息
midiOutShortMsg(handle, voice); // 发送音符
Sleep(sleep); // 等待
midiOutShortMsg(handle, (volume << 16) + ((note) << 8) + 0x80); // 发送音符释放消息
}

midiOutClose(handle);
}

int main() {
PlayScale();
return 0;
}