文档更新,代码更新

This commit is contained in:
EillesWan 2023-09-24 02:14:04 +08:00
parent 7c078be0cf
commit 732dd0453d
8 changed files with 218 additions and 235 deletions

View File

@ -3,7 +3,7 @@
<h3 align="center">一个免费开源的《我的世界》数字音频转换器</h3> <h3 align="center">一个免费开源的《我的世界》数字音频转换器</h3>
<p align="center"> <p align="center">
<img src="https://forthebadge.com/images/badges/built-with-love.svg"> <img src="https://img.shields.io/badge/BUILD%20WITH%20LOVE-FF3432?style=for-the-badge">
<p> <p>
@ -15,65 +15,42 @@
[![][release]](../../releases) [![][release]](../../releases)
简体中文 | [English](README_EN.md) <!-- 简体中文 | [English](README_EN.md) -->
## 软件介绍🚀 ## 软件介绍🚀
伶伦 是一款免费开源的 **《我的世界》** 数字音频工作站 **伶伦** 是一款免费开源的 **《我的世界》** 数字音频工作站
伶伦转换器 是仅用于 **《我的世界》** 数字音频转换的工具 **伶伦转换器** 是仅用于 **《我的世界》** 数字音频转换的工具
欢迎加群:[861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr) 欢迎加群:[861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)
## 软件架构🏢 ## 教程📕
暂无 [转换器的使用与安装](./docs/功能使用说明.md)
## 使用教程📕 [对于小白的答疑指南](./docs/新手答疑指南.md)
暂无 [对于本软件部分疑问的一些解答](./docs/问与答.md)
### 安装教程 [生成文件的使用](https://gitee.com/TriM-Organization/Musicreater/blob/master/docs/%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md)
暂无
[转换库的代码文档](https://gitee.com/TriM-Organization/Musicreater/blob/master/docs/%E5%BA%93%E7%9A%84%E7%94%9F%E6%88%90%E4%B8%8E%E5%8A%9F%E8%83%BD%E6%96%87%E6%A1%A3.md)
[转换乐器对照参考表](https://gitee.com/TriM-Organization/Musicreater/blob/master/docs/%E8%BD%AC%E6%8D%A2%E4%B9%90%E5%99%A8%E5%AF%B9%E7%85%A7%E8%A1%A8.md)
## 致谢列表🙏 ## 致谢列表🙏
> 感谢广大群友为此程序提供的测试等支持 > 感谢广大群友为此库提供的测试和建议等
> >
> 若您对我们有所贡献但您的名字没有显示在此列表中,请联系我 > 若您对我们有所贡献但您的名字没有出现在此列表中,请联系我们
## 联系我们📞 ## 联系我们📞
QQ群 [861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr) QQ群 [861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)
## 待办事项⏲ 电邮 [TriM-Organization@hotmail.com](mailto:TriM-Organization@hotmail.com)
* - [ ] 支持自动安装
* - [ ] 支持多语言
* - [ ] 支持音乐编辑
* - [ ] 窗口优化
* - [ ] 1.支持插件功能
* - [ ] 2.进度条
* - [ ] 3.可以将音乐写入音符盒(红乐)
* - [ ] 4.修改UI界面使之适应当前功能
* - [ ] 5.支持自动给音符盒绑定更多的音色
* - [ ] 6.可以由.schematic文件导入地图亦可反向处理
* - [ ] 7.制作软件下载器使用户更直观地操作
* - [ ] 8.支持自定义创建websocket服务器播放音乐
* - [ ] 9.支持使用红石播放音乐
* - [ ] 10.支持采用延时的播放器
* - [ ] 11.支持使用bdx导出结构
* - [ ] 12.支持采用tp的方法播放
* - [ ] 13.支持识别曲谱(简谱)图片解析音乐
* - [ ] 14.支持使用瀑布流的方式播放音乐
* - [ ] 15.支持读入Everyone Piano的曲谱文件.eop
* - [ ] 16.支持读入Musescore的通用曲谱文件即musicXML.mscz、.mscx
* - [ ] 17.支持自动搜寻地图目录位置(网易&微软)
* - [ ] 18.支持读入JPword曲谱文件.jpd
* - [ ] 19.新的UI设计以及UI主题文件
* - [ ] 20.以小节为单位做音符播放时间对标
[Bilibili: 凌云金羿]: https://img.shields.io/badge/Bilibili-%E5%87%8C%E4%BA%91%E9%87%91%E7%BE%BF-00A1E7?style=for-the-badge [Bilibili: 凌云金羿]: https://img.shields.io/badge/Bilibili-%E5%87%8C%E4%BA%91%E9%87%91%E7%BE%BF-00A1E7?style=for-the-badge

View File

@ -46,7 +46,7 @@
那么请把看到的如左下图的界面变为右下图吧: 那么请把看到的如左下图的界面变为右下图吧:
<table><tr> <table><tr>
<td><img src="https://foruda.gitee.com/images/1665933104313107707/41108f03_9911226.jpeg"> </td> <td><img src="https://foruda.gitee.com/images/1665933104313107707/41108f03_9911226.jpeg"></td>
<td><img src="https://foruda.gitee.com/images/1665933122534781330/3887a901_9911226.jpeg"></td> <td><img src="https://foruda.gitee.com/images/1665933122534781330/3887a901_9911226.jpeg"></td>
</tr></table> </tr></table>

View File

@ -5,40 +5,44 @@
## 下载与启动教程 ## 下载与启动教程
### [视窗(Windows)操作系统](./download%26start/Windows.md) ### [视窗(Windows)操作系统](./download%26start/Windows.md)
### [里纽克斯(Linux)与其衍生操作系统](./download%26start/Linux.md) ### [林纳克斯(Linux)与其衍生操作系统](./download%26start/Linux.md)
### [安卓(Android)与其衍生操作系统](./download%26start/Android.md) ### [安卓(Android)与其衍生操作系统](./download%26start/Android.md)
## 使用教程 ## 使用教程
1. 参数说明 1. 参数说明
<img src=https://foruda.gitee.com/images/1674146209644269990/26b53aa7_9911226.png> <img src=https://foruda.gitee.com/images/1695492228675012042/2136cbe4_9911226.png>
- midi路径含有mid文件路径、文件名、后缀的完整文件路径或者一个目录magicDemo可接受批量转换)。可以使用相对或绝对路径皆可 - MIDI地址含有mid文件路径、文件名、后缀的完整文件路径或者一个目录可接受批量转换。相对或绝对路径皆可
- 输出路径:输出文件夹的路径,不需要指示文件名 - 输出地址:输出文件夹的路径,不需要指示文件名
- 转换算法通过不同通道隔离音轨识别最佳乐器的算法编号为3金羿的算法将所有的音轨合并通过通道来分组的算法编号为2神羽和金羿的算法旧算法即通过音轨分组的算法编号为1Dislink的算法。新算法在某些方面转换效果更好但是如果新算法转换有误的话请使用旧算法。 - 转换算法**已废弃**通过不同通道隔离音轨识别最佳乐器的算法编号为3金羿的算法将所有的音轨合并通过通道来分组的算法编号为2神羽和金羿的算法旧算法即通过音轨分组的算法编号为1Dislink的算法。新算法在某些方面转换效果更好但是如果新算法转换有误的话请使用旧算法。
- 输出格式:目前的演示程序仅支持`BDX`结构和`MCPACK`包 - 输出文件类型:支持 `BDX` 结构和 `MCPACK` 包,其中,以 `BDX` 结构输出支持延迟和积分两种播放器, `MCPACK` 附加包则比前者多了一种 中继器播放器。
- 播放方式:目前的转换库仅支持**计分板**和**延迟**的两种播放方式,具体地关于这些播放方式如何使用的问题,详见[生成文件的使用说明](./%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md) - 播放器类型:`BDX` 结构仅支持**计分板**和**延迟**的两种播放方式;`MCPACK`则支持**计分板**、**延迟**和**中继器**三种播放方式。具体地关于这些播放方式如何使用的问题,详见[生成文件的使用说明](https://gitee.com/TriM-Organization/Musicreater/blob/master/docs/%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md)
- 音量:小数数据在0~1包含首尾)的范围之内,用以表示播放音量大小。 - 音量大小小数在0(不含)~1包含的范围之内用以表示播放音量大小。
- 速度倍率:小数数据其值不可为0用以表示游戏中播放此音乐的速度倍数。 - 速度倍率:小数其值不可为0用以表示游戏中播放此音乐的速度倍数。
- 进度条:是否启用进度条。目前的转换库已经支持自定义进度条,但是当前的演示程序并不能做到这一点。具体的有关进度条自定义的内容,可以看[功能文档](./%E5%BA%93%E7%9A%84%E7%94%9F%E6%88%90%E4%B8%8E%E5%8A%9F%E8%83%BD%E6%96%87%E6%A1%A3.md#%E8%BF%9B%E5%BA%A6%E6%9D%A1%E8%87%AA%E5%AE%9A%E4%B9%89)中的相关部分自行修改参数 - 进度条:是否启用自动生成进度条
- 计分板名称(仅计分板播放器):游戏内的计分板名称 - 若是,则可选是否自定义进度条
自定义的进度条样式,可以参考[功能文档](https://gitee.com/TriM-Organization/Musicreater/blob/master/docs/%E5%BA%93%E7%9A%84%E7%94%9F%E6%88%90%E4%B8%8E%E5%8A%9F%E8%83%BD%E6%96%87%E6%A1%A3.md#%E8%BF%9B%E5%BA%A6%E6%9D%A1%E8%87%AA%E5%AE%9A%E4%B9%89)
- 计分板名称(仅计分板播放器):游戏内的用以延迟的计分板名称
- 是否重置计分板(仅计分板播放器):歌曲放完是否重置,推荐选择自动重置 - 是否重置计分板(仅计分板播放器):歌曲放完是否重置,推荐选择自动重置
- 玩家选择器(仅延迟播放器):包括 `@x` 在内的全部选择器。例:若要选择全部标签为`Holo`的玩家,则需要如此输入:`@a[tag=Holo]` - 玩家选择器(仅延迟播放器):包括 `@x` 在内的全部选择器。例:若要选择全部标签为`Holo`的玩家,则需要如此输入:`@a[tag=Holo]`
- 作者仅BDX结构音乐结构的生成作者 - 作者仅BDX结构结构的生成作者署名
- 指令结构最大高度(仅结构输出):生成音乐结构的最大堆叠高度,可以查看相关[结构部分的开发文档](./%E5%BA%93%E7%9A%84%E7%94%9F%E6%88%90%E4%B8%8E%E5%8A%9F%E8%83%BD%E6%96%87%E6%A1%A3.md#%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84##%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F)了解详细知识 - 指令结构最大高度(`MCPACK`的计分板播放器不含此项):生成音乐结构的最大堆叠高度。对于如何堆叠的问题,可以查看[结构部分的开发文档](https://gitee.com/TriM-Organization/Musicreater/blob/master/docs/%E5%BA%93%E7%9A%84%E7%94%9F%E6%88%90%E4%B8%8E%E5%8A%9F%E8%83%BD%E6%96%87%E6%A1%A3.md#%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F)了解详细内容
- 没有报错且在输出路径下找到对应的文件即为生成成功: - 没有报错且在输出路径下找到对应的文件即为生成成功:

View File

@ -1,24 +1,24 @@
<h1 align="center">伶伦转换器</h1> <h1 align="center">**伶伦转换器**</h1>
# 新手答疑指南 # 新手答疑指南
**考虑到某些用户电脑技术不是特别先进,且对这个项目充满了好奇心,但是又了解的不是很充分,为此,我特别在这里写一份新手指南,以满足各位的好奇心。放心,本文件全程中文。** **考虑到某些用户电脑技术不是特别先进,且对这个项目充满了好奇心,但是又了解的不是很充分,为此,我特别在这里写一份新手指南,以满足各位的好奇心。放心,本文件全程中文。**
## 第一部分 关于音·创的作用 ## 第一部分 关于 **音·创** 的作用
### 1.1 音·创简介 ### 1.1 **音·创** 简介
音·创 Musicreater 是一款免费开源的针对 **《我的世界》** 的midi音乐转换库 **音·创 _Musicreater_** 是一款免费开源的针对 **《我的世界》** 的midi音乐转换库
而能够与人交互,以达到转换功能的,是 音·创 的程序实现:伶伦转换器。 而能够与人交互,以达到转换功能的,是 **音·创** 的程序实现:**伶伦转换器**
伶伦转换器 目前已经具备较为完善的[**教程**](./%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md),其中包括了下载安装一类,使你能够方便地进行转换。 **伶伦转换器** 目前已经具备较为完善的[**教程**](./%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md),其中包括了下载安装一类,使你能够方便地进行转换。
伶伦转换器也是免费开源的,采用**带有特殊条款的Apache2.0**开源协议授权,详情请见[协议](../LICENSE.md)。 **伶伦转换器**也是免费开源的,采用**带有特殊条款的Apache2.0**开源协议授权,详情请见[协议](../LICENSE.md)。
另外的伶伦转换器并不是伶伦的主要开发方向其功能也并非是伶伦本体伶伦DAW所提供的主要功能。**从音·创到伶伦的开发,其目的是为了方便《我的世界》的音乐作者,进行《我的世界》相关音乐的开发与创作**而并不是转换MIDI文件音·创的实现是在伶伦DAW之前试行一定的技术探索,以更好地开发数字音乐工作站。 另外的,**伶伦转换器**并不是伶伦的主要开发方向,其功能也并非是 **伶伦** 本体伶伦DAW所提供的主要功能。**从 _音·创_ _伶伦_ 的开发,其目的是为了方便 _《我的世界》_ 的音乐作者,进行 _《我的世界》_ 相关音乐的开发与创作**而并不是转换MIDI文件转换器的实现是在数字音频工作站的开发之前进行一定的技术探索,以更好地开发数字音乐工作站。
### 1.2 音·创库版本到底目前有什么功能? ### 1.2 **音·创** 库到底有什么功能?
* - [x] 支持导入`.mid`文件 * - [x] 支持导入`.mid`文件
* - [x] 支持写入`.mcpack`文件 * - [x] 支持写入`.mcpack`文件
* - [x] 支持写入`.bdx`文件 * - [x] 支持写入`.bdx`文件
@ -59,7 +59,7 @@
0. 最简单的方法是向你心仪的作编曲人投递一份申请请求TA将其作编曲过程中的相关工程文件给你这样你就可以获得一首乐曲的电子曲谱从而获得其MIDI文件。 0. 最简单的方法是向你心仪的作编曲人投递一份申请请求TA将其作编曲过程中的相关工程文件给你这样你就可以获得一首乐曲的电子曲谱从而获得其MIDI文件。
1. 如果无法向作曲人申请相关文件的话,成为一个作编曲人也许是一个不错的选择,当然,很多人做不到这一点,但是有必要提到这一点,当你在下面的渠道中都无法获得想要的文件时,你应该考虑是不是需要自己创作内容,或者,请别人帮你创作内容。 1. 如果无法向作曲人申请相关文件的话,成为一个作编曲人也许是一个不错的选择,当然,很多人做不到这一点,但是有必要提到这一点,当你在下面的渠道中都无法获得想要的文件时,你应该考虑是不是需要自己创作内容,或者,请别人帮你创作内容。
2. 当你没有这样的文件时,问问别人或者从群里下载公开的文件也是个思路,不过这个办法通常使用次数有限且能找到的文件不多,不过,值得注意的是,**[音·创开发交流群](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)的群文件中所含的MIDI文件均为网友分享学习交流使用请在下载后一个小时内删除。** 2. 当你没有这样的文件时,问问别人或者从群里下载公开的文件也是个思路,不过这个办法通常使用次数有限且能找到的文件不多,不过,值得注意的是,[**音·创**开发交流群](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)的**群文件中所含的MIDI文件均为网友分享学习交流使用请在下载后一个小时内删除。**
3. 自己找MIDI现在我将给你提供一个完整的找mid的方法请认真学习 3. 自己找MIDI现在我将给你提供一个完整的找mid的方法请认真学习
**1.** 首先你需要在[MidiShow](www.midishow.com)网站中注册一个账号并不复杂你可能只需要一个QQ号便可以授权登录。 **1.** 首先你需要在[MidiShow](www.midishow.com)网站中注册一个账号并不复杂你可能只需要一个QQ号便可以授权登录。
@ -125,7 +125,7 @@
如果你是使用桌面平台游玩基岩版,像我一样,是可以直接打开这个文件、并将这个包导入我的世界的。当然,移动平台也很简单,在游戏资源包界面有导入本地资源包的选项,便可将其导入。 如果你是使用桌面平台游玩基岩版,像我一样,是可以直接打开这个文件、并将这个包导入我的世界的。当然,移动平台也很简单,在游戏资源包界面有导入本地资源包的选项,便可将其导入。
资源包导入世界之后的使用方法,我们也制作了[**简单的教程**](./%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md),如果你对使用导入后的文件有所疑问,可以看看。 资源包导入世界之后的使用方法,我们也制作了[**简单的教程**](https://gitee.com/TriM-Organization/Musicreater/blob/master/docs/%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md),如果你对使用导入后的文件有所疑问,可以看看。
#### 2.4.2 .bdx是什么 #### 2.4.2 .bdx是什么

View File

@ -1,40 +0,0 @@
<h1 align="center">伶伦转换器</h1>
# 生成文件的使用
*这是本库所生成文件的使用声明,不是使用教程,点击[此处查看使用教程](%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md);若要查看有关文件结构的内容,可以点击[此处](./%E7%94%9F%E6%88%90%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%E8%AF%B4%E6%98%8E.md)*
## 附加包格式
支持的文件后缀:`.MCPACK`
1. 导入附加包
2. 在一个循环方块中输入指令 `function index`
3. 将需要聆听音乐的实体的播放所用计分板设置为 `1`
4. 激活循环方块
5. 若想要暂停播放,可以停止循环指令方块的激活状态
6. 若想要重置某实体的播放,可以将其播放用的计分板重置
> 其中 步骤三 和 步骤四 的顺序可以调换。
## 结构格式
支持的文件后缀:`.MCSTRUCTURE`、`.BDX`
1. 将结构导入世界
- 延迟播放器
2. 将结构生成的第一个指令方块之模式更改为**脉冲**
3. 激活脉冲方块
4. 若欲重置播放,可以停止对此链的激活,例如停止区块加载
5. 此播放器不支持暂停
- 计分板播放器
2. 在所生成的第一个指令方块前,放置一个循环指令方块,其朝向应当对着所生成的第一个方块
3. 在循环指令方块中输入使播放对象的播放用计分板加分的指令,延迟为`0`,每次循环增加`1`分
4. 激活循环方块
5. 若想要暂停播放,可以停止循环指令方块的激活状态
6. 若想要重置某实体的播放,可以将其播放用的计分板重置

View File

@ -4,19 +4,19 @@
## 关于音·创与伶伦转换器 ## 关于音·创与伶伦转换器
1. “伶伦”是什么? 1. “**伶伦**”是什么?
伶伦是一个针对《我的世界》的数字音频工作站,用以创作、编辑《我的世界》风格的曲目。 **伶伦** 是一个针对《我的世界》的数字音频工作站,用以创作、编辑《我的世界》风格的曲目。
2. “伶伦转换器”是什么? 2. “**伶伦转换器**”是什么?
伶伦转换器是一个用于将Midi文件转换至我的世界可读格式的工具。其使用音·创库作为转换工具库其目的旨在方便midi创作者进行简单的音乐转换同时也是音·创库的一个项目实现。 **伶伦转换器** 是一个用于将Midi文件转换至我的世界可读格式的工具。其使用 **音·创** 作为转换工具库其目的旨在方便midi创作者进行简单的音乐转换同时也是 **音·创** 的一个实现。
3. 为什么要将音·创库的功能迁移至伶伦转换器 3. 为什么要将 **音·创** 的功能迁移至 **伶伦转换器**
音·创库作为单独存在的转换工具库,如果每次更新都需要从源码下载更新可能对用户十分的不友好。而且,音·创库的实现本是为了其他程序的调用,而不是一个转换程序。经过一段时间的观察与开发后,我们发现如果是以一种“可以用来转换音乐”的工具出现在大众面前,那么音·创库不仅不能被人理解,反而可能会让人困惑于其的具体功用,因此将伶伦转换器作为音·创库的实现,将独立的转换功能用更加亲用户的形式展现在大众面前,是一个更好的选择。 **音·创** 作为单独存在的转换工具库,如果每次更新都需要从源码下载更新可能对用户十分的不友好。而且,**音·创** 的实现本是为了其他程序的调用,而不是一个转换程序。经过一段时间的观察与开发后,我们发现如果是以一种“可以用来转换音乐”的工具出现在大众面前,那么 **音·创** 不仅不能被人理解,反而可能会让人困惑于其的具体功用,因此将 **伶伦转换器** 作为 **音·创** 库的实现,将独立的转换功能用更加亲用户的形式展现在大众面前,是一个更好的选择。
4. 之前使用的“音·创库版本”的示例程序,现在还能用吗? 4. 之前使用的“**音·创库版本**”的示例程序,现在还能用吗?
仍然可以使用,不过由于不再维护,已有的错误不会自动修复。 仍然可以使用,不过由于不再维护,已有的错误不会自动修复。
@ -30,6 +30,6 @@
详见问1切换你所需要的播放器即可。 详见问1切换你所需要的播放器即可。
4. 转换算法是什么?怎么填?是越新越好吗? 4. **_已废弃_** 转换算法是什么?怎么填?是越新越好吗?
转换算法是音·创库中所需要指定的内容转换的算法都已经开源可以在音·创仓库内找到。目前转换算法1对应的算法是将midi文件中的所有音轨单独提取并逐轨解析。而算法2是将所有音符单独提取出来而后解析各个音符。算法的转换过程的差异可能会导致结果不同但由于算法1已经不在进行主动维护算法2的效果将会比1更好所以建议使用算法2。算法3所对应的是尚在研究的插值算法使用可能导致转换出错。 转换算法是音·创库中所需要指定的内容转换的算法都已经开源可以在音·创仓库内找到。目前转换算法1对应的算法是将midi文件中的所有音轨单独提取并逐轨解析。而算法2是将所有音符单独提取出来而后解析各个音符。算法的转换过程的差异可能会导致结果不同但由于算法1已经不在进行主动维护算法2的效果将会比1更好所以建议使用算法2。算法3所对应的是尚在研究的插值算法使用可能导致转换出错。

View File

@ -14,7 +14,7 @@ Copyright © 2023 EillesWan & TriM Org.
Terms & Conditions: ./Lisense.md Terms & Conditions: ./Lisense.md
""" """
__version__ = "0.0.5" __version__ = "0.0.6"
import datetime import datetime
import os import os
@ -24,15 +24,16 @@ import sys
import Musicreater import Musicreater
from Musicreater.plugin import ConvertConfig from Musicreater.plugin import ConvertConfig
from Musicreater.plugin.bdxfile import to_BDX_file_in_delay, to_BDX_file_in_score from Musicreater.plugin.bdxfile import to_BDX_file_in_delay, to_BDX_file_in_score
from Musicreater.plugin.funcpack import to_function_addon_in_score from Musicreater.plugin.addonpack import (
from Musicreater.plugin.mcstructpack import to_mcstructure_addon_in_delay, to_mcstructure_addon_in_redstone_cd to_addon_pack_in_delay,
to_addon_pack_in_repeater,
to_addon_pack_in_score,
)
from Musicreater.constants import DEFAULT_PROGRESSBAR_STYLE
# from Musicreater.plugin.mcstructure import commands_to_structure, commands_to_redstone_delay_structure # from Musicreater.plugin.mcstructure import commands_to_structure, commands_to_redstone_delay_structure
from utils.io import * from utils.io import *
from languages.lang import languages
print("小贴不妨试试Mid-BDX转换网页在线的多功能Midi转换器")
print("https://dislink.github.io/midi2bdx/")
MainConsole.print( MainConsole.print(
"[#121110 on #F0F2F4] ", "[#121110 on #F0F2F4] ",
@ -44,36 +45,25 @@ osc.project_name = "伶伦转换器"
osc.version = __version__ osc.version = __version__
def go_for_args(
languageChange: str = "ZH-CN", debugMode: str = "False", logfile: str = "True"
):
global currentLang
global logger
currentLang = (
languageChange.upper()
if languageChange.upper() in languages.keys()
else "ZH-CN"
)
osc.isRelease = False if debugMode.lower() in ("true", "1") else True
logger.printing = not osc.isRelease
logger.writing = True if logfile.lower() in ("true", "1") else False
if len(sys.argv) > 0: if len(sys.argv) > 0:
def go_for_args(debugMode: str = "False", logfile: str = "True"):
global logger
osc.isRelease = False if debugMode.lower() in ("true", "1") else True
logger.printing = not osc.isRelease
logger.writing = True if logfile.lower() in ("true", "1") else False
go_for_args(*sys.argv) go_for_args(*sys.argv)
def _(__):
"""
`languages`
"""
return languages[currentLang][__]
# 显示大标题 # 显示大标题
MainConsole.rule(title="[bold #AB70FF]欢迎使用伶伦独立转换器", characters="=", style="#26E2FF") MainConsole.rule(title="[bold #AB70FF]欢迎使用伶伦独立转换器", characters="=", style="#26E2FF")
MainConsole.rule(title="[bold #AB70FF]Welcome to Linglun Converter", characters="-") # MainConsole.rule(title="[bold #AB70FF]Welcome to Linglun Converter", characters="-")
MainConsole.rule(title="[#AB70FF]版本{} | 音·创内核版本{}".format(__version__,Musicreater.__version__), characters="=", style="#26E2FF") MainConsole.rule(
title="[#AB70FF]版本{} | 音·创内核版本{}".format(__version__, Musicreater.__version__),
characters="-",
style="#26E2FF",
)
nowYang = datetime.datetime.now() nowYang = datetime.datetime.now()
@ -99,13 +89,13 @@ else:
justify="center", justify="center",
) )
prt(f"{_('LangChd')}{_(':')}{_(currentLang)}") # prt(f"{_('LangChd')}{_(':')}{_(currentLang)}")
def format_ipt( def format_ipt(
notice: str, notice: str,
fun, fun,
err_note: str = f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}", err_note: str = "输入内容有误,请重新输入。",
*extraArg, *extraArg,
): ):
"""循环输入,以某种格式 """循环输入,以某种格式
@ -126,167 +116,183 @@ def format_ipt(
# 获取midi列表 # 获取midi列表
while True: while True:
midi_path = ipt(f"{_('ChoosePath')}{_(':')}").lower() midi_path = ipt(f"请键入MIDI地址或所在目录地址")
if os.path.exists(midi_path): try:
if os.path.isfile(midi_path): if os.path.exists(midi_path):
midis = (midi_path,) if os.path.isfile(midi_path):
elif os.path.isdir(midi_path): midis = (midi_path,)
midis = tuple( elif os.path.isdir(midi_path):
( midis = (
os.path.join(midi_path, i) os.path.join(midi_path, i)
for i in os.listdir(midi_path) for i in os.listdir(midi_path)
if i.lower().endswith(".mid") or i.lower().endswith(".midi") if i.lower().endswith(".mid") or i.lower().endswith(".midi")
) )
) else:
prt("输入内容有误,请重新输入。")
continue
else: else:
prt(f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}") prt("该地址不存在,或无法访问该地址,请重新输入。")
continue continue
else: except PermissionError:
prt(f"{_('FileNotFound')}{_(',')}{_('Re-Enter')}{_('.')}") prt("无法访问该地址,请检查是否给予程序相关文件的访问权限。")
continue continue
break break
# 获取输出地址 # 获取输出地址
out_path = format_ipt( while True:
f"{_('ChooseOutPath')}{_(':')}", out_path = ipt(f"请键入文件生成输出地址:")
os.path.exists, try:
f"{_('FileNotFound')}{_(',')}{_('Re-Enter')}{_('.')}", if not os.path.exists(out_path):
)[0].lower() prt("该地址不存在,或无法访问该地址,请重新输入。")
continue
except PermissionError:
prt("无法访问该地址,请检查是否给予程序相关文件的访问权限。")
continue
break
# 选择输出格式 # 选择输出格式
def is_in_bdx_mcpack(sth: str): def is_in_bdx_mcpack(sth: str):
if sth.lower() in ("0", "mcpack"): return isin(sth, {1: ("bdx", "1", "币帝查", "币帝·艾克斯"), 0: ("mcpack", "0", "唉姆西·派克")})
return 0
elif sth.lower() in ("1", "bdx"):
return 1
else:
raise ValueError("文件格式字符串啊?")
fileFormat = format_ipt(
f"{_('ChooseFileFormat')}{_(':')}",
is_in_bdx_mcpack,
f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}",
)[1]
def is_in_player(sth: str): def is_in_player(sth: str):
if sth.lower() in ("0", "延迟", "delay"): return isin(
return 0 sth,
elif sth.lower() in ("1", "计分板", "scoreboard"): {
return 1 0: ("delay", "0", "延迟", "帝蕾"),
elif sth.lower() in ('2', "红石", 'redstone'): 1: ("score", "1", "计分板", "积分", "积分板", "计分", "斯阔尔"),
return 2 2: ("repeater", "2", "中继器", "瑞皮特"),
else: },
raise ValueError("播放器字符串啊?") )
playerFormat = format_ipt( output_file_format = format_ipt(
f"{_('ChoosePlayer')}{_(':')}", "请键入输出文件类型 (mcpack/0|bdx/1)",
is_in_player, is_in_bdx_mcpack,
f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}", "输入内容有误,请重新输入。",
)[1] )[1]
if output_file_format == 0:
player_format = format_ipt(
"请选择播放器类型 (延迟/0|计分板/1|中继器/2)",
is_in_player,
"输入内容有误,请重新输入。",
)[1]
else:
player_format = format_ipt(
"请选择播放器类型 (延迟/0|计分板/1)",
is_in_player,
"输入内容有误,请重新输入。",
)[1]
# 真假字符串判断 old_exe_enabled = format_ipt(
def bool_str(sth: str) -> bool: "启用1.19以前的旧版execute指令格式 (否/0|是/1)", bool_str, "输入内容格式错误,应为 是/1/真/t/y 或 否/0/假/f/n"
try: )[1]
return bool(int(sth))
except ValueError:
if str(sth).lower() in ("true", "", ""):
return True
elif str(sth).lower() == ("false", "", "", ""):
return False
else:
raise ValueError("布尔字符串啊?")
if os.path.exists("./demo_config.json"): if os.path.exists("./demo_config.json"):
import json import json
prompts = json.load(open("./demo_config.json", "r", encoding="utf-8")) prompts = json.load(open("./demo_config.json", "r", encoding="utf-8"))
prompts = prompts[:-1] prompts = prompts[:-1]
else: else:
prompts = [] prompts = []
# 提示语 检测函数 错误提示语 # 提示语 检测函数 错误提示语
for args in [ for args in [
( (
f'{_("EnterVolume")}{_(":")}', "音量大小 (0,1]",
float, float_str,
), ),
( (
f'{_("EnterSpeed")}{_(":")}', "速度倍率 (0,+∞)",
float, float_str,
), ),
( (
f'{_("WhetherPgb")}{_(":")}', "自动生成进度条 (否/0|是/1)",
bool_str, bool_str,
), ),
( (
f'{_("EnterSbName")}{_(":")}', "计分板名称:",
str, str,
) )
if playerFormat == 1 if player_format == 1
else ( else (
f'{_("EnterSelecter")}{_(":")}', "受播放玩家的选择器:",
str, str,
), ),
( (
f'{_("WhetherSbReset")}{_(":")}', "自动重置计分板 (否/0|是/1)",
bool_str, bool_str,
) )
if playerFormat == 1 if player_format == 1
else (), else (),
( (
f'{_("EnterAuthor")}{_(":")}', "BDX作者署名",
str, str,
) )
if fileFormat == 1 if output_file_format == 1
else (), else (),
( (
f'{_("EnterMaxHeight")}{_(":")}', "结构生成最大高度 (0,+∞)",
int, int,
) )
if playerFormat == 0 if player_format == 0
else (), else (),
]: ]:
if args: if args:
prompts.append(format_ipt(*args)[1]) prompts.append(
format_ipt(*args, err_note="输入内容格式错误,应符合 {}".format(args[1]))[1]
)
if prompts[2]:
costom_pgb_enabled = format_ipt(
"自定义进度条样式 (否/0|是/1)", bool_str, "输入内容格式错误,应为 是/1/真/t/y 或 否/0/假/f/n"
)[1]
if costom_pgb_enabled:
style = ipt("基本样式组 (回车默认)")
if not style:
style = DEFAULT_PROGRESSBAR_STYLE[0]
yet_part = ipt("未播放样式 (回车默认)")
if not yet_part:
yet_part = DEFAULT_PROGRESSBAR_STYLE[1][1]
done_part = ipt("已播放样式 (回车默认)")
if not done_part:
done_part = DEFAULT_PROGRESSBAR_STYLE[1][0]
if playerFormat == 1: if player_format == 1:
cvt_method = to_function_addon_in_score cvt_method = to_addon_pack_in_score
elif playerFormat == 0: elif player_format == 0:
cvt_method = to_mcstructure_addon_in_delay cvt_method = to_addon_pack_in_delay
elif playerFormat == 2: elif player_format == 2:
cvt_method = to_mcstructure_addon_in_redstone_cd cvt_method = to_addon_pack_in_repeater
for singleMidi in midis: for singleMidi in midis:
prt("\n" f"{_('Dealing')} {singleMidi} {_(':')}") prt("\n" f"正在处理 {singleMidi}")
cvt_mid = Musicreater.MidiConvert.from_midi_file(singleMidi, old_exe_format=False) cvt_mid = Musicreater.MidiConvert.from_midi_file(
cvt_cfg = ConvertConfig(out_path, *prompts[:3]) singleMidi, old_exe_format=old_exe_enabled
)
conversion_result = (( cvt_cfg = ConvertConfig(out_path, *prompts[:2], progressbar=((style, (done_part, yet_part)) if costom_pgb_enabled else True) if prompts[2] else False) # type: ignore
cvt_method(cvt_mid, cvt_cfg, *prompts[3:])
)if fileFormat == 0 conversion_result = (
(cvt_method(cvt_mid, cvt_cfg, *prompts[3:])) # type: ignore
if output_file_format == 0
else ( else (
to_BDX_file_in_score(cvt_mid, cvt_cfg, *prompts[3:]) to_BDX_file_in_score(cvt_mid, cvt_cfg, *prompts[3:])
if playerFormat == 1 if player_format == 1
else to_BDX_file_in_delay(cvt_mid, cvt_cfg, *prompts[3:]) else to_BDX_file_in_delay(cvt_mid, cvt_cfg, *prompts[3:])
)) )
)
prt( prt(
f" {_('CmdLength')}{_(':')}{conversion_result[0]}{_(',')}{_('MaxDelay')}{_(':')}{conversion_result[1]}{f'''{_(',')}{_('PlaceSize')}{_(':')}{conversion_result[2]}{_(',')}{_('LastPos')}{_(':')}{conversion_result[3]}''' if fileFormat == 1 else ''}" f" 指令总长:{conversion_result[0]},播放刻数:{conversion_result[1]}{f''',结构大小:{conversion_result[2]},末点坐标:{conversion_result[3]}''' if output_file_format == 1 else ''}" # type: ignore
) )
exitSth = ipt(_("PressEnterExit")).lower() exitSth = ipt("结束。换行以退出程序。")
if exitSth == "record": if exitSth == "record":
import json import json

View File

@ -178,3 +178,39 @@ def format_ipt(
prt(err_note) prt(err_note)
continue continue
return result, fun_result return result, fun_result
def isin(sth: str, range_list: dict):
sth = sth.lower()
for bool_value, res_list in range_list.items():
if sth in res_list:
return bool_value
raise ValueError
# 真假字符串判断
def bool_str(sth: str):
try:
return bool(float(sth))
except:
if str(sth).lower() in ("true", "", "", 'y', 't'):
return True
elif str(sth).lower() in ("false", "", "", 'f', 'n'):
return False
else:
raise ValueError
def float_str(sth: str):
try:
return float(sth)
except ValueError:
try:
return float(sth.replace("", "1").replace("", "2").replace("", "3").replace("", "4").replace("", "5").replace("", "6").replace("", "7").replace("", "8").replace("", "9").replace("", "0").replace("", "1").replace("",'2').replace("", "3").replace("", "4").replace("", "5").replace("", "6").replace("", "7").replace("", "8").replace("", "9").replace("", "0").replace("", "0").replace("", "1").replace("", "2").replace("", "2").replace("","7").replace("",'.'))
except:
raise ValueError
def int_str(sth: str):
try:
return int(float_str(sth))
except ValueError:
raise ValueError