MIDI码深度解析

MIDI 协议即数字音乐接口(Musical Instrument Digital Interface),是电子乐器、合成器等演奏设备之间的一种即时通信协议,用于硬件之间的实时演奏数据传递。如果理解还不够深刻,官方如下解释:

请添加图片描述

常用midi硬件接口如5芯插头串口midi和USB midi设备(usb midi任意一种usb口都行,只要usb枚举成midi设备即可),硬件midi串口接口如下:
请添加图片描述
好了,有了midi硬件,硬件中通信的数据,有个标准,我们叫做midi码,本章将重点介绍midi码如何组成的,解析思路,usb midi 和串口midi之间的封包差异。

相关链接:

MIDIOX

Bus Hound

USB MIDI Devices 1.0 | USB-IF

MIDI 1.0

1.midi码的基本格式

midi码分为状态码和数据码,状态码在字节最高位写1,数据码在字节最高位写0。状态码可以看出当前midi事件的具体用途,数据码当然是具体内容参数了。
请添加图片描述

如下格式,就是一个标准midi码
请添加图片描述

2.midi状态码分类

我们已经知道midi状态码字节最高位写1,那么如何区分是什么类型状态码呢?在【4:6】位用于区分状态码具体内容,注意midi 系统码,0xfn具体的内容功能众多,需要根据不同类型帧分析

//midi码事件类型
#define MIDI_STATUS_NOTE_OFF         0x80
#define MIDI_STATUS_NOTE_ON          0x90
#define MIDI_STATUS_AFTERTOUCH       0xA0
#define MIDI_STATUS_CONTROL_CHANGE   0xB0
#define MIDI_STATUS_PROGRAM_CHANGE   0xC0
#define MIDI_STATUS_CHANNEL_PRESSURE 0xD0
#define MIDI_STATUS_PITCH_WHEEL      0xE0
//#define MIDI_STATUS_SYSTEM          0xF0

//系统码具体类型
/*消息类型为系统消息时,低四位的数据定义*/
#define MIDI_SYSEX_Start                      0xF0   //系统独有的格式
#define MIDI_SYSEX_End                        0xF7

#define MIDI_SYS_MTC_Quarter_Frame_Message	  0xF1   //2
#define MIDI_SYS_Song_Position_Pointer		  0xF2   //3
#define MIDI_SYS_Song_Select				  0xF3   //2
#define MIDI_SYS_Tune_Request				  0xF6   //1                
#define MIDI_SYS_Clock						  0xF8   //1
#define MIDI_SYS_Tick						  0xF9   //1
#define MIDI_SYS_Start						  0xFA   //1
#define MIDI_SYS_Stop						  0xFC   //1
#define MIDI_SYS_Continue					  0xFB   //1
#define MIDI_SYS_ActiveSense				  0xFE   //1
#define MIDI_SYS_Reset						  0xFF   //1

3.midi 通道区分

除去系统码,midi通道在低四位中有效【0:3】
请添加图片描述
16个通道就像16个人!对各个通道的操作就是对各个人的操作,你叫他们干嘛就干嘛,你可以叫某个人唱歌、闭嘴、以钢琴的音色唱歌,以吉他的音色唱歌、声音多大、在别人唱了多久开始唱。在同一时间里可以有多个人发声,系统将同一时间所有人的声音合成一个声音再发出去。

4.midi状态码具体功能(系统码下一章介绍)

  • Note On 开音码(0x9n)

顾名思义,就是让某个音符发音,数据参数1:为值键,或者说是音符,就简单理解成触发某个音源发声;数据参数2:力度,或者说是音量大小。注:力度参数为0时,可当作关音码使用

00165716  KEY  2     90    30    14    1  C  3 Note On  
0016578C  KEY  2     80    30    40    1  C  3 Note Off 
00165B07  KEY  2     90    30    08    1  C  3 Note On  
00165B7E  KEY  2     80    30    40    1  C  3 Note Off 
00165F08  KEY  2     90    30    00    1  C  3 Note Off 
00165F7B  KEY  2     80    30    40    1  C  3 Note Off 

请添加图片描述

  • Note Off 关音码 (0x8n)

