diff --git a/README.md b/README.md
index 260e6ca..5837545 100644
--- a/README.md
+++ b/README.md
@@ -33,130 +33,21 @@
诸葛亮与八卦阵 bgArray:我的世界基岩版玩家,喜欢编程和音乐,深圳初一学生。
-## 软件架构🏢
-这是一个简单的Python包
-
-## 使用教程📕
-
-> 0. 安装python3.6+
->
-> 在安装时,一定要勾选Add Python 3.X to PATH,不然就要手动设置!!
->
-> 同时,装完之后记得在cmd中输入:python 试试是否安装成功,
-> python的安装可以去网上随便找一下。
-> 成功安装之后,在cmd中输入python会显示:
->
-> 之类的东西。
-> 1. 安装(下载本程序)git的话,可以使用以下命令:
->
-> `git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git`
->
-> 没有安装git的话,可以下载zip包,解压后进入目录即可。
->
-> 2. 运行(进入目录)
-> 在目录下打开cmd,进入到目录下,执行以下命令:
->
->
-> 回车一下,然后:
->
-> 输入下面的三个指令即可!
->
-> `pip install mido`
->
-> `pip install brotli`
->
-> `pip install openpyxl`
->
-> 3. 开始使用!
-> 在目录下打开cmd(步骤与上面的图片一致,只是执行的代码换了),进入到目录下,执行以下命令:(选择你需要的)
->
-> `python example_convert_bdx.py`
->
-> `python example_convert_mcpack.py`
->
-> 4. 错误补充说明
-> 如果你遇到了以下这种情况
->
-> 那么,请按照这篇文章指引做:
-> https://blog.csdn.net/qq_41179280/article/details/123804948
->
-> 感谢Mono帮我们发现这个问题
->
-> 5. 使用补充说明
->
-> midi路径:含有mid文件路径、文件名、后缀的完整绝对路径
->
-> 输出路径:输出文件夹的路径,就写一个英文.(句号)可以表示生成到当前目录下
-> (意思就是支持相对路径)
->
-> 是否重置计分板:1或0(歌曲放完是否重置,推荐1)
->
-> 是否启用进度条:1或0(看个人需要)
->
-> 计分板名称:游戏内的计分板名称
->
-> 音量:0-1之间的小数(含0,1)正常来说推荐1
->
-> 变速:float数据,一般写1
->
-> 没有报错且在输出路径下找到mcpack或bdx即为生成成功:
->
-
-
-### 对于 进度条自定义 功能的说明
-
-因为我们提供了可以自动转换进度条的功能,因此在这里给出进度条自定义参数的详细解释。
-
-一个进度条,明显地,有**固定部分**和**可变部分**来构成。而可变部分又包括了文字和图形两种(当然,《我的世界》里头的进度条,可变的图形也就是那个“条”了)。这一点你需要了解,因为后文中包含了很多这方面的概念需要你了解。
-
-进度条的自定义功能使用一个字符串来定义自己的样式,其中包含众多**标识符**来表示可变部分。
-
-标识符如下(注意大小写):
-
-| 标识符 | 指定的可变量 |
-|---------|----------------|
-| `%%N` | 乐曲名(即传入的文件名)|
-| `%%s` | 当前计分板值 |
-| `%^s` | 计分板最大值 |
-| `%%t` | 当前播放时间 |
-| `%^t` | 曲目总时长 |
-| `%%%` | 当前进度比率 |
-| `_` | 用以表示进度条占位|
-
-表示进度条占位的 `_` 是用来标识你的进度条的。也就是可变部分的唯一的图形部分。
-
-**样式定义字符串**的样例如下,这也是默认的进度条的样式:
-
-`▶ %%N [ %%s/%^s %%% __________ %%t|%^t]`
-
-这是单独一行的进度条,当然你也可以制作多行的,如果是一行的,输出时所使用的指令便是 `title`,而如果是多行的话,输出就会用 `titleraw` 作为进度条字幕。
-
-哦对了,上面的只不过是样式定义,同时还需要定义的是可变图形的部分,也就是进度条上那个真正的“条”。
-
-对于这个我们就采用了固定参数的方法,对于一个进度条,无非就是“已经播放过的”和“没播放过的”两种形态,所以,使用一个元组来传入这两个参数就是最简单的了。元组的格式也很简单:`(str: 播放过的部分长啥样, str: 没播放过的部分长啥样)` 。例如,我们默认的进度“条”的定义是这样的:
-
-`('§e=§r', '§7=§r')`
-
-综合起来,把这些参数传给函数需要一个参数整合,你猜用的啥?啊对对对,我用的还是元组!
-
-我们的默认定义参数如下:
-
-`(r'▶ %%N [ %%s/%^s %%% __________ %%t|%^t]',('§e=§r', '§7=§r'))`
-
-*对了!为了避免生成错误,请尽量避免使用标识符作为定义样式字符串的其他部分*
## 致谢🙏
-- 感谢 昀梦\ 找出指令生成错误bug并指正
-- 感谢由 Charlie_Ping “查理平” 带来的bdx文件转换参考,
+- 感谢 **昀梦**\ 找出指令生成错误bug并指正
+- 感谢由 **Charlie_Ping “查理平”** 带来的bdx文件转换参考,
以及mid转我的世界乐器参考表格
-- 感谢由 CMA_2401PT 为我们的软件开发进行指导
-- 感谢由 Dislink Sforza \带来的midi音色解析以及转换指令的算法,我们将其加入了我们众多算法之一
-- 感谢 Touch \提供的测试支持
-- 感谢 Mono\反馈安装时的问题
-- 感谢广大群友为此程序提供的测试等支持
-- 若您对我们有所贡献但您的名字没有显示在此列表中,请联系我!
+- 感谢由 **CMA_2401PT** 为我们的软件开发进行指导
+- 感谢由 **Dislink Sforza**\带来的midi音色解析以及转换指令的算法,我们将其改编并应用
+- 感谢 **Touch “偷吃”**\提供的测试支持,并对程序的改进提供了丰富的意见
+- 感谢 **Mono**\反馈安装时的问题
+
+> 感谢广大群友为此程序提供的测试等支持
+>
+> 若您对我们有所贡献但您的名字没有显示在此列表中,请联系我!
## 联系我们📞
@@ -166,7 +57,7 @@
2. 电邮 EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
3. 微信 WYI_DoctorYI
-### 作者\<*诸葛亮与八卦阵*\>(bgArray) 联系方式
+### 作者\<*诸葛亮与八卦阵*\>(bgArray)联系方式
1. QQ 4740437765
diff --git a/README_EN.md b/README_EN.md
index 3617f60..8efc7c8 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -34,103 +34,17 @@ Eilles (金羿):A high school student, individual developer, unfamous Bilibili
bgArray "诸葛亮与八卦阵": Fix bugs, improve code aesthetics, add new functions, change data format, etc.
-### Framework🏢
-
-A simple Python package.
-
-## Instructions📕
-
-> 0. Install Python 3.6+
->
-> During installation, be sure to check "add Python 3.X to path", otherwise it needs to be set manually
->
-> At the same time, after the installation, remember to enter in CMD: "python" to try
->
-> whether the installation is successful.
->
-> Python installation tutorial can be found on the Internet easily.
->
-> 1. Install (download this program)
-> Git, you can use the following commands:
->
-> `git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git`
->
-> If Git is not installed, you can download the zip package from the website. Then decompress it
-> and enter the directory.
->
-> 2. Run (enter directory)
->
-> Open CMD in the directory, enter the directory, and execute the following commands:
->
-> `pip install mido`
->
-> `pip install brotli`
->
-> `pip install openpyxl`
->
-> 3. Start using!
->
-> Open CMD in the directory, enter the directory, and execute the following commands:
->
-> (Choose what you need)
->
-> `python example_convert_bdx.py`
->
-> `python example_convert_mcpack.py`
-
-### Instructions for **Customize Progress Bar**
-
-We have supported the function of making progress bar in *Minecraft*'s music player. And also the method of customize them. So the following instructions are about the parameters of the Progress Bar Customizition.
-
-A Progress Bar, of course, is composed of **changeless** parts and **changable** parts. And the changable parts include texts or *images*(these images are made up of texts, or we can say, character paintings 😁). That is, for *Minecraft*, a changable image in a progress bar is just the "bar" part(which is like a stripe).
-
-We use a string to describe the style of progress bar you need, and it includes many **identifier**s to replace the changable parts.
-
-There are the identifiers:
-
-| Identifier | Changable Part |
-|--------------|------------------------------------------------------|
-| `%%N` | Music name(file name which is imported into program) |
-| `%%s` | Value of scoreboard of now |
-| `%^s` | Max value of scoreboard |
-| `%%t` | Current playback time |
-| `%^t` | Total music time |
-| `%%%` | Current playback progress |
-| `_` | To be replaced by the *Bar* part of the progress bar |
-
-The `_` is a placeholder to identifying the *bar* part, yeah, just the changable image.
-
-This is an example of **style description string**, and this is also the default style of *Musicreater*'s progress bar.
-
-`▶ %%N [ %%s/%^s %%% __________ %%t|%^t]`
-
-This is a progress bar with only one line, but it is possible if you want to give a multiline parameter into the style description string.
-
-But the string above is only for style identification, but we also need to identifying the changable image's image(just what the bar's look).
-
-A "bar", simply, included 2 parts: *Have Been Played* & *Not Been Played*. So we use a tuple to pass the parameter. It's under a simple format: `(str: played, str: not)`. For example, the default parameter is below:
-
-`('§e=§r', '§7=§r')`
-
-So it's time to combine what I said in one parameter now!
-
-This is a default definder parameter:
-
-`('▶ %%N [ %%s/%^s %%% __________ %%t|%^t]',('§e=§r', '§7=§r'))`
-
-*Tip: To avoid errors, please not to use the identifiers as the other part of your style.*
## Thanks🙏
-- Thank [Fuckcraft](https://github.com/fuckcraft) *(“鸣凤鸽子” ,etc)* for the function of Creating the Websocket Server for Minecraft: Bedrock Edition.
- - *!! They have given me the rights to directly copy the lib into Musicreater*
- Thank *昀梦*\ for finding and correcting the bugs in the commands that *Musicreater* Created.
- Thank *Charlie_Ping “查理平”* for bdx convert function, and
the data label that's used to convert the mid's instruments into minecraft's instruments.
- Thank *CMA_2401PT* for BDXWorkShop as the .bdx structure's operation guide.
-- Thank *Miracle Plume “神羽”* \ for the Miracle Plume Bedrock Edition Audio Resource Pack
-- 感谢由 Dislink Sforza \带来的midi转换算法,我们将其加入了我们众多算法之一
-- Thank *Arthur Morgan* for his/her biggest support for the debugging of Musicreater
+- Thank *Dislink Sforza* \ for the algorithm brought to us, his midi analysis algorithm became one of us's best ones
+- Thank *Arthur Morgan*\ for his/her biggest support for the debugging of Musicreater
+- Thank *Touch “偷吃”*\ for support of debugging and testing program and algorithm, as well his/her suggestions to the improvement of our project
+- Thank *Mono*\ for reporting problems while installing
- Thanks for a lot of groupmates who support me and help me to test the program.
- If you have give me some help but u haven't been in the list, please contact me.
@@ -139,8 +53,10 @@ the data label that's used to convert the mid's instruments into minecraft's ins
### Author *Eilles*(金羿)
1. QQ 2647547478
-2. E-mail EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
+2. E-mail EillesWan2006@163.com
+ W-YI_DoctorYI@outlook.com EillesWan@outlook.com
3. WeChat WYI_DoctorYI
+4. Telegram [@EillesWan](https://t.me/EillesWan)
### Author *bgArray*(诸葛亮与八卦阵)
diff --git a/demo_convert.py b/demo_convert.py
index cd4039f..3c4ac42 100644
--- a/demo_convert.py
+++ b/demo_convert.py
@@ -86,7 +86,7 @@ while True:
if os.path.isdir(midipath):
for i in os.listdir(midipath):
- if i.endswith('.mid'):
+ if i.lower().endswith('.mid'):
print(f'正在操作{i}')
convertion.convert(midipath + '/' + i, outpath + '/' + i[:-4] )
if outFormat == 0:
diff --git a/demo_convert_bdx_byDelay.py b/demo_convert_bdx_byDelay.py
index d9a209e..a3e1ee1 100644
--- a/demo_convert_bdx_byDelay.py
+++ b/demo_convert_bdx_byDelay.py
@@ -39,21 +39,25 @@ while True:
print('输入错误,请重新输入')
-if os.path.isdir(midipath):
- for i in os.listdir(midipath):
- if i.endswith('.mid'):
- print(f'正在操作{i}')
- convertion.convert(midipath + '/' + i, outpath)
- convertion.toBDXfile_withDelay(
- 1,
- authorname if authorname != '' else input('请输入作者:'),
- isProgress if isProgress != '' else bool(int(input('是否开启进度条(1|0):'))),
- heightmax if heightmax != '' else int(input('请输入指令结构最大生成高度:')),
- volume if volume != '' else float(input('请输入音量(0-1]:')),
- speed if speed != '' else float(input('请输入速度倍率:')),
- player if player != '' else input('请输入玩家选择器:'),
- )
+def operation(i,):
+ print(f'正在操作{i}')
+ convertion.convert(midipath + '/' + i, outpath)
+ convertion.toBDXfile_withDelay(
+ 1,
+ authorname if authorname != '' else input('请输入作者:'),
+ isProgress if isProgress != '' else bool(int(input('是否开启进度条(1|0):'))),
+ heightmax if heightmax != '' else int(input('请输入指令结构最大生成高度:')),
+ volume if volume != '' else float(input('请输入音量(0-1]:')),
+ speed if speed != '' else float(input('请输入速度倍率:')),
+ player if player != '' else input('请输入玩家选择器:'),
+ )
+
+if os.path.isdir(midipath):
+ import threading
+ for i in os.listdir(midipath):
+ if i.lower().endswith('.mid'):
+ threading.Thread(target=operation,args=(i,)).start()
else:
convertion.convert(midipath, outpath)
convertion.toBDXfile_withDelay(
diff --git a/docs/Use of Funtions.md b/docs/Use of Funtions.md
new file mode 100644
index 0000000..ded6dfc
--- /dev/null
+++ b/docs/Use of Funtions.md
@@ -0,0 +1,88 @@
+音·创 Musicreater
+
+
+
+
+
+
+## Instructions📕
+
+> 0. Install Python 3.6+
+>
+> While installing, be sure to check "add Python 3.X to path", otherwise it needs to be set manually
+>
+> After the installation, remember to enter in CMD: "python" to try
+>
+> whether the installation is successful.
+>
+> Python installation tutorial can be found on the Internet easily.
+>
+> 1. Install (download this program)
+> Git, you can use the following commands:
+>
+> `git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git`
+>
+> If Git is not installed, you can download the zip package from the website. Then decompress it
+> and enter the directory.
+>
+> 2. Run (enter directory)
+>
+> Open CMD in the directory, enter the directory, and execute the following commands:
+>
+> `pip install mido`
+>
+> `pip install brotli`
+>
+> `pip install openpyxl`
+>
+> 3. Start using!
+>
+> Open CMD in the directory, enter the directory, and execute the following commands:
+>
+> (Choose what you need)
+>
+> `python example_convert_bdx.py`
+>
+> `python example_convert_mcpack.py`
+
+### Instructions for **Customize Progress Bar**
+
+We have supported the function of making progress bar in *Minecraft*'s music player. And also the method of customize them. So the following instructions are about the parameters of the Progress Bar Customizition.
+
+A Progress Bar, of course, is composed of **changeless** parts and **changable** parts. And the changable parts include texts or *images*(these images are made up of texts, or we can say, character paintings 😁). That is, for *Minecraft*, a changable image in a progress bar is just the "bar" part(which is like a stripe).
+
+We use a string to describe the style of progress bar you need, and it includes many **identifier**s to replace the changable parts.
+
+There are the identifiers:
+
+| Identifier | Changable Part |
+|--------------|------------------------------------------------------|
+| `%%N` | Music name(file name which is imported into program) |
+| `%%s` | Value of scoreboard of now |
+| `%^s` | Max value of scoreboard |
+| `%%t` | Current playback time |
+| `%^t` | Total music time |
+| `%%%` | Current playback progress |
+| `_` | To be replaced by the *Bar* part of the progress bar |
+
+The `_` is a placeholder to identifying the *bar* part, yeah, just the changable image.
+
+This is an example of **style description string**, and this is also the default style of *Musicreater*'s progress bar.
+
+`▶ %%N [ %%s/%^s %%% __________ %%t|%^t]`
+
+This is a progress bar with only one line, but it is possible if you want to give a multiline parameter into the style description string.
+
+But the string above is only for style identification, but we also need to identifying the changable image's image(just what the bar's look).
+
+A "bar", simply, included 2 parts: *Have Been Played* & *Not Been Played*. So we use a tuple to pass the parameter. It's under a simple format: `(str: played, str: not)`. For example, the default parameter is below:
+
+`('§e=§r', '§7=§r')`
+
+So it's time to combine what I said in one parameter now!
+
+This is a default definder parameter:
+
+`('▶ %%N [ %%s/%^s %%% __________ %%t|%^t]',('§e=§r', '§7=§r'))`
+
+*Tip: To avoid errors, please not to use the identifiers as the other part of your style.*
diff --git a/docs/使用教程.md b/docs/使用教程.md
new file mode 100644
index 0000000..c5c3c69
--- /dev/null
+++ b/docs/使用教程.md
@@ -0,0 +1,117 @@
+音·创 Musicreater
+
+
+
+
+
+
+## 使用教程📕
+
+> 0. 安装python3.6+
+>
+> 在安装时,一定要勾选Add Python 3.X to PATH,不然就要手动设置!!
+>
+> 同时,装完之后记得在cmd中输入:python 试试是否安装成功,
+> python的安装可以去网上随便找一下。
+> 成功安装之后,在cmd中输入python会显示:
+>
+> 之类的东西。
+> 1. 下载本程序
+>
+> git的话,可以使用以下命令:
+>
+> `git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git`
+>
+> 没有安装git的话,可以下载zip包,解压后进入目录即可。
+>
+> 2. 运行(进入目录)
+> 在目录下打开cmd,进入到目录下,执行以下命令:
+>
+>
+> 回车一下,然后:
+>
+> 输入下面的三个指令即可!
+>
+> `pip install mido`
+>
+> `pip install brotli`
+>
+> `pip install openpyxl`
+>
+> 3. 开始使用!
+> 在目录下打开cmd(步骤与上面的图片一致,只是执行的代码换了),进入到目录下,执行以下命令:(选择你需要的)
+>
+> `python example_convert_bdx.py`
+>
+> `python example_convert_mcpack.py`
+>
+> 4. 错误补充说明
+> 如果你遇到了以下这种情况
+>
+> 那么,请按照这篇文章指引做:
+> https://blog.csdn.net/qq_41179280/article/details/123804948
+>
+> 感谢Mono帮我们发现这个问题
+>
+> 5. 使用补充说明
+>
+> midi路径:含有mid文件路径、文件名、后缀的完整绝对路径
+>
+> 输出路径:输出文件夹的路径,就写一个英文.(句号)可以表示生成到当前目录下
+> (意思就是支持相对路径)
+>
+> 是否重置计分板:1或0(歌曲放完是否重置,推荐1)
+>
+> 是否启用进度条:1或0(看个人需要)
+>
+> 计分板名称:游戏内的计分板名称
+>
+> 音量:0-1之间的小数(含0,1)正常来说推荐1
+>
+> 变速:float数据,一般写1
+>
+> 没有报错且在输出路径下找到mcpack或bdx即为生成成功:
+>
+
+
+### 对于 进度条自定义 功能的说明
+
+因为我们提供了可以自动转换进度条的功能,因此在这里给出进度条自定义参数的详细解释。
+
+一个进度条,明显地,有**固定部分**和**可变部分**来构成。而可变部分又包括了文字和图形两种(当然,《我的世界》里头的进度条,可变的图形也就是那个“条”了)。这一点你需要了解,因为后文中包含了很多这方面的概念需要你了解。
+
+进度条的自定义功能使用一个字符串来定义自己的样式,其中包含众多**标识符**来表示可变部分。
+
+标识符如下(注意大小写):
+
+| 标识符 | 指定的可变量 |
+|---------|----------------|
+| `%%N` | 乐曲名(即传入的文件名)|
+| `%%s` | 当前计分板值 |
+| `%^s` | 计分板最大值 |
+| `%%t` | 当前播放时间 |
+| `%^t` | 曲目总时长 |
+| `%%%` | 当前进度比率 |
+| `_` | 用以表示进度条占位|
+
+表示进度条占位的 `_` 是用来标识你的进度条的。也就是可变部分的唯一的图形部分。
+
+**样式定义字符串**的样例如下,这也是默认的进度条的样式:
+
+`▶ %%N [ %%s/%^s %%% __________ %%t|%^t]`
+
+这是单独一行的进度条,当然你也可以制作多行的,如果是一行的,输出时所使用的指令便是 `title`,而如果是多行的话,输出就会用 `titleraw` 作为进度条字幕。
+
+哦对了,上面的只不过是样式定义,同时还需要定义的是可变图形的部分,也就是进度条上那个真正的“条”。
+
+对于这个我们就采用了固定参数的方法,对于一个进度条,无非就是“已经播放过的”和“没播放过的”两种形态,所以,使用一个元组来传入这两个参数就是最简单的了。元组的格式也很简单:`(str: 播放过的部分长啥样, str: 没播放过的部分长啥样)` 。例如,我们默认的进度“条”的定义是这样的:
+
+`('§e=§r', '§7=§r')`
+
+综合起来,把这些参数传给函数需要一个参数整合,你猜用的啥?啊对对对,我用的还是元组!
+
+我们的默认定义参数如下:
+
+`(r'▶ %%N [ %%s/%^s %%% __________ %%t|%^t]',('§e=§r', '§7=§r'))`
+
+*对了!为了避免生成错误,请尽量避免使用标识符作为定义样式字符串的其他部分*
diff --git a/msctPkgver/__init__.py b/msctPkgver/__init__.py
index 4bc583d..a2bef6c 100644
--- a/msctPkgver/__init__.py
+++ b/msctPkgver/__init__.py
@@ -38,5 +38,5 @@ Note! Except for this source file, all the files in this repository and this pro
from .main import *
-print('此转换功能由音·创开发者开发,版权归参与开发的人员共同所有。')
+print('此Midi转换功能由音·创开发者开发,版权归参与开发的人员共同所有。')
print('Copyright © 2022 all the developers of Musicreater')
diff --git a/msctPkgver/main.py b/msctPkgver/main.py
index 3c5fe8f..21098d0 100644
--- a/msctPkgver/main.py
+++ b/msctPkgver/main.py
@@ -463,7 +463,7 @@ class midiConvert:
self, scoreboardname: str = "mscplay", volume: float = 1.0, speed: float = 1.0
) -> list:
"""
- 使用金羿的转换思路,将midi转换为我的世界命令列表
+ 使用金羿的转换思路,将midi转换为我的世界命令列表,使用线性方法调整音量
:param scoreboardname: 我的世界的计分板名称
:param volume: 音量,注意:这里的音量范围为(0,1],如果超出将被处理为正确值,其原理为在距离玩家 (1 / volume -1) 的地方播放音频
:param speed: 速度,注意:这里的速度指的是播放倍率,其原理为在播放音频的时候,每个音符的播放时间除以 speed
@@ -483,6 +483,7 @@ class midiConvert:
ticks = 0
instrumentID = 0
singleTrack = []
+ noteOn = []
for msg in track:
ticks += msg.time
@@ -494,6 +495,33 @@ class midiConvert:
if msg.type == "program_change":
# print("TT")
instrumentID = msg.program
+ if msg.type == 'note_on' and msg.velocity != 0:
+ noteOn.append([msg, msg.note, ticks])
+ elif type_[1] is True:
+ if msg.type == 'note_on' and msg.velocity == 0:
+ for u in noteOn:
+ index = 0
+ if u[1] == msg.note:
+ lastMessage = u[0]
+ lastTick = u[2]
+ break
+ index += 1
+ trackS.append(
+ NoteMessage(
+ msg.channel,
+ msg.note,
+ lastMessage.velocity,
+ lastTick,
+ ticks - lastTick,
+ mid,
+ )
+ )
+ # print(noteOn)
+ # print(index)
+ try:
+ noteOn.pop(index)
+ except IndexError:
+ noteOn.pop(index - 1)
if msg.type == "note_on" and msg.velocity != 0:
nowscore = round(
(ticks * tempo)
diff --git a/noteTmain.py b/noteTmain.py
new file mode 100644
index 0000000..7978304
--- /dev/null
+++ b/noteTmain.py
@@ -0,0 +1,144 @@
+import mido
+
+
+def delete_extra_zero(n: float) -> int or float:
+ """
+ 删除多余的0
+ ————————————————
+ 版权声明:本文为CSDN博主「XerCis」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
+ 原文链接:https://blog.csdn.net/lly1122334/article/details/108770141
+ 删除小数点后多余的0
+ :param n: input
+ :return: output
+ """
+ n = '{:g}'.format(n)
+ n = float(n) if '.' in n else int(n) # 含小数点转float否则int
+ return n
+
+
+def bpm_by_MetaMessage_Set_tempo(tmp: int) -> int or float:
+ """
+ midi文件tempo事件bpm算法。
+ A function that's used to compute the bpm of a midiFile,
+ which algorithm is made up of midiFile's tempo meta message.
+ :param tmp:输入mid的metaMessage中速度tempo值
+ input the tempo value which is in the tempo meta message.
+ :return:bpm
+
+ This algorithm is made by ©bgArray.
+ 算法版权归©诸葛亮与八卦阵所有。
+ """
+ second = tmp / 1000000
+ bpm = delete_extra_zero(60 / second)
+ # debug.dp(bpm)
+ return bpm
+
+
+class NoteMessage:
+ def __init__(self, channel, pitch, velocity, startT, lastT, midi, now_bpm, change_bpm=None):
+ self.channel = channel
+ self.note = pitch
+ self.velocity = velocity
+ self.startTime = startT
+ self.lastTime = lastT
+ self.tempo = now_bpm # 这里要程序实现获取bpm可以参考我的程序
+
+ def mt2gt(mt, tpb_a, bpm_a):
+ return mt / tpb_a / bpm_a * 60
+ self.startTrueTime = mt2gt(self.startTime, midi.ticks_per_beat, self.tempo) # / 20
+ # delete_extra_zero(round_up())
+ if change_bpm is not None:
+ self.lastTrueTime = mt2gt(self.lastTime, midi.ticks_per_beat, change_bpm) # / 20
+ else:
+ self.lastTrueTime = mt2gt(self.lastTime, midi.ticks_per_beat, self.tempo) # / 20
+ # delete_extra_zero(round_up())
+ print((self.startTime * self.tempo) / (midi.ticks_per_beat * 50000))
+
+ def __str__(self):
+ return "noteMessage channel=" + str(self.channel) + " note=" + str(self.note) + " velocity=" + \
+ str(self.velocity) + " startTime=" + str(self.startTime) + " lastTime=" + str(self.lastTime) + \
+ " startTrueTime=" + str(self.startTrueTime) + " lastTrueTime=" + str(self.lastTrueTime)
+
+
+def load(mid: mido.MidiFile):
+
+ type_ = [False, False, False] # note_off / note_on+0 / mixed
+
+ is_tempo = False
+
+ # 预检
+ for i, track in enumerate(mid.tracks):
+ for msg in track:
+ # print(msg)
+ if msg.is_meta is not True:
+ if msg.type == 'note_on' and msg.velocity == 0:
+ type_[1] = True
+ elif msg.type == "note_off":
+ type_[0] = True
+ if msg.is_meta is True and msg.type == "set_tempo":
+ is_tempo = True
+
+ if is_tempo is not True:
+ raise Exception("这个mid没有可供计算时间的tempo事件")
+
+ if type_[0] is True and type_[1] is True:
+ type_[2] = True
+ type_[1] = False
+ type_[0] = False
+ print(type_)
+
+ bpm = 0
+ recent_change_bpm = 0
+ is_change_bpm = False
+ # 实检
+ for i, track in enumerate(mid.tracks):
+ noteOn = []
+ trackS = []
+ ticks = 0
+ for msg in track:
+ print(msg)
+ ticks += msg.time
+ print(ticks)
+ if msg.is_meta is True and msg.type == "set_tempo":
+ recent_change_bpm = bpm
+ bpm = bpm_by_MetaMessage_Set_tempo(msg.tempo)
+ is_change_bpm = True
+ # print((ticks * 92) / (mid.ticks_per_beat * 50000))
+ # MC_tick = delete_extra_zero(round_up(
+ # (ticks * 92) / (mid.ticks_per_beat * 50000)
+ # ))
+ # print(MC_tick)
+ # print(ticks / mid.ticks_per_beat / 92 * 60)
+ if msg.type == 'note_on' and msg.velocity != 0:
+ noteOn.append([msg, msg.note, ticks])
+ if type_[1] is True:
+ if msg.type == 'note_on' and msg.velocity == 0:
+ for u in noteOn:
+ index = 0
+ if u[1] == msg.note:
+ lastMessage = u[0]
+ lastTick = u[2]
+ break
+ index += 1
+ print(lastTick)
+ if is_change_bpm and recent_change_bpm != 0:
+ trackS.append(NoteMessage(msg.channel, msg.note, lastMessage.velocity, lastTick, ticks - lastTick,
+ mid, recent_change_bpm, bpm))
+ is_change_bpm = False
+ else:
+ trackS.append(
+ NoteMessage(msg.channel, msg.note, lastMessage.velocity, lastTick, ticks - lastTick,
+ mid, bpm))
+ # print(noteOn)
+ # print(index)
+ try:
+ noteOn.pop(index)
+ except IndexError:
+ noteOn.pop(index - 1)
+ print(trackS)
+ for j in trackS:
+ print(j)
+
+
+if __name__ == '__main__':
+ load(mido.MidiFile("test.mid"))