52,MIDI音乐

 我的博客:写写感悟

1,程序,奇数是频率,偶数是时间

比如330hz就是1秒震动330次,但是频率周期需要高低电平各占一半,就是500000微秒,然后除以震动次数330,这样就得到每一次的延时数.通过乘以2每一次for循环只操作数组的偶数.

播放的时间长度是对音调的数组值加1,数组的奇数位用毫秒表示,

用次数乘以时间,数组中的时间单位是毫秒,需要除以1000

比如每秒震动330次,那么750毫秒就是震动了330X750/1000次

科普,简谱怎么看

小练习

784,500,

1046,500,

880,250,

1046,250,

784,500,

659,250,

784,250,

587,250,

659,250,

784,500

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于STM32的MIDI音乐播放器的代码示例: ```C // 定义MIDI消息类型 #define MIDI_NOTE_ON 0x90 #define MIDI_NOTE_OFF 0x80 #define MIDI_PROGRAM_CHANGE 0xC0 // 定义MIDI事件结构体 typedef struct { uint8_t status; uint8_t data1; uint8_t data2; } MidiEvent; // 定义MIDI事件队列 #define MAX_EVENTS 16 MidiEvent midiEvents[MAX_EVENTS]; uint8_t midiEventHead = 0; uint8_t midiEventTail = 0; // 定义MIDI播放器状态 enum { MIDI_STOPPED, MIDI_PLAYING, MIDI_PAUSED }; uint8_t midiState = MIDI_STOPPED; // 定义MIDI处理函数 void handleMidiEvent(MidiEvent event) { switch (event.status & 0xF0) { case MIDI_NOTE_ON: // 处理Note On消息 break; case MIDI_NOTE_OFF: // 处理Note Off消息 break; case MIDI_PROGRAM_CHANGE: // 处理Program Change消息 break; default: // 忽略其他消息 break; } } // 定义MIDI输入回调函数 void handleMidiInput(uint8_t data) { if (midiState != MIDI_PLAYING) { // 如果没有在播放状态,忽略所有输入 return; } // 解析MIDI消息 if ((data & 0x80) == 0x80) { // 如果是状态字节 if (midiEventTail != midiEventHead) { // 如果队列还没满,加入新事件 MidiEvent event = {data, 0, 0}; midiEvents[midiEventTail] = event; midiEventTail = (midiEventTail + 1) % MAX_EVENTS; } } else { // 如果是数据字节 if (midiEventTail != midiEventHead) { // 如果队列不为空,更新最后一个事件的数据字段 MidiEvent *event = &midiEvents[midiEventTail - 1]; if (event->data1 == 0) { event->data1 = data; } else { event->data2 = data; handleMidiEvent(*event); midiEventHead = (midiEventHead + 1) % MAX_EVENTS; } } } } // 初始化MIDI播放器 void initMidiPlayer() { // 初始化MIDI输入 // ... // 初始化MIDI输出 // ... // 设置MIDI播放器状态为停止 midiState = MIDI_STOPPED; } // 开始播放MIDI文件 void playMidiFile() { // 读取MIDI文件 // ... // 解析MIDI文件 // ... // 设置MIDI播放器状态为播放 midiState = MIDI_PLAYING; } // 暂停MIDI播放器 void pauseMidiPlayer() { // 设置MIDI播放器状态为暂停 midiState = MIDI_PAUSED; } // 停止MIDI播放器 void stopMidiPlayer() { // 停止MIDI输出 // ... // 清空MIDI事件队列 midiEventHead = 0; midiEventTail = 0; // 设置MIDI播放器状态为停止 midiState = MIDI_STOPPED; } ``` 这段代码实现了一个简单的MIDI播放器,可以读取MIDI文件并播放其中的音乐。它使用了一个事件队列来缓存输入的MIDI消息,并在播放状态下处理这些消息以产生音乐。在停止或暂停状态下,它会忽略所有输入。你可以根据自己的需要修改这段代码以实现更复杂的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值