关掉某个音符,可直接理解成让某个音源停止发声。
请添加图片描述

注意:开音码和关音码需要成对出现,不能有丢包现象

  • 触后音 (0xAn)

触后音:Key Aftertouch,这个用在钢琴的特殊技法中,大概就是在某个音反复按压过程的一种技巧。数据参数1:值键;数据参数2:力度。具体解释如下官方文档:
请添加图片描述

  • 控制改变 (0xBn)

控制改变:Control Change,所以也被叫做CC码。数据参数1:控制ID;数据参数2:控制参数。CC码用处十分广泛,可以自定义,用于某些特殊功能,比如控制某个音色效果参数,音量,开关等等。

00187E4F  KEY  2     B0    40    00    1  ---  CC: Pedal (Sustain)
00187EE3  KEY  2     B0    40    7F    1  ---  CC: Pedal (Sustain)

请添加图片描述

CC码在midi标准中实际是指定了某些具体ID是用来干什么的,但是随着乐曲效果器发展,后面很多ID都被厂商自定义使用了,如下标准ID指定:
请添加图片描述请添加图片描述

  • 乐器改变 (0xCn)

乐器改变:Program Change 也叫做PC码。数据参数1:改变乐器ID。通常电子乐器中可用于音源改变(如,让电子钢琴发吉他贝斯音色等等),在效果器中可以用于预设切换功能。

00177A4D  KEY  2     C0    00    --    1  ---  PC: Acc. Grand Piano  

请添加图片描述

  • 通道压力 (0xDn)

通道压力:Channel Aftertouch Pressure ,从文章中了解,这玩意儿跟0xAn功能有点类似,处理多个Key的时候可能会调用这个。笔者看到文档有说数据两个字节的,也有说一个字节的,因为常规使用没有遇到过,大家遇到可以回复下(笔者这里比较坚持是一个字节的说法,感觉两个字节的那个Note已经没有啥意义了)
请添加图片描述
请添加图片描述

  • 弯音轮 (0xEn)

弯音轮:pitch wheel ,特殊技法,会发出特殊音色。数据参数两个字节,14bit有效,所以有效参数在0~0x3FFF

001DA6DD  MOX  2     E0    00    44    1  ---  Pitch Bend

请添加图片描述
请添加图片描述

5.midi 系统码具体功能

  • System Exclusive (0xF0 0xF7)

    系统独占码,0xF0开始,0xF7截至,0xF0后第一个字节可以表示制造商ID(也有其他功能),早期MIDI有这么定义

    请添加图片描述

    文档有备注的厂商入下:

    Sequential Circuits 1
    Big Briar 2
    Octave / Plateau 3
    Moog 4
    Passport Designs 5
    Lexicon 6
    Kurzweil 7
    Fender 8
    Gulbransen 9
    Delta Labs 0x0A
    Sound Comp. 0x0B
    General Electro 0x0C
    Techmar 0x0D
    Matthews Research 0x0E
    Oberheim 0x10
    PAIA 0x11
    Simmons 0x12
    DigiDesign 0x13
    Fairlight 0x14
    Peavey 0x1B
    JL Cooper 0x15
    Lowery 0x16
    Lin 0x17
    Emu 0x18
    Bon Tempi 0x20
    S.I.E.L. 0x21
    SyntheAxe 0x23
    Hohner 0x24
    Crumar 0x25
    Solton 0x26
    Jellinghaus Ms 0x27
    CTS 0x28
    PPG 0x29
    Elka 0x2F
    Cheetah 0x36
    Waldorf 0x3E
    Kawai 0x40
    Roland 0x41
    Korg 0x42
    Yamaha 0x43
    Casio 0x44
    Akai 0x45
    

    系统独占码还有如下Master Volume功能(其实用CC码自定义也可以):

    0xF0 SysEx
    0x7F Realtime
    0x7F The SysEx channel. Could be from 0x00 to 0x7F.Here we set it to "disregard channel".
    0x04 Sub-ID -- Device Control
    0x01 Sub-ID2 -- Master Volume
    0xLL Bits 0 to 6 of a 14-bit volume
    0xMM Bits 7 to 13 of a 14-bit volume
    0xF7 End of SysEx
    

    除此之外还有很多很多,具体查阅文档了解

  • MTC Quarter Frame Message (0xF1)
    0013E3B1  MOX  2     F1    30    --   --  ---  MTC Quarter Frame
    

