- 分享
茉莉花
- @ 2025-11-23 20:49:15
打开项目 → 工具 → 编译选项 → 切换到 “连接器” 标签页 → 在 “连接器命令行” 输入框中:-static-libgcc -lwinmm
#include <iostream>
#include <Windows.h>
#include <vector>
#include <stdexcept>
#pragma comment(lib, "winmm.lib")
using namespace std;
// 音符频率枚举(MIDI音高码)
enum Note {
Rest = 0,
// 高音区
H5 = 81, H4 = 79, H3 = 77, H2 = 76, H1 = 73,
// 中音区
M7 = 71, M6 = 69, M5 = 67, M4 = 65, M3 = 64, M2 = 62, M1 = 60,
// 低音区
L7 = 59, L6 = 57, L5 = 55, L4 = 53, L3 = 52, L2 = 50, L1 = 48,
// 倍低音区
LL7 = 47, LL6 = 45, LL5 = 43, LL4 = 41, LL3 = 40, LL2 = 38, LL1 = 36
};
// 演奏参数枚举
enum PlayParam {
SpeedSlow = 500, // 慢速
SpeedNormal = 350, // 中速
SpeedFast = 250, // 快速
RestLong = 700, // 长休止符
RestShort = 175, // 短休止符
EndMarker = 0xFF // 乐曲结束标记
};
// 音乐演奏类
class MusicPlayer {
private:
HMIDIOUT midiHandle;
int currentVolume;
int currentSpeed;
// 初始化MIDI设备
void initMidi() {
MMRESULT result = midiOutOpen(&midiHandle, MIDI_MAPPER, 0, 0, CALLBACK_NULL);
if (result != MMSYSERR_NOERROR) {
throw runtime_error("MIDI设备初始化失败!");
}
// 设置乐器(0x00=钢琴)
midiOutShortMsg(midiHandle, 0xC000);
}
// 关闭MIDI设备
void closeMidi() {
if (midiHandle) {
midiOutReset(midiHandle);
midiOutClose(midiHandle);
midiHandle = NULL;
}
}
public:
// 构造函数
MusicPlayer(int volume = 100, int speed = SpeedNormal)
: currentVolume(volume), currentSpeed(speed), midiHandle(NULL) {
initMidi();
}
// 析构函数
~MusicPlayer() {
closeMidi();
}
// 设置音量(0-127)
void setVolume(int volume) {
if (volume < 0) volume = 0;
if (volume > 127) volume = 127;
currentVolume = volume;
}
// 设置速度(毫秒/拍)
void setSpeed(int speed) {
if (speed < 50) speed = 50;
currentSpeed = speed;
}
// 播放单个音符
void playNote(Note note, int duration) {
if (note == Rest) {
Sleep(duration);
return;
}
// 计算MIDI消息:音量(高字节) + 音高(中字节) + 通道(低字节)
DWORD noteOn = (currentVolume << 16) | (static_cast<int>(note) << 8) | 0x90;
midiOutShortMsg(midiHandle, noteOn);
Sleep(duration);
// 停止音符
DWORD noteOff = (0x00 << 16) | (static_cast<int>(note) << 8) | 0x80;
midiOutShortMsg(midiHandle, noteOff);
}
// 播放乐曲
void playMusic(const vector<int>& musicData) {
for (size_t i = 0; i < musicData.size(); i++) {
int data = musicData[i];
if (data == EndMarker) {
break;
}
else if (data == RestLong) {
Sleep(RestLong);
}
else if (data == RestShort) {
Sleep(RestShort);
}
else if (data == SpeedSlow) {
setSpeed(SpeedSlow);
}
else if (data == SpeedNormal) {
setSpeed(SpeedNormal);
}
else if (data == SpeedFast) {
setSpeed(SpeedFast);
}
else {
// 播放普通音符
playNote(static_cast<Note>(data), currentSpeed);
}
}
}
};
// 《茉莉花》乐曲数据初始化
vector<int> jasmineMusic;
void initJasmineMusic() {
// 第一段
jasmineMusic.push_back(M3); jasmineMusic.push_back(M5); jasmineMusic.push_back(H1); jasmineMusic.push_back(H1);
jasmineMusic.push_back(H1); jasmineMusic.push_back(H2); jasmineMusic.push_back(H1); jasmineMusic.push_back(M6);
jasmineMusic.push_back(M5); jasmineMusic.push_back(M5); jasmineMusic.push_back(M6); jasmineMusic.push_back(M5);
jasmineMusic.push_back(M3); jasmineMusic.push_back(M5); jasmineMusic.push_back(M6); jasmineMusic.push_back(M3);
jasmineMusic.push_back(RestShort);
// 第二段
jasmineMusic.push_back(M2); jasmineMusic.push_back(M3); jasmineMusic.push_back(M5); jasmineMusic.push_back(M5);
jasmineMusic.push_back(M3); jasmineMusic.push_back(M2); jasmineMusic.push_back(M1); jasmineMusic.push_back(M1);
jasmineMusic.push_back(M2); jasmineMusic.push_back(M3); jasmineMusic.push_back(M2); jasmineMusic.push_back(M3);
jasmineMusic.push_back(M5); jasmineMusic.push_back(M3); jasmineMusic.push_back(M1); jasmineMusic.push_back(M1);
jasmineMusic.push_back(RestLong);
// 结束标记
jasmineMusic.push_back(EndMarker);
}
int main() {
initJasmineMusic();
try {
cout << "正在播放《茉莉花》..." << endl;
cout << "音量:100,速度:中速" << endl;
// 创建播放器实例
MusicPlayer player(100, SpeedNormal);
// 播放乐曲
player.playMusic(jasmineMusic);
cout << "\n播放完成!" << endl;
}
catch (const exception& e) {
cerr << "播放失败:" << e.what() << endl;
return 1;
}
return 0;
}
2 条评论
-
-
#include <iostream> #include <Windows.h> #include <vector> #include <stdexcept> #include <algorithm> // 用于数值范围限制 #pragma comment(lib, "winmm.lib") using namespace std; // 音符枚举(MIDI音高值,H=高八度 M=中八度 L=低八度 LL=倍低八度) enum Note { Rest = 0, // 休止符 // 高八度 H1 = 73, H2 = 76, H3 = 77, H4 = 79, H5 = 81, // 中八度(基准) M1 = 60, M2 = 62, M3 = 64, M4 = 65, M5 = 67, M6 = 69, M7 = 71, // 低八度 L1 = 48, L2 = 50, L3 = 52, L4 = 53, L5 = 55, L6 = 57, L7 = 59, // 倍低八度 LL1 = 36, LL2 = 38, LL3 = 40, LL4 = 41, LL5 = 43, LL6 = 45, LL7 = 47 }; // 播放参数枚举(时长/速度,单位:毫秒) enum PlayParam { SpeedSlow = 500, // 慢速 SpeedNormal = 350, // 正常速度 SpeedFast = 250, // 快速 RestShort = 175, // 短休止(半拍) RestLong = 700, // 长休止(两拍) EndMarker = 0xFF // 乐曲结束标记 }; // 音乐演奏类(封装MIDI操作,保证资源安全) class MusicPlayer { private: HMIDIOUT midiHandle = NULL; // MIDI输出句柄 int currentVolume = 100; // 音量(0-127) int currentSpeed = SpeedNormal; // 当前速度(毫秒/拍) // 初始化MIDI设备(私有方法,仅构造函数调用) void initMidi() { MMRESULT result = midiOutOpen(&midiHandle, MIDI_MAPPER, 0, 0, CALLBACK_NULL); if (result != MMSYSERR_NOERROR) { throw runtime_error("MIDI设备初始化失败!错误码:" + to_string(result)); } // 设置乐器:0xC0(程序变更) + 通道0 + 乐器编号0(钢琴) midiOutShortMsg(midiHandle, 0xC00000); // 设置初始音量(控制器7,通道0) setVolume(currentVolume); } // 关闭MIDI设备(保证资源释放) void closeMidi() { if (midiHandle) { midiOutReset(midiHandle); // 停止所有播放中的音符 midiOutClose(midiHandle); midiHandle = NULL; } } public: // 构造函数(初始化MIDI,设置默认音量和速度) MusicPlayer(int volume = 100, int speed = SpeedNormal) { currentVolume = clamp(volume, 0, 127); // 限制音量范围 currentSpeed = max(speed, 50); // 速度不低于50ms initMidi(); } // 析构函数(自动释放MIDI资源) ~MusicPlayer() { closeMidi(); } // 禁用拷贝构造和赋值(避免MIDI句柄重复释放) MusicPlayer(const MusicPlayer&) = delete; MusicPlayer& operator=(const MusicPlayer&) = delete; // 设置音量(0-127,超出范围自动修正) void setVolume(int volume) { currentVolume = clamp(volume, 0, 127); // MIDI控制器消息:0xB0(控制器) + 控制器7(音量) + 音量值 + 通道0 DWORD volMsg = (currentVolume << 8) | 0xB007; midiOutShortMsg(midiHandle, volMsg); } // 设置播放速度(最小50ms/拍) void setSpeed(int speed) { currentSpeed = max(speed, 50); } // 播放单个音符(内部调用,处理音符开关) void playNote(Note note, int duration) { if (note == Rest) { // 休止符直接等待 Sleep(duration); return; } // 音符开启消息:0x90(音符开) + 音高 + 音量 + 通道0 DWORD noteOn = (currentVolume << 16) | (static_cast<int>(note) << 8) | 0x90; midiOutShortMsg(midiHandle, noteOn); // 保持音符时长 Sleep(duration); // 音符关闭消息:0x80(音符关) + 音高 + 0(音量) + 通道0 DWORD noteOff = (0 << 16) | (static_cast<int>(note) << 8) | 0x80; midiOutShortMsg(midiHandle, noteOff); } // 播放完整乐曲(解析音符序列) void playMusic(const vector<int>& musicData) { for (int data : musicData) { switch (data) { case EndMarker: // 结束标记,终止播放 return; case RestShort: // 短休止 playNote(Rest, RestShort); break; case RestLong: // 长休止 playNote(Rest, RestLong); break; case SpeedSlow: // 设置慢速 setSpeed(SpeedSlow); break; case SpeedNormal: // 设置正常速度 setSpeed(SpeedNormal); break; case SpeedFast: // 设置快速 setSpeed(SpeedFast); break; default: // 普通音符 if (data >= LL1 && data <= H5) { // 校验音符范围 playNote(static_cast<Note>(data), currentSpeed); } else { cerr << "警告:无效音符值 " << data << ",已跳过" << endl; } break; } } } }; vector<int> jasmineMusic; void initJasmineMusic() { // 第一段:好一朵美丽的茉莉花 jasmineMusic = { M3, M5, H1, H1, // 好 一 朵 美 H1, H2, H1, M6, // 丽 的 茉 莉 M5, M5, M6, M5, // 花 好 一 朵 M3, M5, M6, M3, // 美 丽 的 茉 莉 RestShort, // 短休止 // 第二段:芬芳美丽满枝桠 M2, M3, M5, M5, // 花 芬 芳 美 M3, M2, M1, M1, // 丽 满 枝 桠 M2, M3, M2, M3, // 又 香 又 白 M5, M3, M1, M1, // 人 人 夸 RestLong, // 长休止 EndMarker // 乐曲结束 }; } int main() { initJasmineMusic(); try { cout << "开始播放《茉莉花》..." << endl; MusicPlayer player(100, SpeedNormal); player.playMusic(jasmineMusic); cout << "播放完成!" << endl; } catch (const exception& e) { cerr << "播放失败:" << e.what() << endl; return 1; } return 0; } -
#include <iostream> #include <Windows.h> #include <vector> #include <stdexcept> #pragma comment(lib, "winmm.lib") using namespace std; // 音符频率枚举(MIDI音高码) enum Note { Rest = 0, // 高音区 H5 = 81, H4 = 79, H3 = 77, H2 = 76, H1 = 73, // 中音区 M7 = 71, M6 = 69, M5 = 67, M4 = 65, M3 = 64, M2 = 62, M1 = 60, // 低音区 L7 = 59, L6 = 57, L5 = 55, L4 = 53, L3 = 52, L2 = 50, L1 = 48, // 倍低音区 LL7 = 47, LL6 = 45, LL5 = 43, LL4 = 41, LL3 = 40, LL2 = 38, LL1 = 36 }; // 演奏参数枚举 enum PlayParam { SpeedSlow = 500, // 慢速 SpeedNormal = 350, // 中速 SpeedFast = 250, // 快速 RestLong = 700, // 长休止符 RestShort = 175, // 短休止符 EndMarker = 0xFF // 乐曲结束标记 }; // 音乐演奏类 class MusicPlayer { private: HMIDIOUT midiHandle; int currentVolume; int currentSpeed; // 初始化MIDI设备 void initMidi() { MMRESULT result = midiOutOpen(&midiHandle, MIDI_MAPPER, 0, 0, CALLBACK_NULL); if (result != MMSYSERR_NOERROR) { throw runtime_error("MIDI设备初始化失败!"); } // 设置乐器(0x00=钢琴) midiOutShortMsg(midiHandle, 0xC000); } // 关闭MIDI设备 void closeMidi() { if (midiHandle) { midiOutReset(midiHandle); midiOutClose(midiHandle); midiHandle = NULL; } } public: // 构造函数 MusicPlayer(int volume = 100, int speed = SpeedNormal) : currentVolume(volume), currentSpeed(speed), midiHandle(NULL) { initMidi(); } // 析构函数 ~MusicPlayer() { closeMidi(); } // 设置音量(0-127) void setVolume(int volume) { if (volume < 0) volume = 0; if (volume > 127) volume = 127; currentVolume = volume; } // 设置速度(毫秒/拍) void setSpeed(int speed) { if (speed < 50) speed = 50; currentSpeed = speed; } // 播放单个音符 void playNote(Note note, int duration) { if (note == Rest) { Sleep(duration); return; } // 计算MIDI消息:音量(高字节) + 音高(中字节) + 通道(低字节) DWORD noteOn = (currentVolume << 16) | (static_cast<int>(note) << 8) | 0x90; midiOutShortMsg(midiHandle, noteOn); Sleep(duration); // 停止音符 DWORD noteOff = (0x00 << 16) | (static_cast<int>(note) << 8) | 0x80; midiOutShortMsg(midiHandle, noteOff); } // 播放乐曲 void playMusic(const vector<int>& musicData) { for (size_t i = 0; i < musicData.size(); i++) { int data = musicData[i]; if (data == EndMarker) { break; } else if (data == RestLong) { Sleep(RestLong); } else if (data == RestShort) { Sleep(RestShort); } else if (data == SpeedSlow) { setSpeed(SpeedSlow); } else if (data == SpeedNormal) { setSpeed(SpeedNormal); } else if (data == SpeedFast) { setSpeed(SpeedFast); } else { // 播放普通音符 playNote(static_cast<Note>(data), currentSpeed); } } } }; // 《茉莉花》乐曲数据初始化 vector<int> jasmineMusic; void initJasmineMusic() { // 第一段 jasmineMusic.push_back(M3); jasmineMusic.push_back(M5); jasmineMusic.push_back(H1); jasmineMusic.push_back(H1); jasmineMusic.push_back(H1); jasmineMusic.push_back(H2); jasmineMusic.push_back(H1); jasmineMusic.push_back(M6); jasmineMusic.push_back(M5); jasmineMusic.push_back(M5); jasmineMusic.push_back(M6); jasmineMusic.push_back(M5); jasmineMusic.push_back(M3); jasmineMusic.push_back(M5); jasmineMusic.push_back(M6); jasmineMusic.push_back(M3); jasmineMusic.push_back(RestShort); // 第二段 jasmineMusic.push_back(M2); jasmineMusic.push_back(M3); jasmineMusic.push_back(M5); jasmineMusic.push_back(M5); jasmineMusic.push_back(M3); jasmineMusic.push_back(M2); jasmineMusic.push_back(M1); jasmineMusic.push_back(M1); jasmineMusic.push_back(M2); jasmineMusic.push_back(M3); jasmineMusic.push_back(M2); jasmineMusic.push_back(M3); jasmineMusic.push_back(M5); jasmineMusic.push_back(M3); jasmineMusic.push_back(M1); jasmineMusic.push_back(M1); jasmineMusic.push_back(RestLong); // 结束标记 jasmineMusic.push_back(EndMarker); } int main() { initJasmineMusic(); try { cout << "正在播放《茉莉花》..." << endl; cout << "音量:100,速度:中速" << endl; // 创建播放器实例 MusicPlayer player(100, SpeedNormal); // 播放乐曲 player.playMusic(jasmineMusic); cout << "\n播放完成!" << endl; } catch (const exception& e) { cerr << "播放失败:" << e.what() << endl; return 1; } return 0; }
- 1