打开项目 → 工具 → 编译选项 → 切换到 “连接器” 标签页 → 在 “连接器命令行” 输入框中:-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 条评论

  • @ 2025-12-10 19:47:45
    #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;
    }
    
    • @ 2025-11-28 21:26:03
      #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