请添加图片描述

  • Song Position Pointer (0xF2)
 00122F9F  MOX  2     F2    00    00   --  ---  Song Position Ptr

请添加图片描述

  • Song Select (0xF3)

请添加图片描述

  • Tune Request (0xF6)

请添加图片描述

  • Tick (0xF9)

需要 start stop continue 配合使用
请添加图片描述

  • MIDI Clock (0XF8)、MIDI Start (0xFA) 、 MIDI Stop (0xFB) 、MIDI Continue (0xFC)

这里放到一起说,因为midi的时钟同步需要这几个midi共同实现:

 TIMESTAMP IN PORT STATUS DATA1 DATA2 CHAN NOTE EVENT               
 00002689  MOX  2     FB    --    --   --  ---  Continue              
 0000268B  MOX  2     F8    --    --   --  ---  Timing Clock          
 000026A4  MOX  2     F8    --    --   --  ---  Timing Clock          
 000026BD  MOX  2     F8    --    --   --  ---  Timing Clock          
 000026D6  MOX  2     F8    --    --   --  ---  Timing Clock          
 000026EF  MOX  2     F8    --    --   --  ---  Timing Clock          
 00002707  MOX  2     F8    --    --   --  ---  Timing Clock          
 00002720  MOX  2     F8    --    --   --  ---  Timing Clock          
 0000273A  MOX  2     F8    --    --   --  ---  Timing Clock          
 00002753  MOX  2     F8    --    --   --  ---  Timing Clock          
 0000276D  MOX  2     F8    --    --   --  ---  Timing Clock          
 00002784  MOX  2     F8    --    --   --  ---  Timing Clock          
 0000279E  MOX  2     F8    --    --   --  ---  Timing Clock          
 000027B7  MOX  2     F8    --    --   --  ---  Timing Clock          
 000027D0  MOX  2     F8    --    --   --  ---  Timing Clock          
 000027E9  MOX  2     F8    --    --   --  ---  Timing Clock          
 00002801  MOX  2     F8    --    --   --  ---  Timing Clock          
 0000281B  MOX  2     F8    --    --   --  ---  Timing Clock          
 00002834  MOX  2     F8    --    --   --  ---  Timing Clock          
 0000284C  MOX  2     F8    --    --   --  ---  Timing Clock          
 00002866  MOX  2     F8    --    --   --  ---  Timing Clock          
 0000287E  MOX  2     F8    --    --   --  ---  Timing Clock          
 00002898  MOX  2     F8    --    --   --  ---  Timing Clock          
 000028B1  MOX  2     F8    --    --   --  ---  Timing Clock          
 000028BE  MOX  2     FC    --    --   --  ---  Stop                  
  • Active Sense (0xFE)

请添加图片描述

  • Reset (0xFF)

请添加图片描述

6.midi 码的简发模式

大概意思就是,如果midi在第一次发送了某个事件类型,那么接下来如果重复发送,可以将事件类型省略(这里吐槽一下,当年因为走马观花没把文档读完,封装代码的时候没有考虑简写模式,导致跟某些乐器不兼容情况)。如下,省略开音码方法:
请添加图片描述

注:关于为什么要简写,应该是但当年midi设备波特率为:31250原因,带宽过小,某些设备需要发送的midi事件过多造成的

7.usb midi中封包要求(参考文档,midi10,usb官网可以下载)

usb midi是块传输设备,但在midi限制下,强制每帧格式为:4Byte,具体如下:
请添加图片描述

这里我们可以知道,midi数据大小可以通过cin码来确定:
请添加图片描述
请添加图片描述

举例如下封包:
请添加图片描述
这里我们通过midiox 和 bus hound软件,看看midi码是如何呈现的:
请添加图片描述

8.usb midi 描述符详细内容 ctrl+midi

