我们先说原理,电脑上呢有许多的硬件我们是可以通过调用底层API来驱动的,其中就有蜂鸣器,计算机上的蜂鸣器硬件属于无源蜂鸣器。
无源蜂鸣器与有源蜂鸣器
蜂鸣器根据是否包含内置的振荡源,可以分为有源蜂鸣器和无源蜂鸣器:
-
有源蜂鸣器 :有源蜂鸣器内部带有振荡源,简单通电即可发声。它们通常用于发出简单的警报声或提示音,只需提供电压就可以产生固定频率的声音。
-
无源蜂鸣器 :无源蜂鸣器没有内置振荡源,必须通过外部电路提供振荡信号才能发声。计算机上的蜂鸣器通常是无源蜂鸣器,需要通过控制电路向其提供特定频率的信号以产生相应频率的声音。
驱动无源蜂鸣器的原理 无源蜂鸣器通过振动发出声音。 当施加不同频率的电信号时,蜂鸣器的振动膜会根据信号的频率振动并发出相应频率的声音。
要在计算机上控制无源蜂鸣器,我们需要使用操作系统提供的API,这些API允许我们生成不同频率的电信号。
因为其会发出嗡嗡声,可能特别像蜜蜂发出的声音,所以才会叫做蜂鸣器吧。
众所周知,我们所发出的声音音调高低其实和频率有关系,频率越高音调越高,频率越低音调越低。
声音与音调
声音的频率是指声波振动的频率,单位是赫兹(Hz)。一个声波振动的周期是指它从一个峰值到下一个峰值(或从一个谷值到下一个谷值)所经历的时间。频率则是指每秒钟内发生的振动周期数。
-
高频率 的声音意味着声波振动非常快,频率高,所以我们感觉到的音调也就越高。
-
低频率 的声音意味着声波振动相对缓慢,频率低,所以我们感觉到的音调也就越低。
在音乐理论中,不同的音符对应着不同的频率。音符的命名是按照西方音乐记谱法来的,从A到G(包括半音),然后再从A开始重复。在标准的中央C调中,每个音符对应的频率如下:
-
A – 440 Hz
-
B – 493.88 Hz
-
C – 261.63 Hz
-
D – 293.66 Hz
-
E – 329.63 Hz
-
F – 349.23 Hz
-
G – 392.00 Hz
这些频率是标准音调的基础频率,音乐中的其他音符是通过这些基础频率的倍数或分数来计算的。
因此我们可以通过C语言来调用windows的底层API来驱动蜂鸣器,只要我们设置好特定的频率和时间,我们就可以实现让蜂鸣器唱一首歌。 **
C语言的代码实现 **
接着找一首歌的简谱,这里选的是很经典的生日快乐歌。
void playBirthdaySong() { // 定义音调 float HZ[] = {
0, // 休止符 // 中音 261.63, // C4 293.66, // D4 329.63, // E4 349.23, // F4 392.00, // G4 440.00, // A4 493.88, // B4
// 高音 523.25, // C5 587.33, // D5 659.25, // E5 698.46, // F5 783.99, // G5 880.00, // A5 987.77 // B5 };
int notes[] = { 0,2,0,2,5,1,5,1,6,2,5,2,8,2,7,4,5,1,5,1,6,2,5,2,9,2, 8,4,5,1,5,1,12,2,10,2,8,2,7,2,6,4,0,2,0,2,11,1,11,1, 10,2,8,2,9,2,8,4,5,1,5,1,6,2,5,2,8,2,7,4,5,1,5,1,6,2, 5,2,9,2,8,4,5,1,5,1,12,2,10,2,8,2,7,2,6,4,0,2,0,2,11,1,11,1, 10,2,8,2,9,2,8,4,0,2 };
我们定义一个音调数组用来存放音调,因为生日快乐歌的简谱并没有低音,因此我们只需要定义高音和中音即可。
然后根据简谱,敲写一段生日快乐歌,这里我们的定义规则是:
音调+时长。
int duration = 250;//每个音符的播放持续时间
// 播放音符 for (int i = 0; i < sizeof(notes) / sizeof(notes[0])/2; i++) { if (notes[i*2] == 0) { Sleep(duration * 2); } else { Beep(HZ[notes[i*2]], duration*notes[i*2+1]); } }
接着播放我们的音乐即可。