程序:
文件下载:
BeepMusicPlayer.zip
目录下有四个文件:
exe打开后,按ASDF、HJKL即可弹奏出钢琴的八个音(http://www.huidong.xyz/index.php?mode=2&id=126 )
也可以通过音乐文件播放一段指定的音乐,music_1.txt 和 music_2.txt 都是音乐文件,两个都差不多,是黑人抬棺的音乐,但是模仿的不太像,只是把最前面那一段唱出来了。
将music_1.txt 或 music_2.txt 拖拽到exe来打开,可以播放其中的音乐,播放完毕后,程序自动退出。
音乐文件格式:
就例如下面这一段的解析:
200 2 100 3 200 -1
那么这一段的效果是:
代码 | 效果 |
---|
200 (头)
| 程序知道这个音乐最长就是200个音 |
2 100 (身体) | 2代表“来”音,100代表播放0.1秒 |
3 200 (身体)
| 3代表“米”音,200代表播放0.2秒 |
-1 (尾)
| 程序知道要结束播放这个音乐了 |
其中,头尾很重要,必须有(如果音乐总长度可以确定,那么直接填写头而不必填写尾);身体部分是这首歌曲的内容,自己定义。
0-7代表钢琴中的八个音
源码:
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
// 钢琴八个音的音频
#define SOUND_DOU 523 // 多
#define SOUND_LAI 587 // 来
#define SOUND_MI 659 // 米
#define SOUND_FA 698 // 法
#define SOUND_SOU 784 // 少
#define SOUND_LA 880 // 拉
#define SOUND_XI 980 // 梯
#define SOUND_DO 1060// 多
// 音乐结构
struct SOUND
{
int sound_code; // 音频代码(0-7代表钢琴的8个音)
int time; // 长度
};
// 演奏者模式
void Player()
{
int delay = 100;
while (true)
{
if (GetKeyState('A') & 0x8000)
{
Beep(SOUND_DOU, delay);
}
if (GetKeyState('S') & 0x8000)
{
Beep(SOUND_LAI, delay);
}
if (GetKeyState('D') & 0x8000)
{
Beep(SOUND_MI, delay);
}
if (GetKeyState('F') & 0x8000)
{
Beep(SOUND_FA, delay);
}
if (GetKeyState('H') & 0x8000)
{
Beep(SOUND_SOU, delay);
}
if (GetKeyState('J') & 0x8000)
{
Beep(SOUND_LA, delay);
}
if (GetKeyState('K') & 0x8000)
{
Beep(SOUND_XI, delay);
}
if (GetKeyState('L') & 0x8000)
{
Beep(SOUND_DO, delay);
}
Sleep(delay);
}
}
// 根据音乐文件放音乐模式
void Music(SOUND* sound_list, int music_long)
{
for (int i = 0; i < music_long; i++)
{
// 真实播放的音频
int sound;
switch (sound_list[i].sound_code)
{
case 0:
sound = SOUND_DOU;
break;
case 1:
sound = SOUND_LAI;
break;
case 2:
sound = SOUND_MI;
break;
case 3:
sound = SOUND_FA;
break;
case 4:
sound = SOUND_SOU;
break;
case 5:
sound = SOUND_LA;
break;
case 6:
sound = SOUND_XI;
break;
case 7:
sound = SOUND_DO;
break;
}
Beep(sound, sound_list[i].time);
Sleep(sound_list[i].time);
}
}
int main(int argc, char* argv[])
{
initgraph(840, 480);
IMAGE img_bk;
loadimage(&img_bk, L"./src/bk.png");
putimage(0, 0, &img_bk);
// 没有音乐文件传入
if (argc == 1)
{
Player();
}
else
{
FILE* fp;
if (fopen_s(&fp, argv[1], "rt+") != NULL)
{
throw;
}
// 得到音乐长度
int music_long;
fscanf_s(fp, "%d", &music_long);
// 音乐列表
SOUND* sound_list;
sound_list = new SOUND[music_long];
for (int i = 0; i < music_long; i++)
{
int sound;
int time;
fscanf_s(fp, "%d %d", &sound, &time);
// 终止标志
if (sound == -1)
{
SOUND* new_list;
new_list = new SOUND[i];
// 将先前读取的复制过去
for (int j = 0; j < i; j++)
{
new_list[j] = sound_list[j];
}
free(sound_list);
sound_list = new_list;
music_long = i;
break;
}
sound_list[i].sound_code = sound;
sound_list[i].time = time;
}
Music(sound_list, music_long);
free(sound_list);
sound_list = NULL;
}
closegraph();
return 0;
}