//midi ctrl  18
0x09, 0x04, 0x03, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, //ctrl
0x09, 0x24, 0x01, 0x00, 0x01, 0x09, 0x00, 0x01, 0x01, 

//midi 
0x09, 0x04, 0x04, 0x00, 0x02, 0x01, 0x03, 0x00, 0x00,   
0x07, 0x24, 0x01, 0x00, 0x01, 0x41, 0x00, 
0x06, 0x24, 0x02, 0x01, 0x01, 0x00, 
0x06, 0x24, 0x02, 0x02, 0x02, 0x0C, 
0x09, 0x24, 0x03, 0x01, 0x03, 0x01, 0x02, 0x01, 0x00, 
0x09, 0x24, 0x03, 0x02, 0x04, 0x01, 0x01, 0x01, 0x0B, 
0x09, 0x05, 0x04, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 
0x05, 0x25, 0x01, 0x01, 0x01, 
0x09, 0x05, 0x84, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 
0x05, 0x25, 0x01, 0x01, 0x03, 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/358427.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

超强的AI写简历软件

你们在制作简历时,是不是基本只关注两件事:简历模板,还有基本信息的填写。 当你再次坐下来更新你的简历时,可能会发现自己不自觉地选择了那个“看起来最好看的模板”,填写基本信息,却没有深入思考如何使简历…

15EG使用ps点亮mio的led

创建工程模板在hello_world中已经介绍过了,这里直接从配置完zynq 开始 因为要用到ps的GPIO,所以要对ZYNQ进行额外的配置,双击ZYNQ打开配置->打开IO口配置->勾选GPIO0 MIO外设。我们可以在原理图中看到mio的led引脚为MIO24和MIO25&#…

Django模型(四)

一、数据操作初始化 from django.db import models# Create your models here. class Place(models.Model):"""位置信息"""name = models.CharField(max_length=32,verbose_name=地名)address = models.CharField(max_length=64,null=True,verbo…

代码随想录算法训练营29期|day34 任务以及具体任务

第八章 贪心算法 part03 1005.K次取反后最大化的数组和 class Solution {public int largestSumAfterKNegations(int[] nums, int K) {// 将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小nums IntStream.of(nums).boxed().sorted((o1, o2) -> Math.ab…

再学css

盒模型 有两种, IE盒子模型、W3C盒子模型;盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border);区 别: IE的content部分把 border 和 padding计算了进去; 标准盒子模型的模型图 从上图可以看到&#x…

Coremail启动鸿蒙原生应用开发,打造全场景邮件办公新体验

1月18日,华为在深圳举行鸿蒙生态千帆启航仪式,Coremail出席仪式并与华为签署鸿蒙合作协议,宣布正式启动鸿蒙原生应用开发。作为首批拥抱鸿蒙的邮件领域伙伴,Coremail的加入标志着鸿蒙生态版图进一步完善。 Coremail是国内自建邮件…

MIT6.1810/Fall 2022(which was called 6.S081 then) Lab5-7

Lab: Copy-on-Write Fork for xv6 8.4 Copy On Write Fork - MIT6.S081 先理解COW机制 Implement copy-on-write fork 您的任务是在xv6内核中实现写时复制分叉。如果修改后的内核成功地执行了cowtest和usertests -q程序,那么就完成了。 为了帮助您测试实现&#…

【计算机网络】——TCP协议

📑前言 本文主要是【计算机网络】——传输层TCP协议的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是青衿🥇 ☁️博客首页:CSDN主页放风讲故事 🌄每日一句…

获取依赖aar包的两种方式-在android studio里引入 如:glide

背景:我需要获取aar依赖到内网开发,内网几乎代表没网。 一、 如何需要获取依赖aar包 方式一:在官方的github中下载,耗时不建议 要从开发者网站、GitHub 存储库或其他来源获取 ‘com.github.bumptech.glide:glide:4.12.0’ AAR 包&#xff…

下拉框联动 类似于请求第一个框之后,携带参数请求后端接口,渲染第二个下来框

直接上代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>1233</title></head><body><div><!-- <table><tr><td><div class"mdui-col"><input><…

PyTorch][chapter 12][李宏毅深度学习][Semi-supervised Linear Methods-1]

这里面介绍半监督学习里面一些常用的方案&#xff1a; K-means ,HAC, PCA 等 目录&#xff1a; K-means HAC PCA 一 K-means 【预置条件】 N 个样本分成k 个 簇 step1: 初始化簇中心点 (随机从X中抽取k个样本点作为&#xff09; Repeat: For all in X: 根据其到 &…

仿真APP在金属波纹管液压胀形工艺设计中的应用

一、背景介绍 金属波纹管是带有波纹状截面的金属管状零件&#xff0c;在工业中应用广泛。金属波纹管特殊的截面形状使其具备较好的柔韧性&#xff0c;能够在一定范围内伸缩弯曲。这一特性赋予波纹管两大用途&#xff1a;一是作为变形补偿器&#xff0c;可用于补偿管道设备由于…

转盘寿司 - 华为OD统一考试

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 100分 题解&#xff1a; Java / Python / C 题目描述 寿司店周年庆&#xff0c;正在举办优惠活动回馈新老用户。 寿司转盘上总共有 n 盘寿司&#xff0c; prices[i] 是第 i 盘寿司的价格。 如果客户选择了第 i 盘寿…

【论文阅读】Long-Tailed Recognition via Weight Balancing(CVPR2022)附MaxNorm的代码

目录 论文使用方法weight decayMaxNorm 如果使用原来的代码报错的可以看下面这个 论文 问题&#xff1a;真实世界中普遍存在长尾识别问题&#xff0c;朴素训练产生的模型在更高准确率方面偏向于普通类&#xff0c;导致稀有的类别准确率偏低。 key:解决LTR的关键是平衡各方面&a…

网络原理-TCP/IP(1)

应用层 我们之前编写完了基本的java socket, 要知道,我们之前所写的所有代码都在应用层中,都是为了完成某项业务,如翻译等.关于应用层,后面会有专门的讲解,在此处先讲一下基础知识. 应用层对应着应用程序,是程序员打交道最多的一层,调用系统提供的网络api写出的代码都是应用层…

如何安装配置HFS并实现无公网ip远程访问本地电脑共享文件

文章目录 前言1.下载安装cpolar1.1 设置HFS访客1.2 虚拟文件系统 2. 使用cpolar建立一条内网穿透数据隧道2.1 保留隧道2.2 隧道名称2.3 成功使用cpolar创建二级子域名访问本地hfs 总结 前言 在大厂的云存储产品热度下降后&#xff0c;私人的NAS热度快速上升&#xff0c;其中最…

【webrtc】m98 : vs2019 直接构建webrtc及moduletest工程 2

字数有限制,我们继续 【webrtc】m98 : vs2019 直接构建webrtc及unitest工程 1modules_unittests 构建 Build started... 1>------ Build started: Project: modules_unittests, Configuration: GN Win32 ------ 1>ninja: Entering directory `G:\CDN\rtcCli\m98\src\o…

导出Mysql数据库表名和字段并合并成一个word

参考链接&#xff1a; 导出MySQL数据库所有库和字段注释及相关信息为word文档——工具类 java - Apache POI - How to copy tables from one docx to another docx - Stack Overflow 领导让我研究下一个低代码平台的代码&#xff0c;我就想着做一个把数据库字段直接导出来的…

STM32F407移植OpenHarmony笔记4

上一篇写到make menuconfig报错&#xff0c;继续开整。 make menuconfig需要/device/soc/*下面有对应的Kconfig文件。 直接去gitee下载stm32的配置文件拿来参考用。 先提取Kconfig文件&#xff0c;后面再添加其它文件。https://gitee.com/openharmony/device_soc_st/tree/Open…

【React教程】(1) React简介、React核心概念、React初始化

目录 ReactReact 介绍React 特点React 的发展历史React 与 Vue 的对比技术层面开发团队社区Native APP 开发 相关资源链接 EcmaScript 6 补充React 核心概念组件化虚拟 DOM 起步初始化及安装依赖Hello World React React 介绍 React 是一个用于构建用户界面的渐进式 JavaScrip…