mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2026-01-08 12:52:11 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79f99dd7ed | ||
|
|
af21b75b70 | ||
|
|
75df9dc167 | ||
|
|
7edf979aee |
148
.gitignore
vendored
148
.gitignore
vendored
@@ -1,148 +0,0 @@
|
||||
# sth. can't open
|
||||
/msctPkgver/secrets/*.py
|
||||
/msctPkgver/secrets/*.c
|
||||
|
||||
|
||||
# mystuff
|
||||
/.vscode
|
||||
*.mid
|
||||
*.midi
|
||||
|
||||
# Byte-compiled / optimized
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*$py.class
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# Pycharm
|
||||
/.idea
|
||||
88
1.py
88
1.py
@@ -1,88 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file '1.ui'
|
||||
##
|
||||
## Created by: Qt User Interface Compiler version 6.4.1
|
||||
##
|
||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
################################################################################
|
||||
|
||||
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||
QMetaObject, QObject, QPoint, QRect,
|
||||
QSize, QTime, QUrl, Qt)
|
||||
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||
QFont, QFontDatabase, QGradient, QIcon,
|
||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
||||
from PySide6.QtWidgets import (QApplication, QMainWindow, QMenuBar, QSizePolicy,
|
||||
QStatusBar, QTabWidget, QToolButton, QVBoxLayout,
|
||||
QWidget)
|
||||
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
if not MainWindow.objectName():
|
||||
MainWindow.setObjectName(u"MainWindow")
|
||||
MainWindow.resize(800, 600)
|
||||
self.centralwidget = QWidget(MainWindow)
|
||||
self.centralwidget.setObjectName(u"centralwidget")
|
||||
self.verticalLayoutWidget_2 = QWidget(self.centralwidget)
|
||||
self.verticalLayoutWidget_2.setObjectName(u"verticalLayoutWidget_2")
|
||||
self.verticalLayoutWidget_2.setGeometry(QRect(0, 0, 861, 681))
|
||||
self.verticalLayout_2 = QVBoxLayout(self.verticalLayoutWidget_2)
|
||||
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
||||
self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
|
||||
self.tabWidget = QTabWidget(self.verticalLayoutWidget_2)
|
||||
self.tabWidget.setObjectName(u"tabWidget")
|
||||
self.tab = QWidget()
|
||||
self.tab.setObjectName(u"tab")
|
||||
self.toolButton_2 = QToolButton(self.tab)
|
||||
self.toolButton_2.setObjectName(u"toolButton_2")
|
||||
self.toolButton_2.setGeometry(QRect(30, 10, 24, 22))
|
||||
self.tabWidget.addTab(self.tab, "")
|
||||
self.tab_2 = QWidget()
|
||||
self.tab_2.setObjectName(u"tab_2")
|
||||
self.tabWidget.addTab(self.tab_2, "")
|
||||
|
||||
self.verticalLayout_2.addWidget(self.tabWidget)
|
||||
|
||||
MainWindow.setCentralWidget(self.centralwidget)
|
||||
self.menubar = QMenuBar(MainWindow)
|
||||
self.menubar.setObjectName(u"menubar")
|
||||
self.menubar.setGeometry(QRect(0, 0, 800, 26))
|
||||
MainWindow.setMenuBar(self.menubar)
|
||||
self.statusbar = QStatusBar(MainWindow)
|
||||
self.statusbar.setObjectName(u"statusbar")
|
||||
MainWindow.setStatusBar(self.statusbar)
|
||||
|
||||
self.retranslateUi(MainWindow)
|
||||
self.toolButton_2.clicked.connect(self.toolButton_2.click)
|
||||
|
||||
self.tabWidget.setCurrentIndex(0)
|
||||
|
||||
QMetaObject.connectSlotsByName(MainWindow)
|
||||
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, MainWindow):
|
||||
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
|
||||
self.toolButton_2.setText(QCoreApplication.translate("MainWindow", u"...", None))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab),
|
||||
QCoreApplication.translate("MainWindow", u"Tab 1", None))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2),
|
||||
QCoreApplication.translate("MainWindow", u"Tab 2", None))
|
||||
# retranslateUi
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
from PySide6 import QtWidgets
|
||||
|
||||
app = QtWidgets.QApplication(sys.argv) # 创建一个QApplication,也就是你要开发的软件app
|
||||
MainWindow = QtWidgets.QMainWindow() # 创建一个QMainWindow,用来装载你需要的各种组件、控件
|
||||
# MainWindow = QtWidgets.QWidget() # 创建一个QMainWindow,用来装载你需要的各种组件、控件
|
||||
ui = Ui_MainWindow() # ui是你创建的ui类的实例化对象
|
||||
ui.setupUi(MainWindow) # 执行类中的setupUi方法,方法的参数是第二步中创建的QMainWindow
|
||||
MainWindow.show() # 执行QMainWindow的show()方法,显示这个QMainWindow
|
||||
sys.exit(app.exec_()) # 使用exit()或者点击关闭按钮退出QApplication
|
||||
91
1.ui
91
1.ui
@@ -1,91 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="QWidget" name="verticalLayoutWidget_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>861</width>
|
||||
<height>681</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Tab 1</string>
|
||||
</attribute>
|
||||
<widget class="QToolButton" name="toolButton_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>10</y>
|
||||
<width>24</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Tab 2</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>toolButton_2</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>toolButton_2</receiver>
|
||||
<slot>click()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>44</x>
|
||||
<y>76</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>46</x>
|
||||
<y>71</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
BIN
AutoInstaller/MSCT Auto Installer
Executable file
BIN
AutoInstaller/MSCT Auto Installer
Executable file
Binary file not shown.
BIN
AutoInstaller/MSCT Auto Installer.exe
Normal file
BIN
AutoInstaller/MSCT Auto Installer.exe
Normal file
Binary file not shown.
221
AutoInstaller/MSCT Auto Installer.py
Normal file
221
AutoInstaller/MSCT Auto Installer.py
Normal file
@@ -0,0 +1,221 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# W-YI 金羿
|
||||
# QQ 2647547478
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 Team-Ryoun 金羿("Eilles Wan")
|
||||
# 若需转载或借鉴 请附作者
|
||||
|
||||
|
||||
"""
|
||||
音·创自动安装器 (Musicreater Auto Installer)
|
||||
对音·创的自动安装提供支持的独立软件
|
||||
Musicreater Auto Installer (音·创自动安装器)
|
||||
A software that used for installing Musicreater automatically
|
||||
|
||||
Copyright 2022 Team-Ryoun
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开
|
||||
|
||||
|
||||
# 下面为正文
|
||||
|
||||
|
||||
from sys import platform
|
||||
from platform import architecture
|
||||
import urllib.request
|
||||
import zipfile
|
||||
from os import system as srun
|
||||
from os import walk, rename, remove, path, chdir, listdir
|
||||
from shutil import rmtree, move
|
||||
|
||||
|
||||
if platform == "win32":
|
||||
|
||||
nowpath = __file__[: len(__file__) - __file__[len(__file__) :: -1].index('\\')]
|
||||
|
||||
if srun('python -V'):
|
||||
|
||||
print('\033[7m{}\033[0m'.format("正在下载python\nDownloading Python"))
|
||||
|
||||
try:
|
||||
urllib.request.urlretrieve(
|
||||
"https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe"
|
||||
if architecture()[0] == "32bit"
|
||||
else "https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe",
|
||||
"./pythonInstaller.exe",
|
||||
)
|
||||
# urllib.request.urlretrieve("https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe","./pythonInstaller.exe")
|
||||
except Exception as E:
|
||||
input(str(E) + "\n自动下载失败,按下回车取消")
|
||||
exit()
|
||||
|
||||
print('正在安装python\nInstalling Python')
|
||||
|
||||
# open('install.bat','w').write(f'.\\pythonInstaller.exe /passive InstallAllUsers=0 TargetDir="{nowpath}python38" DefaultJustForMeTargetDir="{nowpath}python38" AssociateFiles=0 CompileAll=1 PrependPath=0 Shortcuts=0 Include_doc=0 Include_launcher=0 InstallLauncherAllUsers=0 Include_test=0 Include_tools=0')
|
||||
|
||||
srun(
|
||||
f'.\\pythonInstaller.exe /passive InstallAllUsers=1 AssociateFiles=1 CompileAll=1 PrependPath=1 Shortcuts=1 Include_doc=0 Include_exe=1 Include_pip=1 Include_lib=1 Include_tcltk=1 Include_launcher=1 InstallLauncherAllUsers=1 Include_test=0 Include_tools=0'
|
||||
)
|
||||
|
||||
remove('./pythonInstaller.exe')
|
||||
|
||||
# print('\033[7m{}\033[0m'.format("正在下载pip安装工具\nDownloading get-pip tool"))
|
||||
|
||||
# try:
|
||||
# urllib.request.urlretrieve(
|
||||
# "https://bootstrap.pypa.io/get-pip.py", "./python38/get-pip.py"
|
||||
# )
|
||||
# except Exception as E:
|
||||
# input(str(E) + "\n自动下载失败,按下回车取消")
|
||||
# exit()
|
||||
|
||||
# print('\033[7m{}\033[0m'.format("正在下载pip\nDownloading pip"))
|
||||
|
||||
# chdir('./python38')
|
||||
# srun(r'".\python.exe get-pip.py')
|
||||
|
||||
# print('\033[7m{}\033[0m'.format('正在安装pip\nInstalling pip'))
|
||||
|
||||
# for dire in listdir('./Lib/site-packages/'):
|
||||
# move('./Lib/site-packages/'+dire,'./'+dire)
|
||||
|
||||
# print('\033[7m{}\033[0m'.format("完成!"))
|
||||
|
||||
# chdir('../')
|
||||
|
||||
try:
|
||||
choseurl = int(
|
||||
input(
|
||||
'\033[7m{}\033[0m'.format(
|
||||
"""请选择 音·创 下载源,默认为0
|
||||
Please choose a download source of Musicreater(default 0)
|
||||
[0] 私有服务器<暂无> | Private Server<Haven't been built>
|
||||
[1] Gitee
|
||||
[2] Github\n:"""
|
||||
)
|
||||
)
|
||||
)
|
||||
except Exception as E:
|
||||
print('\033[7m{}\033[0m'.format(str(E) + "\n将使用默认源\nUsing default source"))
|
||||
choseurl = 0
|
||||
|
||||
myurl = ""
|
||||
Giteeurl = "https://gitee.com/EillesWan/Musicreater/repository/blazearchive/master.zip?Expires=1647771436&Signature=%2BkqLHwmvzScCd4cPQDP0LHLpqeZUxOrOv17QpRy%2FTzs%3D"
|
||||
Githuburl = (
|
||||
"https://codeload.github.com/EillesWan/Musicreater/zip/refs/heads/master"
|
||||
)
|
||||
|
||||
url = (
|
||||
myurl
|
||||
if choseurl == 0
|
||||
else Giteeurl
|
||||
if choseurl == 1
|
||||
else Githuburl
|
||||
if choseurl == 2
|
||||
else myurl
|
||||
)
|
||||
|
||||
print('\033[7m{}\033[0m'.format("正在下载音·创\nDownloading Musicreater"))
|
||||
|
||||
try:
|
||||
urllib.request.urlretrieve(url, "./master.zip")
|
||||
except Exception as E:
|
||||
input('\033[0{}\033[0m'.format(str(E) + "\n自动下载失败,按下回车取消"))
|
||||
exit()
|
||||
|
||||
print('\033[7m{}\033[0m'.format("安装音·创\nInstalling Musicreater"))
|
||||
|
||||
zipfile.ZipFile("./master.zip", "r").extractall()
|
||||
|
||||
remove("./master.zip")
|
||||
|
||||
try:
|
||||
rmtree("./Musicreater")
|
||||
except:
|
||||
pass
|
||||
|
||||
rename("./Musicreater-master/", "./Musicreater/")
|
||||
|
||||
elif platform == 'linux':
|
||||
srun("sudo apt-get install python3")
|
||||
srun("sudo apt-get install python3-pip")
|
||||
srun("sudo apt-get install git")
|
||||
try:
|
||||
choseurl = int(
|
||||
input(
|
||||
'\033[0{}\033[0m'.format(
|
||||
"""请选择 音·创 下载源,默认为1
|
||||
Please choose a download source of Musicreater(default 1)
|
||||
[1] Gitee
|
||||
[2] Github\n:"""
|
||||
)
|
||||
)
|
||||
)
|
||||
except Exception as E:
|
||||
print(str(E) + "\n将使用默认源\nUsing default source")
|
||||
choseurl = 1
|
||||
|
||||
url = (
|
||||
"https://gitee.com/EillesWan/Musicreater.git"
|
||||
if choseurl == 1
|
||||
else "https://github.com/EillesWan/Musicreater.git"
|
||||
if choseurl == 2
|
||||
else "https://gitee.com/EillesWan/Musicreater.git"
|
||||
)
|
||||
srun(f"sudo git clone {url}")
|
||||
|
||||
|
||||
print('\033[7m{}\033[0m'.format("编译音·创\nCompiling Musicreater"))
|
||||
|
||||
if platform == "linux":
|
||||
srun("python3 -O -m compileall -b ./Musicreater/")
|
||||
elif platform == "win32":
|
||||
srun("python -O -m compileall -b ./Musicreater/")
|
||||
|
||||
for parent, dirnames, filenames in walk("./Musicreater"):
|
||||
for filename in filenames:
|
||||
if filename[-3:] == ".py":
|
||||
fn = path.join(parent, filename)
|
||||
remove(fn)
|
||||
print(f"删除文件 {fn}")
|
||||
for dirname in dirnames:
|
||||
if dirname == "__pycache__":
|
||||
pn = path.join(parent, dirname)
|
||||
rmtree(pn)
|
||||
print(f"删除目录 {pn}")
|
||||
|
||||
|
||||
print(
|
||||
'\033[7m{}\033[0m'.format(
|
||||
"""您可以开始使用音·创了
|
||||
我们将在后台为您安装各项支持库
|
||||
您可以运行Musicreater文件夹中的Musicreater.pyc文件来运行音·创
|
||||
|
||||
You can use Musicreater now,
|
||||
We will setup the libraries ineed for you in background,
|
||||
You can now open Musicreater.PYC in the directory of ./Musicreater to run Musicreater
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
if platform == "linux":
|
||||
srun("python3 ./Musicreater/补全库.pyc")
|
||||
elif platform == "win32":
|
||||
srun("python ./Musicreater/补全库.pyc")
|
||||
@@ -1,219 +1,192 @@
|
||||
**注意,以下条款或版权声明应当且必须是高于此项目中任何其他声明的**
|
||||
|
||||
1. 音·创的全部开发者享有其完整版权,其开发者可以在任一时刻终止以后音·创源代码开放,若经由其开发者授予特殊权利,则授权对象可以将源代码进行特定的被特殊授权的操作
|
||||
2. 音·创或(及)其代码允许在 Apache2.0 协议的条款与说明下进行非商业使用
|
||||
3. 除部分代码特殊声明外,音·创允许对其或(及)其代码进行商业化使用,但是需要经过音·创主要开发者(诸葛亮与八卦阵、金羿)的一致授权,同时,授权对象在商业化授权的使用过程中必须依照 Apache2.0 协议的条款与说明
|
||||
4. 若存在对于音·创包含的部分代码的特殊开源声明,则此部分代码依照其特定的开源方式授权,但若此部分代码经由此部分代码的主要开发者一致特殊授权后商用,则授权对象在商用时依照此部分的开发者所准许的方式(或条款)进行商用,或默认依照 Apache2.0 协议进行商业化使用
|
||||
5. Apache2.0 协议的英文原文副本可见下文
|
||||
|
||||
> The English Translation of the TERMS AND CONDITIONS above is listed below
|
||||
>
|
||||
> This translated version is for reference only and has no legal effect.
|
||||
>
|
||||
> The version with legal effect is the Chinese version above.
|
||||
|
||||
**Note, The TERMS AND CONDITIONS below should and must be above all others in this project**
|
||||
|
||||
1. *Musicreater* is fully copyrighted by all its developers, the developers have the right to make *Musicreater* close sourced at any time. Operations are permitted under specific terms instructed by its developer(s).
|
||||
2. Non-commercial use of *Musicreater* and(or) its source code is permitted under Apache License 2.0.
|
||||
3. Commercial use of *Musicreater* is permitted under Apache License 2.0 with the unanimous permission of the steering developers of *Musicreater* (*bgArray*诸葛亮与八卦阵 and *Eilles*金羿).
|
||||
4. *Musicreater* is open sourced under priority given:
|
||||
1. License granted by the core developer(s) of a section after negotiation.
|
||||
2. Explicitly stated license.
|
||||
3. Apache 2.0 License.
|
||||
5. A copy of the original Apache Lisence 2.0 can be found below.
|
||||
|
||||
|
||||
```text
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
Copyright 2022 Team-Ryoun 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray")
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
```
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
Copyright 2022 Team-Ryoun 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray")
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
2005
Musicreater.py
Normal file
2005
Musicreater.py
Normal file
File diff suppressed because it is too large
Load Diff
532
PySide6-Pkg.ui
532
PySide6-Pkg.ui
@@ -1,532 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="QWidget" name="verticalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>951</width>
|
||||
<height>611</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabO">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Tab 1</string>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="verticalLayoutWidget_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>881</width>
|
||||
<height>591</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTableWidget" name="tableWidget"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Tab 2</string>
|
||||
</attribute>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>71</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>30</y>
|
||||
<width>281</width>
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="verticalLayoutWidget_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>0</y>
|
||||
<width>271</width>
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="widget_2" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>280</x>
|
||||
<y>30</y>
|
||||
<width>281</width>
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="verticalLayoutWidget_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>0</y>
|
||||
<width>271</width>
|
||||
<height>131</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="widget_3" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>160</y>
|
||||
<width>781</width>
|
||||
<height>191</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="verticalLayoutWidget_5">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>781</width>
|
||||
<height>191</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>默认保存路径:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButton">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>速度倍率</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="horizontalSlider">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="text">
|
||||
<string>音量倍率</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSlider" name="horizontalSlider_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_21">
|
||||
<property name="text">
|
||||
<string>最大指令生成高度</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_16">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_13">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_24">
|
||||
<property name="text">
|
||||
<string>选择器模式</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_3"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_18">
|
||||
<property name="text">
|
||||
<string>计分板名称</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_20">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>玩家选择器</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="textEdit_2">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>bdx作者名称</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox_2">
|
||||
<property name="text">
|
||||
<string>是否启用进度条</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="checkBox">
|
||||
<property name="text">
|
||||
<string>是否自定义进度条</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_22">
|
||||
<property name="text">
|
||||
<string>自定义进度条内容:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="textEdit_3">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_18"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_23">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>选择命令格式版本</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_2">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_14">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_25">
|
||||
<property name="text">
|
||||
<string>选择转换算法版本</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_4"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_15">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_26">
|
||||
<property name="text">
|
||||
<string>选择导出模式</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboBox_5"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>页</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
<attribute name="title">
|
||||
<string>页</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>26</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu">
|
||||
<property name="title">
|
||||
<string>文件</string>
|
||||
</property>
|
||||
<addaction name="action"/>
|
||||
<addaction name="action_Input"/>
|
||||
</widget>
|
||||
<addaction name="menu"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
<action name="action">
|
||||
<property name="icon">
|
||||
<iconset theme="document-open">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>打开 Open</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Input">
|
||||
<property name="text">
|
||||
<string>导入 Input</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
136
README.md
136
README.md
@@ -1,9 +1,7 @@
|
||||
<h1 align="center">音·创 Musicreater</h1>
|
||||
|
||||
<h2 align="center">库版 Package Version</h2>
|
||||
|
||||
<p align="center">
|
||||
<img width="128" height="128" src="https://s1.ax1x.com/2022/05/06/Ouhghj.md.png" >
|
||||
<img width="128" height="128" src="https://s1.ax1x.com/2022/04/01/qhfOPA.png" >
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@@ -19,42 +17,102 @@
|
||||
|
||||
简体中文🇨🇳 | [English🇬🇧](README_EN.md)
|
||||
|
||||
## **嘿伙计,你是不是来错地儿了,这里还在开发,注意选对版本!**
|
||||
|
||||
## 介绍🚀
|
||||
## 软件介绍🚀
|
||||
|
||||
音·创 Musicreater 是一款免费开源的 **《我的世界:基岩版》** 音乐制作软件
|
||||
|
||||
音·创 库版 (Musicreater Package Version) 是一款免费开源的针对 **《我的世界:基岩版》** 的midi音乐转换库
|
||||
|
||||
欢迎加群:[861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)
|
||||
|
||||
**此分支为音·创的包版本,即便于其他软件使用的可被import版本**
|
||||
|
||||
### **看这看这!看这看这!看这看这!教程:[教程链接](./docs/%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md)**
|
||||
**注意注意注意!!!本程序尚在测试与开发阶段,且代码重构未完成,请自行定夺使用。**
|
||||
|
||||
## 软件作者✒
|
||||
|
||||
金羿 Eilles:我的世界基岩版指令师,个人开发者,B站不知名UP主,江西在校高中生。
|
||||
金羿 Eilles:我的世界基岩版指令师,个人开发者,B站不知名UP主,南昌在校高中生。
|
||||
|
||||
诸葛亮与八卦阵 bgArray:我的世界基岩版玩家,喜欢编程和音乐,深圳初二学生。
|
||||
诸葛亮与八卦阵 bgArray:我的世界基岩版玩家,喜欢编程和音乐,深圳初一学生。
|
||||
|
||||
## 软件架构🏢
|
||||
|
||||
软件采用 *Python* 作为第一语言,目前还没有使用其他语言辅助。使用可更换的UI结构库,即开发人员可以通过更换display.py文件随心所欲地切换UI库;后期将支持插件自加载。
|
||||
|
||||
支持 Windows7+ 以及各个支持 Python3.6+ 的 Linux
|
||||
|
||||
***各位开发人员注意!!!多语言支持请使用函数`_`加载文字!!!如需补充,请在简体中文的语言文件(zh-CN.lang)中补充!!!***
|
||||
|
||||
## 使用教程📕
|
||||
|
||||
### 安装教程
|
||||
|
||||
下载[音·创自动安装器](https://gitee.com/EillesWan/Musicreater/releases/v0.2.0.0-Delta),将其放在你希望安装音·创的位置,运行后将自动安装。
|
||||
|
||||
提示:下载源最好选择\"2 GitHub\"。
|
||||
|
||||
### 从源代码运行教程
|
||||
|
||||
#### Windows7+
|
||||
|
||||
0. [Gitee下载(需要登陆)](https://gitee.com/EillesWan/Musicreater)
|
||||
[Github下载(慢)](https://github.com/EillesWan/Musicreater)本程序源代码
|
||||
1. 安装Python 3.8.10
|
||||
[下载64位Python安装包](https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe)
|
||||
[下载32位Python安装包](https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe)
|
||||
2. 以管理员身份运行 补全库.py :
|
||||
- 点击 “开始” 菜单,搜索 `命令提示符`
|
||||
- 右键点击 `命令提示符` 左键点击 “以管理员身份运行”
|
||||
- 将 “补全库.py” 拖拽入开启的窗口,按下回车
|
||||
3. 等待安装完成后,双击运行 Musicreater.py
|
||||
|
||||
#### Linux
|
||||
|
||||
0. 若你没有足够优秀的环境,推荐先在终端敲:
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get upgrade
|
||||
sudo apt-get install python3
|
||||
sudo apt-get install python3-pip
|
||||
sudo apt-get install git
|
||||
```
|
||||
1. 若你足够自信,该整的都整了,就在你想下载此程序的地方打开终端,敲:
|
||||
```bash
|
||||
sudo git clone https://gitee.com/EillesWan/Musicreater.git
|
||||
cd Musicreater
|
||||
python3 补全库.py
|
||||
python3 Musicreater.py
|
||||
```
|
||||
|
||||
### 使用说明
|
||||
|
||||
1. 直接运行就好
|
||||
2. 后期会出详细的使用教程
|
||||
3. 如果在使用过程中发现了bug拜托请上报给我,详见下方联系方式
|
||||
|
||||
## 诸葛亮与八卦阵的关于羽音缭绕资源包应用地说明(不必要)📖
|
||||
|
||||
1. 首先!这里的提示是给想使用多音色资源包的人的,如果你想用就请下载 [神羽资源包(神羽自己的链接)](https://pan.baidu.com/s/11uoq5zwN7c3rX-98DqVpJg)提取码:ek3t
|
||||
2. 下载到你自己电脑上某个位置,可以不放置于本项目下。音色资源包较大,可以选取只下载:
|
||||
`神羽资源包_乐器、音源的资源包\羽音缭绕-midiout_25.0` 这个文件夹,再嫌麻烦的话,也可以只下载其中的:
|
||||
`神羽资源包_乐器\音源的资源包\羽音缭绕-midiout_25.0\mcpack(国际版推荐)格式_25.0` 或者:
|
||||
`神羽资源包_乐器\音源的资源包\羽音缭绕-midiout_25.0\zip格式_25.0`
|
||||
4. 接下来就是关键了:在*音创*中绑定资源包
|
||||
首先,先打开 *音创*->帮助与疑问->\[神羽资源包位置选择\]:选择文件夹... 这时候,会跳出选择框
|
||||
关键来了,选择:***您下载的`羽音缭绕-midiout_25.0`文件夹,或者`mcpack(国际版推荐)格式_25.0`或`zip格式_25.0`的上级目录***
|
||||
举个例子:我的文件路径是这样的:
|
||||
`L:\shenyu\音源的资源包\羽音缭绕-midiout_25.0`这里面有:`神羽资源包_25.0_使用方法.xls`、
|
||||
`mcpack(国际版推荐)格式_25.0`、`zip格式_25.0`两个文件夹和一个.xls文件,而你在音创中
|
||||
也应该选择这个文件夹:**L:\shenyu\音源的资源包\羽音缭绕-midiout_25.0**
|
||||
6. 如果你想使用音色资源包来制作函数,那么解析时你应该用 *音创*->编辑->从midi导入音轨且用新方法解析,
|
||||
然后再使用 *音创*->函数(包)->下面的四个新函数
|
||||
|
||||
## 致谢🙏
|
||||
|
||||
- 感谢 **昀梦**\<QQ1515399885\> 找出指令生成错误bug并指正
|
||||
- 感谢由 **Charlie_Ping “查理平”** 带来的bdx文件转换参考,
|
||||
以及mid转我的世界乐器参考表格
|
||||
- 感谢由 **CMA_2401PT** 为我们的软件开发进行指导
|
||||
- 感谢由 **Dislink Sforza “断联·斯福尔扎”**\<QQ1600515314\>带来的midi音色解析以及转换指令的算法,我们将其改编并应用;同时,感谢他的[网页版转换器](https://dislink.github.io/midi2bdx/)给我们的开发与更新带来巨大的压力和动力,让我们在原本一骑绝尘的摸鱼道路上转向开发
|
||||
- 感谢 **Touch “偷吃”**\<QQ1793537164\>提供的测试支持,并对程序的改进提供了丰富的意见;同时也感谢他的不断尝试新的内容,使我们的排错更进一步
|
||||
- 感谢 **Mono**\<QQ738893087\>反馈安装时的问题
|
||||
- 感谢 **Ammelia** 敦促我们进行新的功能开发,并为新功能提出了非常优秀的大量建议
|
||||
|
||||
> 感谢广大群友为此程序提供的测试等支持
|
||||
>
|
||||
> 若您对我们有所贡献但您的名字没有显示在此列表中,请联系我!
|
||||
1. 感谢由 [Fuckcraft](https://github.com/fuckcraft) “鸣凤鸽子”等 带来的我的世界websocket服务器功能
|
||||
2. 感谢 昀梦\<QQ1515399885\> 找出指令生成错误bug并指正
|
||||
3. 感谢由 Charlie_Ping “查理平” 带来的bdx转换功能
|
||||
4. 感谢由 CMA_2401PT 带来的 BDXWorkShop 供本程序对于bdx操作的指导
|
||||
5. 感谢由 Miracle Plume “神羽” \<QQshenyu40403\>带来的羽音缭绕基岩版音色资源包
|
||||
6. 感谢 Arthur Morgan 对本程序的排错提出了最大的支持
|
||||
7. 感谢广大群友为此程序提供的测试等支持
|
||||
8. 若您对我们有所贡献但您的名字没有显示在此列表中,请联系我!
|
||||
|
||||
## 联系我们📞
|
||||
|
||||
@@ -63,12 +121,36 @@
|
||||
1. QQ 2647547478
|
||||
2. 电邮 EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
3. 微信 WYI_DoctorYI
|
||||
4. Telegram [@EillesWan](https://t.me/EillesWan)
|
||||
|
||||
### 作者\<*诸葛亮与八卦阵*\>(bgArray)联系方式
|
||||
### 作者\<*诸葛亮与八卦阵*\>(bgArray) 联系方式
|
||||
|
||||
1. QQ 4740437765
|
||||
|
||||
## 待办事项
|
||||
|
||||
* - [x] 可以使用由神羽提供的音乐资源包
|
||||
* - [x] 支持多语言
|
||||
* - [x] 支持创建可被Fastbuilder导入的.BDX文件支持
|
||||
* - [ ] 1.可以导出自定义的结构文件用于存储要导入地图中的结构
|
||||
* - [ ] 2.进度条
|
||||
* - [ ] 3.可以将音乐写入音符盒(红乐)
|
||||
* - [ ] 4.修改UI界面使之适应当前功能
|
||||
* - [ ] 5.支持自动给音符盒绑定更多的音色
|
||||
* - [ ] 6.可以由.schematic文件导入地图,亦可反向处理
|
||||
* - [x] 7.制作软件下载器使用户更直观地操作
|
||||
* - [x] 8.支持自定义创建websockeet服务器播放音乐
|
||||
* - [ ] 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
|
||||
|
||||
104
README_EN.md
104
README_EN.md
@@ -1,7 +1,7 @@
|
||||
<h1 align="center">音·创 Musicreater</h1>
|
||||
|
||||
<p align="center">
|
||||
<img width="128" height="128" src="https://s1.ax1x.com/2022/05/06/Ouhghj.md.png" >
|
||||
<img width="128" height="128" src="https://s1.ax1x.com/2022/04/01/qhfOPA.png" >
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@@ -17,18 +17,15 @@
|
||||
|
||||
[简体中文🇨🇳](README.md) | English🇬🇧
|
||||
|
||||
|
||||
**Notice that the language support of *README* may be a little SLOW.**
|
||||
|
||||
## Introduction🚀
|
||||
|
||||
Musicreater(音·创) is a free open source software which is used for making and also creating music in **Minecraft: Bedrock Edition**.
|
||||
|
||||
Musicreater pkgver(Package Version 音·创 库版) is a free open source library used for convert midi file into formats that is suitable for **Minecraft: Bedrock Edition**.
|
||||
Musicreater(音·创) is an free open source software which is used for making and also creating music in **Minecraft: Bedrock Edition**.
|
||||
|
||||
Welcome to join our QQ group: [861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)
|
||||
|
||||
### **SEEEEEEEEE Tutorials [HERE](./docs/Use%20of%20Funtions.md)**
|
||||
**ATTENTION!** This software is under testing and developing, there is still a lot of bugs needed to be fixed. Please use it wisely.
|
||||
|
||||
### Authors✒
|
||||
|
||||
@@ -36,29 +33,96 @@ Eilles (金羿):A high school student, individual developer, unfamous Bilibili
|
||||
|
||||
bgArray "诸葛亮与八卦阵": Fix bugs, improve code aesthetics, add new functions, change data format, etc.
|
||||
|
||||
### Framework🏢
|
||||
|
||||
Developed under *Python3.8 3.9*. However, theoretically support Python3.6+.
|
||||
|
||||
Support Windows7+ && Linux (that supports Python3.6+)
|
||||
|
||||
***ATTENTION TO DEVELOPERS!!! TO SUPPORT DIFFERENT LANGUAGES, PLEASE USE FUNCTION(METHOD) `_` TO LOAD TEXTs!!! IF YOU NEED TO SUPPLEMENT, PLEASE ADD THEM IN SIMPLEFIED CHINESE\'S LANGUAGE FILE(zh-CN.lang), WHEATHER WHAT LANGUAGE YOU USE!!!***
|
||||
|
||||
## Instructions📕
|
||||
|
||||
### Installation
|
||||
|
||||
Download the *[MSCT Auto Installer](https://github.com/EillesWan/Musicreater/releases/tag/v0.2.0.0-Delta)*, put it in a directory that you want to install *Musicreater* into. Then run the auto installer and it will help you to install the *Musicreator* as well as Python3.8(if you haven\'t install it)
|
||||
|
||||
Tips: You'd better choose the \"2 GitHub\" download source
|
||||
|
||||
### Run with Source Code
|
||||
|
||||
#### Windows7+
|
||||
|
||||
0. First, download the source code pack of Musicreater.
|
||||
[Download from Gitee (Need to Login)](https://gitee.com/EillesWan/Musicreater/repository/archive/master.zip)
|
||||
[Download from Github](https://github.com/EillesWan/Musicreater/archive/refs/heads/master.zip)
|
||||
1. Install Python 3.8.10
|
||||
[Download the 64-bit Python Installer](https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe)
|
||||
[Download the 32-bit Python Installer](https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe)
|
||||
2. After completing installation, we need to install the libraries :
|
||||
- Open "Start Menu" and find `cmd`
|
||||
- Run `cmd` as Administrator
|
||||
- Drag "补全库.py" into the opened window and press Enter
|
||||
3. After completing installation,double click Musicreater.py to run
|
||||
|
||||
#### Linux
|
||||
|
||||
0. If you 're not sure whether your environment is good enough, please run these commands on Terminal
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get upgrade
|
||||
sudo apt-get install python3
|
||||
sudo apt-get install python3-pip
|
||||
sudo apt-get install git
|
||||
```
|
||||
1. Now if you are confident enough about your runtime environment, open Terminal on the place which you want to download Musicreater, and run these
|
||||
```bash
|
||||
sudo git clone https://gitee.com/EillesWan/Musicreater.git
|
||||
cd Musicreater
|
||||
python3 补全库.py
|
||||
python3 Musicreater.py
|
||||
```
|
||||
|
||||
### Instructions of Using
|
||||
|
||||
1. Just run Musicreater.pyc(or .py) if you have installed well
|
||||
2. Detailed instructions is coming soon
|
||||
3. If you find a bug, could you please report it to me? My contact info is right below.
|
||||
|
||||
## Explanation of the use of *PlumeAudioSurrounding Resource Pack* by bgArray (unnecessary)📖
|
||||
|
||||
1. First! The tips here are for those who want to use the multi tone resource package, [Shenyu resource package (Shenyu's own link)](https://pan.baidu.com/s/11uoq5zwN7c3rX-98DqVpJg) \(Extraction code: `ek3t`\)
|
||||
2. Download it to any location on your PC. Note that it does ***not*** need to be placed in the directory where *Musicreater* are. The audio resource package is large, so you can choose to download only:`神羽资源包_乐器、音源的资源包\羽音缭绕-midiout_25.0`.
|
||||
Also, you can download only `神羽资源包_乐器\音源的资源包\羽音缭绕-midiout_25.0\mcpack(国际版推荐)格式_25.0` or
|
||||
`神羽资源包_乐器\音源的资源包\羽音缭绕-midiout_25.0\zip格式_25.0`.
|
||||
4. The next step is the most IMPORTANT: to bind the resource package to *Musicreater*
|
||||
First, open *Musicreater*->Q&A->Select \[MiraclePlumeResourcePack\]... .At this time, in the selection box,
|
||||
the IMPORTANT step comes, select: ***The directory you downloaded: `羽音缭绕-midiout_25.0`, or also the parent directory `mcpack(国际版推荐)格式_25.0`or`zip格式_25.0`***
|
||||
For example, my file path is as follows:
|
||||
`L:\shenyu\音源的资源包\羽音缭绕-midiout_25.0` and in the directory, there are two folders and one .xls file:
|
||||
`神羽资源包_25.0_使用方法.xls`, `mcpack(国际版推荐)格式_25.0` and `zip格式_25.0`, so in *Musicreater* you should also select this folder: **L:\shenyu\音源的资源包\羽音缭绕-midiout_25.0**
|
||||
6. If you want to use the Miracle Plume Bedrock Edition Audio Resource Pack to make .mcfunction s, you should use Musicreater -> Edit - > Import audio tracks from MIDI and parse them with a new method, and then use it
|
||||
Musicreater - > function (package) - > the following four new functions
|
||||
|
||||
## Thanks🙏
|
||||
|
||||
- Thank *昀梦*\<QQ1515399885\> 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 *Dislink Sforza* \<QQ1600515314\> for the algorithm brought to us, his midi analysis algorithm became one of us's best ones
|
||||
- Thank *Arthur Morgan*\<QQ312280061\> for his/her biggest support for the debugging of Musicreater
|
||||
- Thank *Touch “偷吃”*\<QQ1793537164\> for support of debugging and testing program and algorithm, as well his/her suggestions to the improvement of our project
|
||||
- Thank *Mono*\<QQ738893087\> 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.
|
||||
1. 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*
|
||||
2. Thank *昀梦*\<QQ1515399885\> for finding and correcting the bugs in the commands that *Musicreater* Created.
|
||||
3. Thank *Charlie_Ping “查理平”* for bdx convert funtion.
|
||||
4. Thank *CMA_2401PT* for BDXWorkShop as the .bdx structure's operation guide.
|
||||
5. Thank *Miracle Plume “神羽”* \<QQshenyu40403\> for the Miracle Plume Bedrock Edition Audio Resource Pack
|
||||
6. Thank *Arthur Morgan* for his/her biggest support for the debugging of Musicreater
|
||||
7. Thanks for a lot of groupmates who support me and help me to test the program.
|
||||
8. If you have give me some help but u haven't been in the list, please contact me.
|
||||
|
||||
## Contact Information📞
|
||||
|
||||
### 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*(诸葛亮与八卦阵)
|
||||
|
||||
@@ -66,6 +130,8 @@ the data label that's used to convert the mid's instruments into minecraft's ins
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[Bilibili: Eilles]: https://img.shields.io/badge/Bilibili-%E5%87%8C%E4%BA%91%E9%87%91%E7%BE%BF-00A1E7?style=for-the-badge
|
||||
[Bilibili: bgArray]: https://img.shields.io/badge/Bilibili-%E8%AF%B8%E8%91%9B%E4%BA%AE%E4%B8%8E%E5%85%AB%E5%8D%A6%E9%98%B5-00A1E7?style=for-the-badge
|
||||
[CodeStyle: black]: https://img.shields.io/badge/code%20style-black-121110.svg?style=for-the-badge
|
||||
|
||||
0
bgArrayLib/__init__.py
Normal file
0
bgArrayLib/__init__.py
Normal file
BIN
bgArrayLib/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
bgArrayLib/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/bpm.cpython-38.pyc
Normal file
BIN
bgArrayLib/__pycache__/bpm.cpython-38.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/bpm.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/bpm.cpython-39.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/compute.cpython-38.pyc
Normal file
BIN
bgArrayLib/__pycache__/compute.cpython-38.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/compute.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/compute.cpython-39.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/instrumentConstant.cpython-38.pyc
Normal file
BIN
bgArrayLib/__pycache__/instrumentConstant.cpython-38.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/instrumentConstant.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/instrumentConstant.cpython-39.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/namesConstant.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/namesConstant.cpython-39.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/pitchStrConstant.cpython-38.pyc
Normal file
BIN
bgArrayLib/__pycache__/pitchStrConstant.cpython-38.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/pitchStrConstant.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/pitchStrConstant.cpython-39.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/reader.cpython-38.pyc
Normal file
BIN
bgArrayLib/__pycache__/reader.cpython-38.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/reader.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/reader.cpython-39.pyc
Normal file
Binary file not shown.
BIN
bgArrayLib/__pycache__/sy_resourcesPacker.cpython-39.pyc
Normal file
BIN
bgArrayLib/__pycache__/sy_resourcesPacker.cpython-39.pyc
Normal file
Binary file not shown.
67
bgArrayLib/bpm.py
Normal file
67
bgArrayLib/bpm.py
Normal file
@@ -0,0 +1,67 @@
|
||||
import mido
|
||||
import numpy
|
||||
|
||||
'''
|
||||
bpm
|
||||
bites per minutes
|
||||
每分钟的拍数
|
||||
'''
|
||||
|
||||
def mt2gt(mt, tpb_a, bpm_a):
|
||||
return round(mt / tpb_a / bpm_a * 60)
|
||||
|
||||
|
||||
def get(mid:mido.MidiFile) -> int:
|
||||
'''传入一个 MidiFile, 返回其音乐的bpm
|
||||
:param mid : mido.MidFile
|
||||
mido库识别的midi文件数据
|
||||
:return bpm : int
|
||||
'''
|
||||
# mid = mido.MidiFile(mf)
|
||||
long = mid.length
|
||||
tpb = mid.ticks_per_beat
|
||||
bpm = 20
|
||||
gotV = 0
|
||||
|
||||
for track in mid.tracks:
|
||||
global_time = 0
|
||||
for msg in track:
|
||||
global_time += msg.time
|
||||
if msg.type == "note_on" and msg.velocity > 0:
|
||||
gotV = mt2gt(global_time, tpb, bpm)
|
||||
errorV = numpy.fabs(gotV - long)
|
||||
last_dic = {bpm: errorV}
|
||||
if last_dic.get(bpm) > errorV:
|
||||
last_dic = {bpm: errorV}
|
||||
bpm += 2
|
||||
|
||||
while True:
|
||||
for track in mid.tracks:
|
||||
global_time = 0
|
||||
for msg in track:
|
||||
global_time += msg.time
|
||||
if msg.type == "note_on" and msg.velocity > 0:
|
||||
gotV = mt2gt(global_time, tpb, bpm)
|
||||
errorV = numpy.fabs(gotV - long)
|
||||
try:
|
||||
if last_dic.get(bpm - 2) > errorV:
|
||||
last_dic = {bpm: errorV}
|
||||
except TypeError:
|
||||
pass
|
||||
bpm += 2
|
||||
if bpm >= 252:
|
||||
break
|
||||
print(list(last_dic.keys())[0])
|
||||
return list(last_dic.keys())[0]
|
||||
|
||||
|
||||
def compute(mid:mido.MidiFile):
|
||||
answer = 60000000/mid.ticks_per_beat
|
||||
print(answer)
|
||||
return answer
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mid = mido.MidiFile(r"C:\Users\lc\Documents\MuseScore3\乐谱\乐谱\Bad style - Time back.mid")
|
||||
get(mid)
|
||||
compute(mid)
|
||||
40
bgArrayLib/compute.py
Normal file
40
bgArrayLib/compute.py
Normal file
@@ -0,0 +1,40 @@
|
||||
def round_up(num, power=0):
|
||||
"""
|
||||
实现精确四舍五入,包含正、负小数多种场景
|
||||
:param num: 需要四舍五入的小数
|
||||
:param power: 四舍五入位数,支持0-∞
|
||||
:return: 返回四舍五入后的结果
|
||||
"""
|
||||
try:
|
||||
print(1 / 0)
|
||||
except ZeroDivisionError:
|
||||
digit = 10 ** power
|
||||
num2 = float(int(num * digit))
|
||||
# 处理正数,power不为0的情况
|
||||
if num >= 0 and power != 0:
|
||||
tag = num * digit - num2 + 1 / (digit * 10)
|
||||
if tag >= 0.5:
|
||||
return (num2 + 1) / digit
|
||||
else:
|
||||
return num2 / digit
|
||||
# 处理正数,power为0取整的情况
|
||||
elif num >= 0 and power == 0:
|
||||
tag = num * digit - int(num)
|
||||
if tag >= 0.5:
|
||||
return (num2 + 1) / digit
|
||||
else:
|
||||
return num2 / digit
|
||||
# 处理负数,power为0取整的情况
|
||||
elif power == 0 and num < 0:
|
||||
tag = num * digit - int(num)
|
||||
if tag <= -0.5:
|
||||
return (num2 - 1) / digit
|
||||
else:
|
||||
return num2 / digit
|
||||
# 处理负数,power不为0的情况
|
||||
else:
|
||||
tag = num * digit - num2 - 1 / (digit * 10)
|
||||
if tag <= -0.5:
|
||||
return (num2 - 1) / digit
|
||||
else:
|
||||
return num2 / digit
|
||||
24
bgArrayLib/instrumentConstant.py
Normal file
24
bgArrayLib/instrumentConstant.py
Normal file
@@ -0,0 +1,24 @@
|
||||
instrument_list = {'0': 'harp', '1': 'harp', '2': 'pling', '3': 'harp', '4': 'pling', '5': 'pling', '6': 'harp',
|
||||
'7': 'harp',
|
||||
'8': 'share', '9': 'harp', '10': 'didgeridoo', '11': 'harp', '12': 'xylophone', '13': 'chime',
|
||||
'14': 'harp', '15': 'harp', '16': 'bass', '17': 'harp', '18': 'harp', '19': 'harp', '20': 'harp',
|
||||
'21': 'harp', '22': 'harp', '23': 'guitar', '24': 'guitar', '25': 'guitar', '26': 'guitar',
|
||||
'27': 'guitar', '28': 'guitar', '29': 'guitar', '30': 'guitar', '31': 'bass', '32': 'bass',
|
||||
'33': 'bass',
|
||||
'34': 'bass', '35': 'bass', '36': 'bass', '37': 'bass', '38': 'bass', '39': 'bass', '40': 'harp',
|
||||
'41': 'harp', '42': 'harp', '43': 'harp', '44': 'iron_xylophone', '45': 'guitar', '46': 'harp',
|
||||
'47': 'harp', '48': 'guitar', '49': 'guitar', '50': 'bit', '51': 'bit', '52': 'harp', '53': 'harp',
|
||||
'54': 'bit', '55': 'flute', '56': 'flute', '57': 'flute', '58': 'flute', '59': 'flute',
|
||||
'60': 'flute',
|
||||
'61': 'flute', '62': 'flute', '63': 'flute', '64': 'bit', '65': 'bit', '66': 'bit', '67': 'bit',
|
||||
'68': 'flute', '69': 'harp', '70': 'harp', '71': 'flute', '72': 'flute', '73': 'flute', '74': 'harp',
|
||||
'75': 'flute', '76': 'harp', '77': 'harp', '78': 'harp', '79': 'harp', '80': 'bit', '81': 'bit',
|
||||
'82': 'bit', '83': 'bit', '84': 'bit', '85': 'bit', '86': 'bit', '87': 'bit', '88': 'bit',
|
||||
'89': 'bit',
|
||||
'90': 'bit', '91': 'bit', '92': 'bit', '93': 'bit', '94': 'bit', '95': 'bit', '96': 'bit',
|
||||
'97': 'bit',
|
||||
'98': 'bit', '99': 'bit', '100': 'bit', '101': 'bit', '102': 'bit', '103': 'bit', '104': 'harp',
|
||||
'105': 'banjo', '106': 'harp', '107': 'harp', '108': 'harp', '109': 'harp', '110': 'harp',
|
||||
'111': 'guitar', '112': 'harp', '113': 'bell', '114': 'harp', '115': 'cow_bell', '116': 'basedrum',
|
||||
'117': 'bass', '118': 'bit', '119': 'basedrum', '120': 'guitar', '121': 'harp', '122': 'harp',
|
||||
'123': 'harp', '124': 'harp', '125': 'hat', '126': 'basedrum', '127': 'snare'}
|
||||
92
bgArrayLib/namesConstant.py
Normal file
92
bgArrayLib/namesConstant.py
Normal file
@@ -0,0 +1,92 @@
|
||||
zip_name = {-1: '-1.Acoustic_Kit_打击乐.zip', 0: '0.Acoustic_Grand_Piano_大钢琴.zip', 1: '1.Bright_Acoustic_Piano_亮音大钢琴.zip',
|
||||
10: '10.Music_Box_八音盒.zip', 100: '100.FX_brightness_合成特效-亮音.zip', 101: '101.FX_goblins_合成特效-小妖.zip',
|
||||
102: '102.FX_echoes_合成特效-回声.zip', 103: '103.FX_sci-fi_合成特效-科幻.zip', 104: '104.Sitar_锡塔尔.zip',
|
||||
105: '105.Banjo_班卓.zip', 106: '106.Shamisen_三味线.zip', 107: '107.Koto_筝.zip', 108: '108.Kalimba_卡林巴.zip',
|
||||
109: '109.Bagpipe_风笛.zip', 11: '11.Vibraphone_电颤琴.zip', 110: '110.Fiddle_古提琴.zip', 111: '111.Shanai_唢呐.zip',
|
||||
112: '112.Tinkle_Bell_铃铛.zip', 113: '113.Agogo_拉丁打铃.zip', 114: '114.Steel_Drums_钢鼓.zip',
|
||||
115: '115.Woodblock_木块.zip', 116: '116.Taiko_Drum_太鼓.zip', 117: '117.Melodic_Tom_嗵鼓.zip',
|
||||
118: '118.Synth_Drum_合成鼓.zip', 119: '119.Reverse_Cymbal_镲波形反转.zip', 12: '12.Marimba_马林巴.zip',
|
||||
13: '13.Xylophone_木琴.zip', 14: '14.Tubular_Bells_管钟.zip', 15: '15.Dulcimer_扬琴.zip',
|
||||
16: '16.Drawbar_Organ_击杆风琴.zip', 17: '17.Percussive_Organ_打击型风琴.zip', 18: '18.Rock_Organ_摇滚风琴.zip',
|
||||
19: '19.Church_Organ_管风琴.zip', 2: '2.Electric_Grand_Piano_电子大钢琴.zip', 20: '20.Reed_Organ_簧风琴.zip',
|
||||
21: '21.Accordion_手风琴.zip', 22: '22.Harmonica_口琴.zip', 23: '23.Tango_Accordian_探戈手风琴.zip',
|
||||
24: '24.Acoustic_Guitar_(nylon)_尼龙弦吉他.zip', 25: '25.Acoustic_Guitar(steel)_钢弦吉他.zip',
|
||||
26: '26.Electric_Guitar_(jazz)_爵士乐电吉他.zip', 27: '27.Electric_Guitar_(clean)_清音电吉他.zip',
|
||||
28: '28.Electric_Guitar_(muted)_弱音电吉他.zip', 29: '29.Overdriven_Guitar_驱动音效吉他.zip',
|
||||
3: '3.Honky-Tonk_Piano_酒吧钢琴.zip', 30: '30.Distortion_Guitar_失真音效吉他.zip', 31: '31.Guitar_Harmonics_吉他泛音.zip',
|
||||
32: '32.Acoustic_Bass_原声贝司.zip', 33: '33.Electric_Bass(finger)_指拨电贝司.zip',
|
||||
34: '34.Electric_Bass(pick)_拨片拨电贝司.zip', 35: '35.Fretless_Bass_无品贝司.zip', 36: '36.Slap_Bass_A_击弦贝司A.zip',
|
||||
37: '37.Slap_Bass_B_击弦贝司B.zip', 38: '38.Synth_Bass_A_合成贝司A.zip', 39: '39.Synth_Bass_B_合成贝司B.zip',
|
||||
4: '4.Electric_Piano_1_电钢琴A.zip', 40: '40.Violin_小提琴.zip', 41: '41.Viola_中提琴.zip', 42: '42.Cello_大提琴.zip',
|
||||
43: '43.Contrabass_低音提琴.zip', 44: '44.Tremolo_Strings_弦乐震音.zip', 45: '45.Pizzicato_Strings_弦乐拨奏.zip',
|
||||
46: '46.Orchestral_Harp_竖琴.zip', 47: '47.Timpani_定音鼓.zip', 48: '48.String_Ensemble_A_弦乐合奏A.zip',
|
||||
49: '49.String_Ensemble_B_弦乐合奏B.zip', 5: '5.Electric_Piano_2_电钢琴B.zip', 50: '50.SynthStrings_A_合成弦乐A.zip',
|
||||
51: '51.SynthStrings_B_合成弦乐B.zip', 52: '52.Choir_Aahs_合唱“啊”音.zip', 53: '53.Voice_Oohs_人声“哦”音.zip',
|
||||
54: '54.Synth_Voice_合成人声.zip', 55: '55.Orchestra_Hit_乐队打击乐.zip', 56: '56.Trumpet_小号.zip',
|
||||
57: '57.Trombone_长号.zip', 58: '58.Tuba_大号.zip', 59: '59.Muted_Trumpet_弱音小号.zip',
|
||||
6: '6.Harpsichord_拨弦古钢琴.zip', 60: '60.French_Horn_圆号.zip', 61: '61.Brass_Section_铜管组.zip',
|
||||
62: '62.Synth_Brass_A_合成铜管A.zip', 63: '63.Synth_Brass_A_合成铜管B.zip', 64: '64.Soprano_Sax_高音萨克斯.zip',
|
||||
65: '65.Alto_Sax_中音萨克斯.zip', 66: '66.Tenor_Sax_次中音萨克斯.zip', 67: '67.Baritone_Sax_上低音萨克斯.zip',
|
||||
68: '68.Oboe_双簧管.zip', 69: '69.English_Horn_英国管.zip', 7: '7.Clavinet_击弦古钢琴.zip', 70: '70.Bassoon_大管.zip',
|
||||
71: '71.Clarinet_单簧管.zip', 72: '72.Piccolo_短笛.zip', 73: '73.Flute_长笛.zip', 74: '74.Recorder_竖笛.zip',
|
||||
75: '75.Pan_Flute_排笛.zip', 76: '76.Bottle_Blow_吹瓶口.zip', 77: '77.Skakuhachi_尺八.zip', 78: '78.Whistle_哨.zip',
|
||||
79: '79.Ocarina_洋埙.zip', 8: '8.Celesta_钢片琴.zip', 80: '80.Lead_square_合成主音-方波.zip',
|
||||
81: '81.Lead_sawtooth_合成主音-锯齿波.zip', 82: '82.Lead_calliope_lead_合成主音-汽笛风琴.zip',
|
||||
83: '83.Lead_chiff_lead_合成主音-吹管.zip', 84: '84.Lead_charang_合成主音5-吉他.zip', 85: '85.Lead_voice_合成主音-人声.zip',
|
||||
86: '86.Lead_fifths_合成主音-五度.zip', 87: '87.Lead_bass+lead_合成主音-低音加主音.zip', 88: '88.Pad_new_age_合成柔音-新时代.zip',
|
||||
89: '89.Pad_warm_合成柔音-暖音.zip', 9: '9.Glockenspiel_钟琴.zip', 90: '90.Pad_polysynth_合成柔音-复合成.zip',
|
||||
91: '91.Pad_choir_合成柔音-合唱.zip', 92: '92.Pad_bowed_合成柔音-弓弦.zip', 93: '93.Pad_metallic_合成柔音-金属.zip',
|
||||
94: '94.Pad_halo_合成柔音-光环.zip', 95: '95.Pad_sweep_合成柔音-扫弦.zip', 96: '96.FX_rain_合成特效-雨.zip',
|
||||
97: '97.FX_soundtrack_合成特效-音轨.zip', 98: '98.FX_crystal_合成特效-水晶.zip', 99: '99.FX_atmosphere_合成特效-大气.zip'}
|
||||
|
||||
mcpack_name = {-1: '-1.Acoustic_Kit_打击乐.mcpack', 0: '0.Acoustic_Grand_Piano_大钢琴.mcpack',
|
||||
1: '1.Bright_Acoustic_Piano_亮音大钢琴.mcpack', 10: '10.Music_Box_八音盒.mcpack',
|
||||
100: '100.FX_brightness_合成特效-亮音.mcpack', 101: '101.FX_goblins_合成特效-小妖.mcpack',
|
||||
102: '102.FX_echoes_合成特效-回声.mcpack', 103: '103.FX_sci-fi_合成特效-科幻.mcpack', 104: '104.Sitar_锡塔尔.mcpack',
|
||||
105: '105.Banjo_班卓.mcpack', 106: '106.Shamisen_三味线.mcpack', 107: '107.Koto_筝.mcpack',
|
||||
108: '108.Kalimba_卡林巴.mcpack', 109: '109.Bagpipe_风笛.mcpack', 11: '11.Vibraphone_电颤琴.mcpack',
|
||||
110: '110.Fiddle_古提琴.mcpack', 111: '111.Shanai_唢呐.mcpack', 112: '112.Tinkle_Bell_铃铛.mcpack',
|
||||
113: '113.Agogo_拉丁打铃.mcpack', 114: '114.Steel_Drums_钢鼓.mcpack', 115: '115.Woodblock_木块.mcpack',
|
||||
116: '116.Taiko_Drum_太鼓.mcpack', 117: '117.Melodic_Tom_嗵鼓.mcpack', 118: '118.Synth_Drum_合成鼓.mcpack',
|
||||
119: '119.Reverse_Cymbal_镲波形反转.mcpack', 12: '12.Marimba_马林巴.mcpack', 13: '13.Xylophone_木琴.mcpack',
|
||||
14: '14.Tubular_Bells_管钟.mcpack', 15: '15.Dulcimer_扬琴.mcpack', 16: '16.Drawbar_Organ_击杆风琴.mcpack',
|
||||
17: '17.Percussive_Organ_打击型风琴.mcpack', 18: '18.Rock_Organ_摇滚风琴.mcpack',
|
||||
19: '19.Church_Organ_管风琴.mcpack', 2: '2.Electric_Grand_Piano_电子大钢琴.mcpack',
|
||||
20: '20.Reed_Organ_簧风琴.mcpack', 21: '21.Accordion_手风琴.mcpack', 22: '22.Harmonica_口琴.mcpack',
|
||||
23: '23.Tango_Accordian_探戈手风琴.mcpack', 24: '24.Acoustic_Guitar_(nylon)_尼龙弦吉他.mcpack',
|
||||
25: '25.Acoustic_Guitar(steel)_钢弦吉他.mcpack', 26: '26.Electric_Guitar_(jazz)_爵士乐电吉他.mcpack',
|
||||
27: '27.Electric_Guitar_(clean)_清音电吉他.mcpack', 28: '28.Electric_Guitar_(muted)_弱音电吉他.mcpack',
|
||||
29: '29.Overdriven_Guitar_驱动音效吉他.mcpack', 3: '3.Honky-Tonk_Piano_酒吧钢琴.mcpack',
|
||||
30: '30.Distortion_Guitar_失真音效吉他.mcpack', 31: '31.Guitar_Harmonics_吉他泛音.mcpack',
|
||||
32: '32.Acoustic_Bass_原声贝司.mcpack', 33: '33.Electric_Bass(finger)_指拨电贝司.mcpack',
|
||||
34: '34.Electric_Bass(pick)_拨片拨电贝司.mcpack', 35: '35.Fretless_Bass_无品贝司.mcpack',
|
||||
36: '36.Slap_Bass_A_击弦贝司A.mcpack', 37: '37.Slap_Bass_B_击弦贝司B.mcpack', 38: '38.Synth_Bass_A_合成贝司A.mcpack',
|
||||
39: '39.Synth_Bass_B_合成贝司B.mcpack', 4: '4.Electric_Piano_1_电钢琴A.mcpack', 40: '40.Violin_小提琴.mcpack',
|
||||
41: '41.Viola_中提琴.mcpack', 42: '42.Cello_大提琴.mcpack', 43: '43.Contrabass_低音提琴.mcpack',
|
||||
44: '44.Tremolo_Strings_弦乐震音.mcpack', 45: '45.Pizzicato_Strings_弦乐拨奏.mcpack',
|
||||
46: '46.Orchestral_Harp_竖琴.mcpack', 47: '47.Timpani_定音鼓.mcpack', 48: '48.String_Ensemble_A_弦乐合奏A.mcpack',
|
||||
49: '49.String_Ensemble_B_弦乐合奏B.mcpack', 5: '5.Electric_Piano_2_电钢琴B.mcpack',
|
||||
50: '50.SynthStrings_A_合成弦乐A.mcpack', 51: '51.SynthStrings_B_合成弦乐B.mcpack',
|
||||
52: '52.Choir_Aahs_合唱“啊”音.mcpack', 53: '53.Voice_Oohs_人声“哦”音.mcpack', 54: '54.Synth_Voice_合成人声.mcpack',
|
||||
55: '55.Orchestra_Hit_乐队打击乐.mcpack', 56: '56.Trumpet_小号.mcpack', 57: '57.Trombone_长号.mcpack',
|
||||
58: '58.Tuba_大号.mcpack', 59: '59.Muted_Trumpet_弱音小号.mcpack', 6: '6.Harpsichord_拨弦古钢琴.mcpack',
|
||||
60: '60.French_Horn_圆号.mcpack', 61: '61.Brass_Section_铜管组.mcpack', 62: '62.Synth_Brass_A_合成铜管A.mcpack',
|
||||
63: '63.Synth_Brass_A_合成铜管B.mcpack', 64: '64.Soprano_Sax_高音萨克斯.mcpack', 65: '65.Alto_Sax_中音萨克斯.mcpack',
|
||||
66: '66.Tenor_Sax_次中音萨克斯.mcpack', 67: '67.Baritone_Sax_上低音萨克斯.mcpack', 68: '68.Oboe_双簧管.mcpack',
|
||||
69: '69.English_Horn_英国管.mcpack', 7: '7.Clavinet_击弦古钢琴.mcpack', 70: '70.Bassoon_大管.mcpack',
|
||||
71: '71.Clarinet_单簧管.mcpack', 72: '72.Piccolo_短笛.mcpack', 73: '73.Flute_长笛.mcpack',
|
||||
74: '74.Recorder_竖笛.mcpack', 75: '75.Pan_Flute_排笛.mcpack', 76: '76.Bottle_Blow_吹瓶口.mcpack',
|
||||
77: '77.Skakuhachi_尺八.mcpack', 78: '78.Whistle_哨.mcpack', 79: '79.Ocarina_洋埙.mcpack',
|
||||
8: '8.Celesta_钢片琴.mcpack', 80: '80.Lead_square_合成主音-方波.mcpack', 81: '81.Lead_sawtooth_合成主音-锯齿波.mcpack',
|
||||
82: '82.Lead_calliope_lead_合成主音-汽笛风琴.mcpack', 83: '83.Lead_chiff_lead_合成主音-吹管.mcpack',
|
||||
84: '84.Lead_charang_合成主音5-吉他.mcpack', 85: '85.Lead_voice_合成主音-人声.mcpack',
|
||||
86: '86.Lead_fifths_合成主音-五度.mcpack', 87: '87.Lead_bass+lead_合成主音-低音加主音.mcpack',
|
||||
88: '88.Pad_new_age_合成柔音-新时代.mcpack', 89: '89.Pad_warm_合成柔音-暖音.mcpack', 9: '9.Glockenspiel_钟琴.mcpack',
|
||||
90: '90.Pad_polysynth_合成柔音-复合成.mcpack', 91: '91.Pad_choir_合成柔音-合唱.mcpack',
|
||||
92: '92.Pad_bowed_合成柔音-弓弦.mcpack', 93: '93.Pad_metallic_合成柔音-金属.mcpack',
|
||||
94: '94.Pad_halo_合成柔音-光环.mcpack', 95: '95.Pad_sweep_合成柔音-扫弦.mcpack', 96: '96.FX_rain_合成特效-雨.mcpack',
|
||||
97: '97.FX_soundtrack_合成特效-音轨.mcpack', 98: '98.FX_crystal_合成特效-水晶.mcpack',
|
||||
99: '99.FX_atmosphere_合成特效-大气.mcpack'}
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(zip_name[0])
|
||||
133
bgArrayLib/pitchStrConstant.py
Normal file
133
bgArrayLib/pitchStrConstant.py
Normal file
@@ -0,0 +1,133 @@
|
||||
pitch = {
|
||||
'0': '0.0220970869120796',
|
||||
'1': '0.0234110480761981',
|
||||
'2': '0.0248031414370031',
|
||||
'3': '0.0262780129766786',
|
||||
'4': '0.0278405849418856',
|
||||
'5': '0.0294960722713029',
|
||||
'6': '0.03125',
|
||||
'7': '0.033108221698728',
|
||||
'8': '0.0350769390096679',
|
||||
'9': '0.037162722343835',
|
||||
'10': '0.0393725328092148',
|
||||
'11': '0.0417137454428136',
|
||||
'12': '0.0441941738241592',
|
||||
'13': '0.0468220961523963',
|
||||
'14': '0.0496062828740062',
|
||||
'15': '0.0525560259533572',
|
||||
'16': '0.0556811698837712',
|
||||
'17': '0.0589921445426059',
|
||||
'18': '0.0625',
|
||||
'19': '0.066216443397456',
|
||||
'20': '0.0701538780193358',
|
||||
'21': '0.0743254446876701',
|
||||
'22': '0.0787450656184296',
|
||||
'23': '0.0834274908856271',
|
||||
'24': '0.0883883476483184',
|
||||
'25': '0.0936441923047926',
|
||||
'26': '0.0992125657480125',
|
||||
'27': '0.105112051906714',
|
||||
'28': '0.111362339767542',
|
||||
'29': '0.117984289085212',
|
||||
'30': '0.125',
|
||||
'31': '0.132432886794912',
|
||||
'32': '0.140307756038672',
|
||||
'33': '0.14865088937534',
|
||||
'34': '0.157490131236859',
|
||||
'35': '0.166854981771254',
|
||||
'36': '0.176776695296637',
|
||||
'37': '0.187288384609585',
|
||||
'38': '0.198425131496025',
|
||||
'39': '0.210224103813429',
|
||||
'40': '0.222724679535085',
|
||||
'41': '0.235968578170423',
|
||||
'42': '0.25',
|
||||
'43': '0.264865773589824',
|
||||
'44': '0.280615512077343',
|
||||
'45': '0.29730177875068',
|
||||
'46': '0.314980262473718',
|
||||
'47': '0.333709963542509',
|
||||
'48': '0.353553390593274',
|
||||
'49': '0.37457676921917',
|
||||
'50': '0.39685026299205',
|
||||
'51': '0.420448207626857',
|
||||
'52': '0.44544935907017',
|
||||
'53': '0.471937156340847',
|
||||
'54': '0.5',
|
||||
'55': '0.529731547179648',
|
||||
'56': '0.561231024154687',
|
||||
'57': '0.594603557501361',
|
||||
'58': '0.629960524947437',
|
||||
'59': '0.667419927085017',
|
||||
'60': '0.707106781186548',
|
||||
'61': '0.749153538438341',
|
||||
'62': '0.7937005259841',
|
||||
'63': '0.840896415253715',
|
||||
'64': '0.890898718140339',
|
||||
'65': '0.943874312681694',
|
||||
'66': '1',
|
||||
'67': '1.0594630943593',
|
||||
'68': '1.12246204830937',
|
||||
'69': '1.18920711500272',
|
||||
'70': '1.25992104989487',
|
||||
'71': '1.33483985417003',
|
||||
'72': '1.4142135623731',
|
||||
'73': '1.49830707687668',
|
||||
'74': '1.5874010519682',
|
||||
'75': '1.68179283050743',
|
||||
'76': '1.78179743628068',
|
||||
'77': '1.88774862536339',
|
||||
'78': '2',
|
||||
'79': '2.11892618871859',
|
||||
'80': '2.24492409661875',
|
||||
'81': '2.37841423000544',
|
||||
'82': '2.51984209978975',
|
||||
'83': '2.66967970834007',
|
||||
'84': '2.82842712474619',
|
||||
'85': '2.99661415375336',
|
||||
'86': '3.1748021039364',
|
||||
'87': '3.36358566101486',
|
||||
'88': '3.56359487256136',
|
||||
'89': '3.77549725072677',
|
||||
'90': '4',
|
||||
'91': '4.23785237743718',
|
||||
'92': '4.48984819323749',
|
||||
'93': '4.75682846001088',
|
||||
'94': '5.03968419957949',
|
||||
'95': '5.33935941668014',
|
||||
'96': '5.65685424949238',
|
||||
'97': '5.99322830750673',
|
||||
'98': '6.3496042078728',
|
||||
'99': '6.72717132202972',
|
||||
'100': '7.12718974512272',
|
||||
'101': '7.55099450145355',
|
||||
'102': '8',
|
||||
'103': '8.47570475487436',
|
||||
'104': '8.97969638647498',
|
||||
'105': '9.51365692002177',
|
||||
'106': '10.079368399159',
|
||||
'107': '10.6787188333603',
|
||||
'108': '11.3137084989848',
|
||||
'109': '11.9864566150135',
|
||||
'110': '12.6992084157456',
|
||||
'111': '13.4543426440594',
|
||||
'112': '14.2543794902454',
|
||||
'113': '15.1019890029071',
|
||||
'114': '16',
|
||||
'115': '16.9514095097487',
|
||||
'116': '17.95939277295',
|
||||
'117': '19.0273138400435',
|
||||
'118': '20.158736798318',
|
||||
'119': '21.3574376667206',
|
||||
'120': '22.6274169979695',
|
||||
'121': '23.9729132300269',
|
||||
'122': '25.3984168314912',
|
||||
'123': '26.9086852881189',
|
||||
'124': '28.5087589804909',
|
||||
'125': '30.2039780058142',
|
||||
'126': '32',
|
||||
'127': '33.9028190194974',
|
||||
'128': '35.9187855458999',
|
||||
'129': '38.0546276800871',
|
||||
'130': '40.3174735966359',
|
||||
'131': '42.7148753334411'}
|
||||
148
bgArrayLib/reader.py
Normal file
148
bgArrayLib/reader.py
Normal file
@@ -0,0 +1,148 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
from nmcsup.log import log
|
||||
import pickle
|
||||
|
||||
|
||||
class Note:
|
||||
def __init__(self, channel, pitch, velocity, time, time_position, instrument):
|
||||
self.channel = channel
|
||||
self.pitch = pitch
|
||||
self.velocity = velocity
|
||||
self.delay = time
|
||||
self.time_position = time_position
|
||||
self.instrument = instrument
|
||||
self.CD = "d"
|
||||
|
||||
def get_CD(self, start, end):
|
||||
if end - start > 1.00:
|
||||
self.CD = "c"
|
||||
else:
|
||||
self.CD = "d"
|
||||
|
||||
|
||||
def midiNewReader(midfile: str):
|
||||
import mido
|
||||
# from msctspt.threadOpera import NewThread
|
||||
from bgArrayLib.bpm import get
|
||||
|
||||
def Time(mt, tpb_a, bpm_a):
|
||||
return round(mt / tpb_a / bpm_a * 60 * 20)
|
||||
|
||||
Notes = []
|
||||
tracks = []
|
||||
note_list = []
|
||||
close = []
|
||||
on = []
|
||||
off = []
|
||||
instruments = []
|
||||
isPercussion = False
|
||||
try:
|
||||
mid = mido.MidiFile(midfile)
|
||||
except Exception:
|
||||
log("找不到文件或无法读取文件" + midfile)
|
||||
return False
|
||||
tpb = mid.ticks_per_beat
|
||||
bpm = get(mid)
|
||||
# 解析
|
||||
# def loadMidi(track1):
|
||||
for track in mid.tracks:
|
||||
overallTime = 0.0
|
||||
instrument = 0
|
||||
for i in track:
|
||||
overallTime += i.time
|
||||
try:
|
||||
if i.channel != 9:
|
||||
# try:
|
||||
# log("event_type(事件): " + str(i.type) + " channel(音轨): " + str(i.channel) +
|
||||
# " note/pitch(音高): " +
|
||||
# str(i[2]) +
|
||||
# " velocity(力度): " + str(i.velocity) + " time(间隔时间): " + str(i.time) +
|
||||
# " overallTime/globalTime/timePosition: " + str(overallTime) + " \n")
|
||||
# except AttributeError:
|
||||
# log("event_type(事件): " + str(i.type) + " thing(内容):" + str(i) + " \n")
|
||||
if 'program_change' in str(i):
|
||||
instrument = i.program
|
||||
if instrument > 119: # 音色不够
|
||||
pass
|
||||
else:
|
||||
instruments.append(i.program)
|
||||
if 'note_on' in str(i) and i.velocity > 0:
|
||||
print(i)
|
||||
# print(i.note)
|
||||
# print([Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), instrument)])
|
||||
tracks.append(
|
||||
[Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), instrument)])
|
||||
note_list.append(
|
||||
[i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), instrument])
|
||||
on.append([i.note, Time(overallTime, tpb, bpm)])
|
||||
# return [Note(i.channel, i, i.velocity, i.time, Time(overallTime, tpb, bpm))]
|
||||
if 'note_off' in str(i) or 'note_on' in str(i) and i.velocity == 0:
|
||||
# print(i)
|
||||
# print([Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm))])
|
||||
close.append(
|
||||
[Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), instrument)])
|
||||
off.append([i.note, Time(overallTime, tpb, bpm)])
|
||||
# return [Note(i.channel, i, i.velocity, i.time, Time(overallTime, tpb, bpm))]
|
||||
except AttributeError:
|
||||
pass
|
||||
if 'note_on' in str(i) and i.channel == 9:
|
||||
if 'note_on' in str(i) and i.velocity > 0:
|
||||
print(i)
|
||||
# print(i.note)
|
||||
# print([Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), -1)])
|
||||
tracks.append([Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), -1)])
|
||||
note_list.append([i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), -1])
|
||||
on.append([i.note, Time(overallTime, tpb, bpm)])
|
||||
isPercussion = True
|
||||
# return [Note(i.channel, i, i.velocity, i.time, Time(overallTime, tpb, bpm))]
|
||||
Notes.append(tracks)
|
||||
if instruments is []:
|
||||
instruments.append(0)
|
||||
instruments = list(set(instruments))
|
||||
with open("1.pkl", 'wb') as b:
|
||||
pickle.dump([instruments, isPercussion], b)
|
||||
|
||||
# for j, track in enumerate(mid.tracks):
|
||||
# th = NewThread(loadMidi, (track,))
|
||||
# th.start()
|
||||
# Notes.append(th.getResult())
|
||||
|
||||
# print(Notes)
|
||||
print(Notes.__len__())
|
||||
# print(note_list)
|
||||
print(instruments)
|
||||
return Notes
|
||||
# return [Notes, note_list]
|
||||
|
||||
|
||||
def midiClassReader(midfile: str):
|
||||
import mido
|
||||
from bgArrayLib.bpm import get
|
||||
|
||||
def Time(mt, tpb_a, bpm_a):
|
||||
return round(mt / tpb_a / bpm_a * 60 * 20)
|
||||
|
||||
Notes = []
|
||||
tracks = []
|
||||
try:
|
||||
mid = mido.MidiFile(filename=midfile,clip=True)
|
||||
except Exception:
|
||||
log("找不到文件或无法读取文件" + midfile)
|
||||
return False
|
||||
log("midi已经载入了。")
|
||||
tpb = mid.ticks_per_beat
|
||||
bpm = get(mid)
|
||||
for track in mid.tracks:
|
||||
overallTime = 0.0
|
||||
instrument = 0
|
||||
for i in track:
|
||||
overallTime += i.time
|
||||
if 'note_on' in str(i) and i.velocity > 0:
|
||||
print(i)
|
||||
tracks.append(
|
||||
[Note(i.channel, i.note, i.velocity, i.time, Time(overallTime, tpb, bpm), instrument)])
|
||||
Notes.append(tracks)
|
||||
print(Notes.__len__())
|
||||
return Notes
|
||||
131
bgArrayLib/sy_resourcesPacker.py
Normal file
131
bgArrayLib/sy_resourcesPacker.py
Normal file
@@ -0,0 +1,131 @@
|
||||
import os
|
||||
import pickle
|
||||
# import tkinter.filedialog
|
||||
# from namesConstant import zip_name
|
||||
# from namesConstant import mcpack_name
|
||||
import bgArrayLib.namesConstant
|
||||
import shutil
|
||||
zipN = bgArrayLib.namesConstant.zip_name
|
||||
mpN = bgArrayLib.namesConstant.mcpack_name
|
||||
|
||||
manifest = {
|
||||
"format_version": 1,
|
||||
"header": {
|
||||
"name": "羽音缭绕-midiout_25.5--音创使用",
|
||||
"description": "羽音缭绕-midiout_25.0--音创使用",
|
||||
"uuid": "c1adbda4-3b3e-4e5b-a57e-cde8ac80ee19",
|
||||
"version": [25, 5, 0]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"description": "羽音缭绕-midiout_25.0--音创使用",
|
||||
"type": "resources",
|
||||
"uuid": "c13455d5-b9f3-47f2-9706-c05ad86b3180 ",
|
||||
"version": [25, 5, 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
def resources_pathSetting(newPath: str = ""):
|
||||
if not os.path.isfile("./bgArrayLib/resourcesPath.rpposi") and newPath == "":
|
||||
return [False, 1] # 1:没有路径文件
|
||||
elif newPath != "": # not os.path.isfile("./bgArrayLib/resourcesPath.rpposi") and
|
||||
path = newPath
|
||||
print(path)
|
||||
with open("./bgArrayLib/resourcesPath.rpposi", 'w') as w:
|
||||
w.write(path)
|
||||
if "mcpack(国际版推荐)格式_25.0" in os.listdir(path) and "zip格式_25.0" in os.listdir(path):
|
||||
return [True, path, 1] # 1:都有
|
||||
elif "mcpack(国际版推荐)格式_25.0" in os.listdir(path) and "zip格式_25.0" not in os.listdir(path):
|
||||
return [True, path, 2] # 2:有pack
|
||||
elif "mcpack(国际版推荐)格式_25.0" not in os.listdir(path) and "zip格式_25.0" in os.listdir(path):
|
||||
return [True, path, 3] # 3:有zip
|
||||
else:
|
||||
return [False, 2] # 2:路径文件指示错误
|
||||
if os.path.isfile("./bgArrayLib/resourcesPath.rpposi") and newPath == "":
|
||||
with open("./bgArrayLib/resourcesPath.rpposi", 'r') as f:
|
||||
path = f.read()
|
||||
if "mcpack(国际版推荐)格式_25.0" in os.listdir(path) and "zip格式_25.0" in os.listdir(path):
|
||||
return [True, path, 1] # 1:都有
|
||||
elif "mcpack(国际版推荐)格式_25.0" in os.listdir(path) and "zip格式_25.0" not in os.listdir(path):
|
||||
return [True, path, 2] # 2:有pack
|
||||
elif "mcpack(国际版推荐)格式_25.0" not in os.listdir(path) and "zip格式_25.0" in os.listdir(path):
|
||||
return [True, path, 3] # 3:有zip
|
||||
else:
|
||||
return [False, 2] # 2:路径文件指示错误
|
||||
|
||||
|
||||
def choose_resources():
|
||||
global zipN
|
||||
global mpN
|
||||
back_list = []
|
||||
try:
|
||||
with open(r"1.pkl", 'rb') as rb:
|
||||
instrument = list(pickle.load(rb))
|
||||
print(instrument)
|
||||
except FileNotFoundError:
|
||||
try:
|
||||
with open(r"./nmcsup/1.pkl", 'rb') as rb:
|
||||
instrument = list(pickle.load(rb))
|
||||
print(instrument)
|
||||
except FileNotFoundError:
|
||||
return False
|
||||
path = resources_pathSetting()
|
||||
if path.__len__() == 2:
|
||||
return path
|
||||
else:
|
||||
dataT = path[2]
|
||||
pathT = path[1]
|
||||
if dataT == 1:
|
||||
if instrument[1] is True:
|
||||
index = zipN.get(-1)
|
||||
percussion_instrument = str(pathT) + "\\zip格式_25.0\\" + index
|
||||
# print(percussion_instrument)
|
||||
back_list.append(percussion_instrument)
|
||||
for i in instrument[0]:
|
||||
ins_p = str(pathT) + "\\zip格式_25.0\\" + str(zipN.get(i))
|
||||
# print(ins_p)
|
||||
back_list.append(ins_p)
|
||||
print(back_list)
|
||||
return back_list
|
||||
elif dataT == 2:
|
||||
if instrument[1] is True:
|
||||
index = mpN.get(-1)
|
||||
percussion_instrument = str(pathT) + "\\mcpack(国际版推荐)格式_25.0\\" + index
|
||||
# print(percussion_instrument)
|
||||
back_list.append(percussion_instrument)
|
||||
for i in instrument[0]:
|
||||
ins_p = str(pathT) + "\\mcpack(国际版推荐)格式_25.0\\" + str(mpN.get(i))
|
||||
# print(ins_p)
|
||||
back_list.append(ins_p)
|
||||
print(back_list)
|
||||
return back_list
|
||||
elif dataT == 3:
|
||||
if instrument[1] is True:
|
||||
index = zipN.get(-1)
|
||||
percussion_instrument = str(pathT) + "\\zip格式_25.0\\" + index
|
||||
# print(percussion_instrument)
|
||||
back_list.append(percussion_instrument)
|
||||
for i in instrument[0]:
|
||||
ins_p = str(pathT) + "\\zip格式_25.0\\" + str(zipN.get(i))
|
||||
# print(ins_p)
|
||||
back_list.append(ins_p)
|
||||
print(back_list)
|
||||
return back_list
|
||||
|
||||
|
||||
def scatteredPack(path):
|
||||
pack_list = choose_resources()
|
||||
print(pack_list)
|
||||
print(path)
|
||||
# os.close("L:/0WorldMusicCreater-MFMS new edition")
|
||||
# shutil.copy("L:\\shenyu\\音源的资源包\\羽音缭绕-midiout_25.0\\mcpack(国际版推荐)格式_25.0\\0.Acoustic_Grand_Piano_大钢琴.mcpack",
|
||||
# "L:/0WorldMusicCreater-MFMS new edition")
|
||||
for i in pack_list:
|
||||
shutil.copy(i, path)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# print(resources_pathSetting(r"L:\shenyu\音源的资源包\羽音缭绕-midiout_25.0"))
|
||||
choose_resources()
|
||||
151
demo_convert.py
151
demo_convert.py
@@ -1,151 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
|
||||
|
||||
|
||||
"""
|
||||
音·创 库版 MIDI转换展示程序
|
||||
Musicreater Package Version : Demo for Midi Conversion
|
||||
|
||||
Copyright 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 ./Lisence.md
|
||||
Terms & Conditions: ./Lisence.md
|
||||
"""
|
||||
|
||||
from msctPkgver.main import *
|
||||
import os
|
||||
|
||||
convertion = midiConvert()
|
||||
|
||||
while True:
|
||||
midipath = input('请输入midi文件路径:')
|
||||
if os.path.exists(midipath):
|
||||
break
|
||||
else:
|
||||
print('文件不存在,请重新输入')
|
||||
|
||||
outpath = input('请输入输出路径:')
|
||||
|
||||
if not os.path.exists(outpath):
|
||||
os.makedirs(outpath)
|
||||
|
||||
while True:
|
||||
try:
|
||||
outFormat = int(input('请输入输出格式(0:mcpack|1:BDX结构):'))
|
||||
if outFormat == 0:
|
||||
isAutoReset = input('是否自动重置计分板(1|0):')
|
||||
if isAutoReset != '':
|
||||
isAutoReset = bool(int(isAutoReset))
|
||||
while True:
|
||||
isProgress = input('*进度条[本Demo不支持自定义]:')
|
||||
if isProgress != '':
|
||||
if isProgress in ('1', 'True'):
|
||||
isProgress = True
|
||||
elif isProgress in ('0', 'False'):
|
||||
isProgress = False
|
||||
else:
|
||||
isProgress = isProgress
|
||||
else:
|
||||
continue
|
||||
break
|
||||
sbname = input('请输入计分板名称:')
|
||||
volume = input('请输入音量(0-1):')
|
||||
if volume != '':
|
||||
volume = float(volume)
|
||||
speed = input('请输入速度倍率:')
|
||||
if speed != '':
|
||||
speed = float(speed)
|
||||
elif outFormat == 1:
|
||||
author = input('请输入作者:')
|
||||
while True:
|
||||
isProgress = input('*进度条[本Demo不支持自定义]:')
|
||||
if isProgress != '':
|
||||
if isProgress in ('1', 'True'):
|
||||
isProgress = True
|
||||
elif isProgress in ('0', 'False'):
|
||||
isProgress = False
|
||||
else:
|
||||
isProgress = isProgress
|
||||
else:
|
||||
continue
|
||||
break
|
||||
maxHeight = input('请输入指令结构最大生成高度:')
|
||||
if maxHeight != '':
|
||||
maxHeight = int(maxHeight)
|
||||
sbname = input('请输入计分板名称:')
|
||||
volume = input('请输入音量(0-1):')
|
||||
if volume != '':
|
||||
volume = float(volume)
|
||||
speed = input('请输入速度倍率:')
|
||||
if speed != '':
|
||||
speed = float(speed)
|
||||
isAutoReset = input('是否自动重置计分板(1|0):')
|
||||
if isAutoReset != '':
|
||||
isAutoReset = bool(int(isAutoReset))
|
||||
break
|
||||
except BaseException:
|
||||
print('输入错误,请重新输入')
|
||||
|
||||
|
||||
|
||||
|
||||
m = 1
|
||||
'''采用的算法编号'''
|
||||
|
||||
|
||||
if os.path.isdir(midipath):
|
||||
for i in os.listdir(midipath):
|
||||
if i.lower().endswith('.mid'):
|
||||
print(f'正在操作{i}')
|
||||
convertion.convert(midipath + '/' + i, outpath + '/' + i[:-4])
|
||||
if outFormat == 0:
|
||||
print(convertion.tomcpack(
|
||||
m,
|
||||
isAutoReset
|
||||
if isAutoReset != ''
|
||||
else bool(int(input('是否自动重置计分板(1|0):'))),
|
||||
isProgress,
|
||||
sbname if sbname != '' else input('请输入计分板名称:'),
|
||||
volume if volume != '' else float(input('请输入音量(0-1):')),
|
||||
speed if speed != '' else float(input('请输入速度倍率:')),
|
||||
))
|
||||
elif outFormat == 1:
|
||||
print(convertion.toBDXfile(
|
||||
m,
|
||||
author if author != '' else input('请输入作者:'),
|
||||
isProgress,
|
||||
maxHeight if maxHeight != '' else int(input('请输入指令结构最大生成高度:')),
|
||||
sbname if sbname != '' else input('请输入计分板名称:'),
|
||||
volume if volume != '' else float(input('请输入音量(0-1):')),
|
||||
speed if speed != '' else float(input('请输入速度倍率:')),
|
||||
isAutoReset
|
||||
if isAutoReset != ''
|
||||
else bool(int(input('是否自动重置计分板(1|0):'))),
|
||||
))
|
||||
else:
|
||||
convertion.convert(midipath, outpath)
|
||||
if outFormat == 0:
|
||||
print(convertion.tomcpack(
|
||||
m,
|
||||
isAutoReset if isAutoReset != '' else bool(int(input('是否自动重置计分板(1|0):'))),
|
||||
isProgress,
|
||||
sbname if sbname != '' else input('请输入计分板名称:'),
|
||||
volume if volume != '' else float(input('请输入音量(0-1):')),
|
||||
speed if speed != '' else float(input('请输入速度倍率:')),
|
||||
))
|
||||
elif outFormat == 1:
|
||||
print(convertion.toBDXfile(
|
||||
m,
|
||||
author if author != '' else input('请输入作者:'),
|
||||
isProgress,
|
||||
maxHeight if maxHeight != '' else int(input('请输入指令结构最大生成高度:')),
|
||||
sbname if sbname != '' else input('请输入计分板名称:'),
|
||||
volume if volume != '' else float(input('请输入音量(0-1):')),
|
||||
speed if speed != '' else float(input('请输入速度倍率:')),
|
||||
isAutoReset if isAutoReset != '' else bool(int(input('是否自动重置计分板(1|0):'))),
|
||||
))
|
||||
@@ -1,101 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# THIS PROGRAM IS ONLY A TEST EXAMPLE
|
||||
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
|
||||
|
||||
|
||||
"""
|
||||
音·创 库版 MIDI转换展示程序
|
||||
Musicreater Package Version : Demo for Midi Conversion
|
||||
|
||||
Copyright 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 ./Lisence.md
|
||||
Terms & Conditions: ./Lisence.md
|
||||
"""
|
||||
|
||||
from msctPkgver.main import *
|
||||
|
||||
convertion = midiConvert()
|
||||
|
||||
while True:
|
||||
midipath = input('请输入midi文件路径:')
|
||||
if os.path.exists(midipath):
|
||||
break
|
||||
else:
|
||||
print('文件不存在,请重新输入')
|
||||
|
||||
outpath = input('请输入输出路径:')
|
||||
|
||||
if not os.path.exists(outpath):
|
||||
os.makedirs(outpath)
|
||||
|
||||
while True:
|
||||
try:
|
||||
authorname = input('请输入作者:')
|
||||
while True:
|
||||
isProgress = input('*进度条[本Demo不支持自定义]:')
|
||||
if isProgress != '':
|
||||
if isProgress in ('1', 'True'):
|
||||
isProgress = True
|
||||
elif isProgress in ('0', 'False'):
|
||||
isProgress = False
|
||||
else:
|
||||
isProgress = isProgress
|
||||
else:
|
||||
continue
|
||||
break
|
||||
|
||||
volume = input('请输入音量(0-1):')
|
||||
if volume != '':
|
||||
volume = float(volume)
|
||||
speed = input('请输入速度倍率:')
|
||||
if speed != '':
|
||||
speed = float(speed)
|
||||
player = input('请输入玩家选择器:')
|
||||
heightmax = input('请输入指令结构最大生成高度:')
|
||||
if heightmax != '':
|
||||
heightmax = int(heightmax)
|
||||
break
|
||||
|
||||
except BaseException:
|
||||
print('输入错误,请重新输入')
|
||||
|
||||
|
||||
def operation(
|
||||
i,
|
||||
):
|
||||
print(f'正在操作{i}')
|
||||
convertion.convert(midipath + '/' + i, outpath)
|
||||
convertion.toBDXfile_withDelay(
|
||||
1,
|
||||
authorname if authorname != '' else input('请输入作者:'),
|
||||
isProgress,
|
||||
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(
|
||||
1,
|
||||
authorname if authorname != '' else input('请输入作者:'),
|
||||
isProgress,
|
||||
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('请输入玩家选择器:'),
|
||||
)
|
||||
@@ -1,262 +0,0 @@
|
||||
<h1 align="center">音·创 Musicreater</h1>
|
||||
|
||||
<p align="center">
|
||||
<img width="128" height="128" src="https://s1.ax1x.com/2022/05/06/Ouhghj.md.png" >
|
||||
</p>
|
||||
|
||||
|
||||
# Instructions for Using Demo(s)
|
||||
|
||||
*This is a tutorial for using the demo(s) of this library, not the Development Guide. If you want to see so, please read Below*
|
||||
|
||||
## Under Windows
|
||||
|
||||
0. Install Python 3.6+
|
||||
|
||||
First of all, you need to install the runtime environment of this library, *Python*. And a Installation Pack maybe the best choice:
|
||||
|
||||
> [Downloading Python 64-bit](https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe)
|
||||
> [Downloading Python 32-bit](https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe)
|
||||
|
||||
While installing, it's better to check `Add Python 3.X to PATH`(just as the screenshot showed below), otherwise it needs to be set manually which may cause some time wasting
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1662736520757331846/e38efb81_9911226.png>
|
||||
|
||||
If you are new to Python or not very familiar to Computer Programming, and having the disk space in your PC's System Partition (usually C:) of 150 MB, you can directly choose *Install Now*.
|
||||
|
||||
However, if you want to do it like a pro, choosing *Customize Installation*, it's a necessary to be sure to check `pip` and `py launcher` will be installed on your computer(see screenshot below). The two options is required for the next step of installing the requirements.
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1662736621235871190/2ac3d98f_9911226.png>
|
||||
|
||||
After the installation, you can enter in your terminal(CMD/PowerShell/Bash/etc): "python" to ensure whether the installation was successful. If it was, your terminal will show things like below:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659972669907359295/cmd.png>
|
||||
|
||||
|
||||
1. Installing Requirements
|
||||
|
||||
It's better to open your terminal(CMD/PowerShell/Bash/etc) under Administrator Mode.
|
||||
|
||||
For example, if you want to use CMD in Administrator Mode, you can search `cmd` in the *Start Menu*, right click it and *Run as Administrator*
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662736878650993886/62487dd8_9911226.png">
|
||||
|
||||
Okay, after that, please enter in your terminal:
|
||||
|
||||
`pip install mido`
|
||||
|
||||
`pip install brotli`
|
||||
|
||||
If successful you will see something like below:
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662737676719454287/f61a70f7_9911226.png">
|
||||
|
||||
|
||||
|
||||
2. Download This Package and Demo(s)
|
||||
|
||||
- If you using Git, you can use the following commands to clone this lib:
|
||||
|
||||
`git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git`
|
||||
|
||||
- If Git is not installed, you can download the zip package from the code page(from [GitHub](https://github.com/EillesWan/Musicreater.git) or [Gitee](https://gitee.com/EillesWan/Musicreater.git)). Or you are a Chinese fan having a QQ account, you can [Join the QQ Group 861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr) and get it from our GroupFiles.
|
||||
|
||||
<img src=" https://foruda.gitee.com/images/1659972440341216712/下载.png" >
|
||||
|
||||
|
||||
2. Start Using Demo(s)
|
||||
|
||||
Open your terminal in the directory of this, taking CMD, for example, just enter the directory and enter `cmd` in the path box:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659974437388532868/输入.png>
|
||||
<img src=https://foruda.gitee.com/images/1659974754378201859/输入c.png>
|
||||
|
||||
And enter one of the commands below by choosing what you need:
|
||||
|
||||
`python demo_convert.py`
|
||||
|
||||
`python demo_convert_bdx_byDelay.py`
|
||||
|
||||
|
||||
### Addition for Error(s) Using or Installing
|
||||
|
||||
1. Environment Error of Microsoft Visual C++ Redistributable
|
||||
|
||||
If you meet this condition as the screenshot shows:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659972789779764953/bug.jpeg>
|
||||
|
||||
Your MSVC Environment may be not installed, and you can download and install
|
||||
> [Here of 64-Bit VCREDIST](https://aka.ms/vs/17/release/vc_redist.x64.exe)
|
||||
> [Here of 32-Bit VCREDIST](https://aka.ms/vs/17/release/vc_redist.x86.exe)
|
||||
|
||||
Thank our groupmate *Mono* again for helping finding this problem.
|
||||
|
||||
|
||||
|
||||
## Under Linux OS
|
||||
|
||||
|
||||
### Install Runtime Environment
|
||||
|
||||
0. Install and Verify Python Runtime
|
||||
|
||||
Common Linux Releases do include a Python Runtime Environment, what we should do only is to check it is a satisfied version to our program. If the version ≥Python3.6, theoretically our program can be run.
|
||||
|
||||
We can type:
|
||||
|
||||
```bash
|
||||
python -V
|
||||
```
|
||||
|
||||
To check the Python version, as the follows
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1665120915821957090/429561fd_9911226.png>
|
||||
|
||||
- Not Necessary
|
||||
|
||||
If you want to change a Python version just as what I want to do, it is such a great fantastic action! Let do as the follows:
|
||||
|
||||
- pacman Package Manager(In Arch Linux Mostly)
|
||||
|
||||
Let's write python3 into the ingore list of updating. Via `vim` to edit `/etc/pacman.conf`, add `python3` after `IgnorePkg`.
|
||||
|
||||
```bash
|
||||
sudo vim /etc/pacman.conf
|
||||
```
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1665124611490335193/5e99ca26_9911226.png>
|
||||
|
||||
Then we can search for python releases in [Arch Achieve](https://archive.archlinux.org/packages/).(*HERE, under Arch, Python refers to Python3 defaultly, while some other Linux releases using Python2 as default. So dose Arch Achieve.*)What I find here is [Python3.8.6](https://archive.archlinux.org/packages/p/python/python-3.8.6-1-x86_64.pkg.tar.zst), so let's download she via `pacman`:
|
||||
|
||||
```bash
|
||||
sudo pacman -U https://archive.archlinux.org/packages/p/python/python-3.8.6-1-x86_64.pkg.tar.zst
|
||||
```
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1665126362769399903/ea4b9598_9911226.png>
|
||||
|
||||
Perfect!
|
||||
|
||||
1. Install and Verify pip Package Manager
|
||||
|
||||
Before installing, it is to be checked, wheather Python's pip is OK:
|
||||
|
||||
```bash
|
||||
python -m pip # To check is pip installed
|
||||
# If a long tip occured, it is OK
|
||||
|
||||
# If returned as this, then not.
|
||||
/usr/bin/python: No module named pip
|
||||
# We can install pip via:
|
||||
sudo pacman -S python-pip
|
||||
# Verfy, remember.
|
||||
python -m pip
|
||||
|
||||
|
||||
# If you did but failed, we should use other methods to install pip:
|
||||
wget https://bootstrap.pypa.io/get-pip.py
|
||||
sudo python get-pip.py
|
||||
# Verfy, must.
|
||||
python -m pip
|
||||
```
|
||||
|
||||
Over after checking, lets install the dependences.
|
||||
|
||||
```bash
|
||||
pip install mido -i https://mirrors.aliyun.com/pypi/simple/
|
||||
pip install brotli -i https://mirrors.aliyun.com/pypi/simple/
|
||||
```
|
||||
|
||||
See the tips below as successfully installed:
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662737676719454287/f61a70f7_9911226.png">
|
||||
|
||||
|
||||
### Download this sources pack and Using its demos.
|
||||
|
||||
1. 使用Git下载本库及其示例代码
|
||||
|
||||
```bash
|
||||
git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git MSCTpkgver
|
||||
```
|
||||
|
||||
当上述命令执行成功,你会在执行此命令的所在位置发现一个名为 `MSCTpkgver` 的文件夹,其中包含的正是我们心心念念下载的本程序和示例代码。
|
||||
而我们要运行的也正是示例代码,因此,赶快进入下载到的文件夹:
|
||||
|
||||
```bash
|
||||
cd MSCTpkgver
|
||||
```
|
||||
|
||||
1. 开始使用
|
||||
|
||||
在目录下打开终端,执行以下命令:(选择你需要的)
|
||||
|
||||
```bash
|
||||
python demo_convert.py
|
||||
python demo_convert_bdx_byDelay.py
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
2. More Info for Parameters of Our Demo Program(s)
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659974810147043475/运行.png>
|
||||
|
||||
|Input Prompt|English Translation|Description|
|
||||
|----------------|----------------|-------|
|
||||
|请输入MIDI文件路径|Midi File Path|Path of a .mid file or a directory. While directory entered, our demo will convert all midi(s) in the directory|
|
||||
|请输入输出路径|Output Path|Where files converted in|
|
||||
|是否重置计分板|Whether Reset Scoreboard Automatically|Can only be 1 or 0(Recommanded 1)|
|
||||
|*进度条[注]|Progressbar|Whether to enable Progressbar and customize progressbar style. Type 0 or False to disable, 1 or True to use default style, or type using format taught in follow the Instructions below to customize one you like|
|
||||
|请输入计分板名称|Scoreboard Name|*Only not byDelay* The name of scoreboard that player using|
|
||||
|请输入音量|Volume|Only decimal in [0,1],(Recommanded 1)|
|
||||
|请输入速度倍率|Speed Multiplying Factor|Maybe you want to play it faster(>1) or slower(>0 <1)?|
|
||||
|请输入玩家选择器|Player Selector|Full Selector including `@x`. E.g: Play for players tagged `Holo`, enter `@a[tag=Holo]` on this parameter|
|
||||
|
||||
|
||||
|
||||
|
||||
# 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.*
|
||||
@@ -1,167 +0,0 @@
|
||||
## 使用前的准备工作
|
||||
|
||||
### 安装终端工具
|
||||
|
||||
这里我们选用 **Termux** 作为我们的终端工具来安装,这是一个强大的终端模拟器,旨在安卓环境下模拟Linux的软件包环境。
|
||||
|
||||
1. 下载
|
||||
|
||||
下载可以通过 [GitHub源](https://github.com/termux/termux-app/releases) 或者 [F-Droid源](https://f-droid.org/en/packages/com.termux/) ,个人建议选择 F-Droid 源,因为在国内可以访问得到,而 GitHub 源就看运气。
|
||||
|
||||
2. 安装
|
||||
|
||||
下载*APK*包后直接安装,安装后打开可以看到一个类似这样的界面:
|
||||
|
||||
<img height="512" src="https://foruda.gitee.com/images/1665933025120627254/a0479618_9911226.jpeg">
|
||||
|
||||
3. 完成
|
||||
|
||||
恭喜你,你已经获得了一个极客般流畅地操作你手机的终端工具。
|
||||
|
||||
### 安装运行环境
|
||||
|
||||
1. 换源
|
||||
|
||||
接下来,我们就要来准备安装一下 **Python** 运行环境了,这是运行 **Python** 源代码必要的。
|
||||
|
||||
首先,我估计你等不了多久,急得要死,所以我们要让下载速度稍微快一点,先来换个源。在 **Termux** 中,输入以下指令:
|
||||
|
||||
```bash
|
||||
echo "deb https://mirror.mwt.me/termux/main stable main" > /data/data/com.termux/files/usr/etc/apt/sources.list
|
||||
```
|
||||
|
||||
*感谢 天如<QQ 3291691454>为我们带来的简单换源方法。*
|
||||
|
||||
- *非必要步骤*:手动编辑换源
|
||||
|
||||
如果你闲着没事,非要要手动编辑个文档来换源,那用啥?用普通的编辑器肯定可以,于是我们就让他更普通一点,用**nano**吧!
|
||||
|
||||
在 **Termux** 中,输入以下指令:
|
||||
|
||||
```bash
|
||||
export EDITOR=nano
|
||||
apt edit-sources
|
||||
```
|
||||
|
||||
那么请把看到的如左下图的界面变为右下图吧:
|
||||
|
||||
<table><tr>
|
||||
<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>
|
||||
</tr></table>
|
||||
|
||||
- 图片中的文件,最后应该加入的两行为:
|
||||
|
||||
```bash
|
||||
deb https://mirrors.ustc.edu.cn/termux/apt/termux-main/ stable main
|
||||
deb https://mirrors.tuna.tsinghua.edu.cn/termux/apt/termux-main/ stable main
|
||||
```
|
||||
|
||||
然后键入 `Ctrl`+`S`,再键入 `Ctrl`+`X`,退出`nano`。
|
||||
|
||||
在换源之后,你可能会见到类似的提示:
|
||||
|
||||
```bash
|
||||
Your '/data/data/com.termux/files/usr/etc/apt/sources.list' file changed. Please run 'apt-get update'.
|
||||
```
|
||||
|
||||
那就遵循它的指引,输入:
|
||||
|
||||
```bash
|
||||
apt-get update
|
||||
```
|
||||
|
||||
Alright.
|
||||
|
||||
2. 安装 **Python**
|
||||
|
||||
```bash
|
||||
apt-get install python3
|
||||
```
|
||||
|
||||
如果遇到提示问是否继续,那就输入`Y`表示是,如左下图,安装成功后,图若右下。
|
||||
|
||||
<table><tr>
|
||||
<td><img src="https://foruda.gitee.com/images/1665933181440420034/7f0fb5fd_9911226.jpeg"></td>
|
||||
<td><img src="https://foruda.gitee.com/images/1665933238339972260/a9f06f4f_9911226.jpeg"></td>
|
||||
</tr></table>
|
||||
|
||||
接下来,我们来试一试 **Python** 是不是安装成了吧,输入
|
||||
|
||||
```bash
|
||||
python3 -V
|
||||
```
|
||||
|
||||
如果输出了形如 `Python 3.X.X` 的提示,则完成。
|
||||
|
||||
3. 安装依赖库
|
||||
|
||||
```bash
|
||||
# 首先换源
|
||||
pip config set global.index-url http://mirrors.aliyun.com/pypi/simple/
|
||||
# 然后安装
|
||||
pip install mido
|
||||
pip install brotli
|
||||
```
|
||||
|
||||
- 如果出现以下情况,真是死了鬼的,我们要来再搞个设置:
|
||||
|
||||
<img height="512" src="https://foruda.gitee.com/images/1665933289612919459/b87b7804_9911226.jpeg">
|
||||
|
||||
我们来修改收信任的源设置:
|
||||
|
||||
```bash
|
||||
pip config set global.trusted-host mirrors.aliyun.com/
|
||||
```
|
||||
|
||||
之后再来安装即可
|
||||
|
||||
```bash
|
||||
pip install mido
|
||||
pip install brotli
|
||||
```
|
||||
|
||||
安装成功后您可能会见到类似下图的提示:
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662737676719454287/f61a70f7_9911226.png">
|
||||
|
||||
### 安装下载工具
|
||||
|
||||
既然已经有了运行环境,那么我们就需要下载下我们的**音·创库版示例代码**工具,我非常推崇**Git**这种方便快捷好用还能下载仓库的代码管理器,这个世界上你也找不到第二个,所以我们来安装一下:
|
||||
|
||||
```bash
|
||||
pkg install git
|
||||
```
|
||||
|
||||
安装完成后记得测试一下:
|
||||
|
||||
<img height="512" src="https://foruda.gitee.com/images/1665933331269483373/9374c85d_9911226.jpeg">
|
||||
|
||||
## 本代码库的下载与演示程序的使用
|
||||
|
||||
1. 使用Git下载本库及其示例代码
|
||||
|
||||
```bash
|
||||
git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git MSCTpkgver
|
||||
```
|
||||
|
||||
当上述命令执行成功,你会在执行此命令的所在位置发现一个名为 `MSCTpkgver` 的文件夹,其中包含的正是我们心心念念下载的本程序和示例代码。
|
||||
而我们要运行的也正是示例代码,因此,赶快进入下载到的文件夹:
|
||||
|
||||
```bash
|
||||
cd MSCTpkgver
|
||||
```
|
||||
|
||||
1. 开始使用演示程序
|
||||
|
||||
依照你的需要,执行以下命令之一:
|
||||
|
||||
```bash
|
||||
python demo_convert.py #计分板播放器,支持mcpack与BDX
|
||||
python demo_convert_bdx_byDelay.py #延迟播放器,仅支持BDX
|
||||
```
|
||||
|
||||
运行成功了,哦耶!
|
||||
|
||||
<img height="512" src="https://foruda.gitee.com/images/1665933366784631363/db9f80f6_9911226.jpeg">
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
|
||||
## 运行环境安装
|
||||
|
||||
### 检验Python运行环境
|
||||
|
||||
0. 一般的Linux发行版都有安装Python环境,我们只需要保证其版本即可,理论上 ≥Python3.6 都可以运行我们的库
|
||||
|
||||
我们可以使用
|
||||
|
||||
```bash
|
||||
python -V
|
||||
```
|
||||
|
||||
来查看 Python 版本,如下
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1665120915821957090/429561fd_9911226.png>
|
||||
|
||||
1. *非必要环节*:回退版本
|
||||
|
||||
如果你跟作者一样,觉得 Python 3.10+ 太难用很烦人的话,那真是皆大欢喜,让我们一起来回退版本吧!
|
||||
|
||||
- pacman 包管理器(多用于Arch Linux上)
|
||||
|
||||
1. 让我们先来把 python3 加入忽略升级的列表中,使用`vim`修改`/etc/pacman.conf`,在`IgnorePkg`后加上`python3`
|
||||
|
||||
```bash
|
||||
sudo vim /etc/pacman.conf
|
||||
```
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1665124611490335193/5e99ca26_9911226.png>
|
||||
|
||||
2. 然后我们开始从[Arch Achieve](https://archive.archlinux.org/packages/)上找Python的版本列表。(*这里说明一下,在Arch中,Python默认指的是Python3,而与其他某些Linux发行版中Python默认指代Python2不同,所以在Arch Achieve中也是如此。*)我这里找到的是[Python3.8.6](https://archive.archlinux.org/packages/p/python/python-3.8.6-1-x86_64.pkg.tar.zst),于是我们用`pacman`把她下载下来并安装:
|
||||
|
||||
```bash
|
||||
sudo pacman -U https://archive.archlinux.org/packages/p/python/python-3.8.6-1-x86_64.pkg.tar.zst
|
||||
```
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1665126362769399903/ea4b9598_9911226.png>
|
||||
|
||||
3. 完美!
|
||||
|
||||
- 其他包管理器
|
||||
|
||||
暂无
|
||||
|
||||
### 检查并安装pip包管理器依赖
|
||||
|
||||
1. 我们在安装依赖库之前,应该确认一下,Python自带的包管理器pip是否安装到位:
|
||||
|
||||
```bash
|
||||
python -m pip # 确认pip是否安装
|
||||
# 当这个命令输入后有长段提示出现则为已经安装
|
||||
|
||||
# 如果返回如下,那么则pip尚未安装
|
||||
/usr/bin/python: No module named pip
|
||||
# 可以使用如下命令来安装pip
|
||||
sudo pacman -S python-pip
|
||||
# 安装完成后记得验证
|
||||
python -m pip
|
||||
|
||||
|
||||
# 如果还是失败,那么就需要用其他工具安装pip:
|
||||
wget https://bootstrap.pypa.io/get-pip.py
|
||||
sudo python get-pip.py
|
||||
# 安装完成后一定要验证!!!
|
||||
python -m pip
|
||||
```
|
||||
|
||||
2. 确认完成之后,我们来安装一下依赖库:
|
||||
|
||||
```bash
|
||||
pip install mido -i https://mirrors.aliyun.com/pypi/simple/
|
||||
pip install brotli -i https://mirrors.aliyun.com/pypi/simple/
|
||||
```
|
||||
|
||||
3. 安装成功后可能会见到类似下图的提示:
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662737676719454287/f61a70f7_9911226.png">
|
||||
|
||||
|
||||
## 本代码库的下载与使用
|
||||
|
||||
1. 使用Git下载本库及其示例代码
|
||||
|
||||
```bash
|
||||
git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git MSCTpkgver
|
||||
```
|
||||
|
||||
当上述命令执行成功,你会在执行此命令的所在位置发现一个名为 `MSCTpkgver` 的文件夹,其中包含的正是我们心心念念下载的本程序和示例代码。
|
||||
而我们要运行的也正是示例代码,因此,赶快进入下载到的文件夹:
|
||||
|
||||
```bash
|
||||
cd MSCTpkgver
|
||||
```
|
||||
|
||||
1. 开始使用
|
||||
|
||||
在目录下打开终端,执行以下命令:(选择你需要的)
|
||||
|
||||
```bash
|
||||
python demo_convert.py #计分板播放器,支持mcpack与BDX
|
||||
python demo_convert_bdx_byDelay.py #延迟播放器,仅支持BDX
|
||||
```
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
## 一、运行环境安装
|
||||
|
||||
### (一)安装 Python3.6+
|
||||
|
||||
1. 首先需要下载Python的安装包,最好是 *Python3.8*,因为作者就用的是这个版本
|
||||
|
||||
> [下载64位Python安装包](https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe)
|
||||
> [下载32位Python安装包](https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe)
|
||||
|
||||
2. 在安装时,最好需要勾选 `Add Python 3.X to PATH`,如下图所示,当然,如果您对自己非常自信,您也可以手动设置此项目:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1662736520757331846/e38efb81_9911226.png>
|
||||
|
||||
- 若您对Python一知半解或者不怎么了解、并对自己的系统盘(通常是C盘)有大约150*兆字节*(MB)的信心的话,您可以在安装时直接选择*快速安装*(Install Now)
|
||||
|
||||
3. 若您选择了*自定义安装*(Customize Installation),请务必勾选 `pip` 和 `py launcher` 便于后续安装依赖,如下图:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1662736621235871190/2ac3d98f_9911226.png>
|
||||
|
||||
4. 安装结束之后可以在*终端*(命令行/PowerShell/Bash/etc)中输入:python 试试是否安装成功,成功安装之后,在终端中输入python会显示诸如如下图片的提示:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659972669907359295/cmd.png>
|
||||
|
||||
|
||||
### (二)安装依赖
|
||||
|
||||
1. 请以管理员模式打开您的*终端*(命令行/PowerShell/Bash/etc)
|
||||
|
||||
例如,命令行,可以如此打开:在*视窗开始菜单*(Windows开始)中搜索 `cmd`, 并以管理员身份运行
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662736878650993886/62487dd8_9911226.png">
|
||||
|
||||
2. 打开了终端之后,请在终端中输入以下指令
|
||||
|
||||
```bash
|
||||
pip install mido -i https://mirrors.aliyun.com/pypi/simple/
|
||||
pip install brotli -i https://mirrors.aliyun.com/pypi/simple/
|
||||
```
|
||||
|
||||
3. 安装成功后您可能会见到类似下图的提示:
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1662737676719454287/f61a70f7_9911226.png">
|
||||
|
||||
## 二、本工具的下载与使用
|
||||
|
||||
0. 下载本代码库以及演示程序
|
||||
|
||||
- 若您使用git,请直接克隆本仓库:
|
||||
|
||||
```bash
|
||||
git clone -b pkgver https://gitee.com/EillesWan/Musicreater.git
|
||||
```
|
||||
|
||||
- 若您不使用git,可以在[*码云*(Gitee)](https://gitee.com/EillesWan/Musicreater.git)或[*GitHub*](https://github.com/EillesWan/Musicreater.git)下载zip包,或者[加入QQ群聊861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr),在群文件中获取。
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1669540786443169766/fabf0acd_9911226.png" >
|
||||
|
||||
值得注意的是,这张图上有1、2两个数字,虽然是手写的,但确实是数字,表示着要进行的步骤。希望眼尖得能找出我的口头禅的你们能够发现这两个用鼠标手写的数字并在安装时认真地执行。我认为这并不算十分的难,移动鼠标并单击大约消耗不了多少卡路里,不过我没有进行精确的计算,我也不是十分的清楚这个活动对于一个常人来讲有多难,但我怀疑它不难。
|
||||
|
||||
|
||||
1. 开始使用
|
||||
|
||||
在目录下打开终端。
|
||||
|
||||
例如:打开命令行:请进入到目录下,在文件资源管理器的地址框内输入`cmd`:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659974437388532868/输入.png>
|
||||
<img src=https://foruda.gitee.com/images/1659974754378201859/输入c.png>
|
||||
|
||||
执行以下命令:(选择你需要的)
|
||||
|
||||
```bash
|
||||
python demo_convert.py #计分板播放器,支持mcpack与BDX
|
||||
python demo_convert_bdx_byDelay.py #延迟播放器,仅支持BDX
|
||||
```
|
||||
|
||||
## 三、安装时错误的补充说明
|
||||
|
||||
1. Microsoft Visual C++ Redistributable 环境出错
|
||||
|
||||
如果你遇到了类似以下这种情况:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659972789779764953/bug.jpeg>
|
||||
|
||||
请下载最新的VCREDIST安装包,可以参照[这个网页](https://docs.microsoft.com/zh-CN/cpp/windows/latest-supported-vc-redist)的说明,也可以在这直接选择你需要的安装包下载:
|
||||
> [下载64位VCREDIST安装包](https://aka.ms/vs/17/release/vc_redist.x64.exe)
|
||||
> [下载32位VCREDIST安装包](https://aka.ms/vs/17/release/vc_redist.x86.exe)
|
||||
|
||||
感谢群友Mono帮我们发现这个问题。
|
||||
105
docs/功能使用说明.md
105
docs/功能使用说明.md
@@ -1,105 +0,0 @@
|
||||
<h1 align="center">音·创 Musicreater</h1>
|
||||
|
||||
<h2 align="center">库版 Package Version</h2>
|
||||
|
||||
<p align="center">
|
||||
<img width="128" height="128" src="https://s1.ax1x.com/2022/05/06/Ouhghj.md.png" >
|
||||
</p>
|
||||
|
||||
# 演示程序使用教程
|
||||
|
||||
*由于先前的 **读我文件**(README.md) 过于冗杂,现另辟蹊径来给大家全方位的教程。*
|
||||
|
||||
*这是演示程序(demo)的使用教程,将在这里提供演示程序的相应的使用教程*
|
||||
|
||||
## 下载与启动教程
|
||||
|
||||
### [视窗(Windows)操作系统](./download%26atart/Windows.md)
|
||||
### [里纽克斯(Linux)操作系统](./download%26atart/Linux.md)
|
||||
### [安卓(Android)与安卓衍生操作系统](./download%26atart/Android.md)
|
||||
|
||||
## 演示程序使用教程
|
||||
|
||||
1. 参数说明
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659974810147043475/运行.png>
|
||||
|
||||
- midi路径:含有mid文件路径、文件名、后缀的完整文件路径,或者一个目录(demo可接受批量转换)。可以使用相对或绝对路径皆可
|
||||
|
||||
- 输出路径:输出文件夹的路径,不需要指示文件名
|
||||
|
||||
- 是否重置计分板:`1`或`0`(歌曲放完是否重置,推荐`1`)
|
||||
|
||||
- 进度条:是否启用进度条,以及自定义进度条样式。输入`0`或`False`表示不启用进度条,输入`1`或`True`表示使用默认进度条,其余的输入均表示使用输入的格式作为自定义的进度条样式
|
||||
|
||||
若不支持自定义,则仅能输入`0`或`1`表示“关闭”或“开启”
|
||||
|
||||
- 计分板名称:游戏内的计分板名称
|
||||
|
||||
- 音量:0-1之间的小数(含0,1)正常来说推荐`1`
|
||||
|
||||
- 速度倍率:小数数据,其值不可为0,一般写`1`
|
||||
|
||||
- 玩家选择器:包括 `@x` 在内的全部选择器,即若要选择全部标签为`Holo`的玩家,则需要如此输入:`@a[tag=Holo]`
|
||||
|
||||
- 没有报错且在输出路径下找到mcpack或bdx即为生成成功:
|
||||
|
||||
<img src=https://foruda.gitee.com/images/1659973655881460036/输出.png>
|
||||
|
||||
|
||||
# 其他说明
|
||||
|
||||
## 对于 延迟播放器 的说明
|
||||
|
||||
问1:什么是延迟播放器?
|
||||
|
||||
答1:播放音乐,不同的音符之间存在间隔,可以用不同的方式实现音符间空白的时间。其一是计分板,通过给计分板加分,对应分数播放对应的音符就可以间隔到,还有就是命令方块自带的延迟,这样也可以实现音符间空白。延迟播放器即后者,但是因为只能对命令方块写入这样的延迟数据,所以仅可以使用包含NBT的结构导出或者直接输出至世界。
|
||||
|
||||
问2:可不可以不要积分板?
|
||||
|
||||
答2:详见问1,切换你所需要的播放器即可。
|
||||
|
||||
## 对于 进度条自定义 功能的说明
|
||||
|
||||
因为我们提供了可以自动转换进度条的功能,因此在这里给出进度条自定义参数的详细解释。
|
||||
|
||||
请注意,并非所有的演示样例程序都支持自定义进度条。
|
||||
|
||||
一个进度条,明显地,有**固定部分**和**可变部分**来构成。而可变部分又包括了文字和图形两种(当然,《我的世界》里头的进度条,可变的图形也就是那个“条”了)。这一点你需要了解,因为后文中包含了很多这方面的概念需要你了解。
|
||||
|
||||
进度条的自定义功能使用一个字符串来定义自己的样式,其中包含众多**标识符**来表示可变部分。
|
||||
|
||||
标识符如下(注意大小写):
|
||||
|
||||
| 标识符 | 指定的可变量 |
|
||||
|---------|----------------|
|
||||
| `%%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'))`
|
||||
|
||||
*对了!为了避免生成错误,请尽量避免使用标识符作为定义样式字符串的其他部分*
|
||||
|
||||
180
docs/新手答疑指南.md
180
docs/新手答疑指南.md
@@ -1,180 +0,0 @@
|
||||
<h1 align="center">音·创 Musicreater</h1>
|
||||
|
||||
<h2 align="center">库版 Package Version</h2>
|
||||
|
||||
<p align="center">
|
||||
<img width="128" height="128" src="https://s1.ax1x.com/2022/05/06/Ouhghj.md.png" >
|
||||
</p>
|
||||
|
||||
# 新手答疑指南
|
||||
|
||||
**考虑到某些用户电脑技术不是特别先进,且对这个项目充满了好奇心,但是又了解的不是很充分,
|
||||
为此,我特别在这里写一份文档,解答各位的好奇心。放心,本文件全程中文,英文版本随后更新!**
|
||||
|
||||
## 第一部分 关于音·创的作用
|
||||
|
||||
### 1.1 音·创简介
|
||||
|
||||
音·创 Musicreater 是一款免费开源的 **《我的世界:基岩版》** 音乐制作软件
|
||||
|
||||
音·创 库版 (Musicreater Package Version) 是一款免费开源的针对 **《我的世界:基岩版》** 的midi音乐转换库
|
||||
|
||||
音·创 采用的是**带有特殊条款的Apache2.0**开源协议,详情请见[这里](https://gitee.com/EillesWan/Musicreater/blob/master/LICENSE.md)。
|
||||
|
||||
音·创
|
||||
目前已经具备较为完善的**教程**,如果你还不知道音·创有教程,请点击
|
||||
[
|
||||
这里](https://gitee.com/EillesWan/Musicreater/blob/pkgver/docs/%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md)。
|
||||
|
||||
### 1.2 音·创到底目前有什么功能?
|
||||
* - [x] 支持导入.mid文件
|
||||
* - [x] 支持写入.mcpack文件
|
||||
* - [x] 支持写入.bdx文件
|
||||
|
||||
|
||||
* 不支持导入.mp3 .mp4 .wav等音频流文件
|
||||
|
||||
## 第二部分 关于格式的问题
|
||||
|
||||
### 2.1 关于.mid格式
|
||||
其实对于经常玩音乐电子制作的朋友们来说,mid格式并不陌生,这里我简单介绍一下。
|
||||
|
||||
> mid格式是由MIDI继承而来。MID文件并不是一段录制好的声音,而是记录声音的信息,然后再告诉声卡如何再现音乐的一组指令。
|
||||
> 这样一个MIDI文件每存1分钟的音乐只用大约5~10KB。今天,MID文件主要用于原始乐器作品、流行歌曲的业余表演、游戏音轨以及电子贺卡等。
|
||||
>
|
||||
> ——百度百科
|
||||
>
|
||||
> MIDI 音乐,保存在电脑上,就是 *.mid 类型的文件。和一般意义上的“音乐”不同,mid 类型的音乐通常并不是可直接发行供大众欣赏的音乐,
|
||||
> 它更像是一种音乐创作者使用的工程文件。它没有歌词,不含有人类语言。如果说五线谱是给人类阅读的乐谱,
|
||||
> MIDI音乐文件便是给计算机或其他电子设备使用的乐谱。对于“音乐”这个世界来说,它微不足道,却又是现代数字音乐的基石。虽不为大众所知,
|
||||
> 但在 MIDI 音乐爱好者眼中,它却是非常有意思的东西。有了 MIDI 音乐技术和一台电脑,基本就等于拥有了一个乐队,加上相关的音乐知识,
|
||||
> 就可以自己指挥这个“乐队”,创作音乐作品了!
|
||||
> 同时,MIDI 技术由于数据结构简单,又与音乐有关,也成为了部分技术极客的爱好。有人使用MIDI技术+Arduino开源硬件制作了架子鼓,
|
||||
> 有人通过分析大量MIDI乐曲结构,设计了人工智能作曲软件,还有更酷的人使用MIDI音乐制作了随节奏变幻的特斯拉线圈!
|
||||
> 在MIDI 音乐的世界里,汇聚了一批喜欢音乐又热爱技术的人。我们有理由相信,玩MIDI音乐的你,定是多才多艺的。
|
||||
>
|
||||
> ——midishow.com
|
||||
|
||||
**所以,mid文件的本质是电子乐谱,而不是记录声音波形文件的.mp3/.wav/.m4a等等文件!**
|
||||
|
||||
### 2.2 关于.mid格式的获取
|
||||
|
||||
通过刚刚的介绍,你可能已经发现,*.mid文件因为受众并不多而并没有被广泛熟知,因而你之前可能完全没见过这个文件,更何况要弄一首自己心仪的歌了。
|
||||
|
||||
这里介绍几个获取.mid格式的方法:
|
||||
|
||||
1. 最简单的方法就是成为一个作编曲的人,当然,很多人做不到这一点,但是有必要提到这一点,当你在下面的渠道中都无法获得想要的文件时,
|
||||
你应该考虑是不是需要自己创作内容,或者,请别人帮你创作内容。
|
||||
2. 当你没有这样的文件时,问问别人或者从群里下在公告的免费的也是个思路,不过这个办法通常使用次数有限。
|
||||
3. 自己找mid:现在,我将给你提供一个完整的找mid的方法,请认真学习:
|
||||
**1.** 首先你需要在www.midishow.com中注册一个账号,并不复杂,你可能只需要一个QQ号。
|
||||
**2.** 登录你的账号,主界面应该如下图所示:
|
||||
<img src="https://foruda.gitee.com/images/1672644995747340749/36c9c143_10062986.png">
|
||||
**3.** 在显眼的搜索框中,输入你想要的歌曲名称,接下来的教程,我以`夜空中最亮的星`这首歌及它的mid来演示下载流程。点击搜索框,完成这一步。
|
||||
<img src="https://foruda.gitee.com/images/1672645340943813483/44d0db69_10062986.png">
|
||||
**4.** 接下来看到搜索结果如下,你可以点进去一个听听,决定你是否要下载;也有可能你什么都没搜到,那你就得换首歌或者换个途径了。
|
||||
<img src="https://foruda.gitee.com/images/1672645574402099694/6b7e18e5_10062986.png">
|
||||
**5.** 点击播放按钮试听,网站上的效果可能一般,但是会听音乐的人应该很快就能决定你是否需要下载这个音乐。如果需要下载,你可以进行到下一步,
|
||||
如果不行,那你可以退回刚刚的页面换一个。
|
||||
<img src="https://foruda.gitee.com/images/1672645752246438160/47cead78_10062986.png">
|
||||
**6.** 翻到最下面,如图,你可以对这首歌进行打分,打分可以使积分+1,建议打5分;你可以对这首歌进行评论,一次有意义的评论可以+3分。
|
||||
下载一首歌需要-3积分,如果你先完成了这两项操作再下载,那你还会再赚1积分。所以推荐这样做!
|
||||
<img src="https://foruda.gitee.com/images/1672646433045265565/26ea29b2_10062986.png">
|
||||
**完成后会像这样:**
|
||||
<img src="https://foruda.gitee.com/images/1672646242419857480/5e8809b8_10062986.png">
|
||||
**7.** 接下来下载,往上翻网页,找到这个标识,然后单击。
|
||||
<img src="https://foruda.gitee.com/images/1672646275215822535/63b402db_10062986.png">
|
||||
**8.** 确认完毕后点击下载。
|
||||
<img src="https://foruda.gitee.com/images/1672646309787744490/f459adac_10062986.png">
|
||||
**9.** 完成下载,如图:
|
||||
<img src="https://foruda.gitee.com/images/1672646335942429563/2449ed0b_10062986.png">
|
||||
4. 使用mp3转换为mid的工具:不得不说,科技的进步带来了许多便利,让这样困难的事情也变得简单。如果上述方法仍然没有解决你的问题,
|
||||
那么你可以在下一章节中找到有关这个途径的说明。
|
||||
|
||||
### 2.3 .mp3格式转换为.mid格式
|
||||
|
||||
**注意,使用这个技术有一定难度,酌情使用!**
|
||||
|
||||
概述:mp3转mid需要把**模拟的波形频谱信号转为数字乐谱信号**,这个过程**一定有损失**。
|
||||
|
||||
请各位以后不要在答疑群中问类似于我这个转换效果为什么不好这样的问题,谢谢。
|
||||
|
||||
如果直接用**widi**的话相当于对声音进行了**傅里叶变换**,你确实可以分离出其中的音高,但是效果在不同情况下差异较大,
|
||||
尤其是有架子鼓啊啥的玩也的时候,比较**差**。
|
||||
([widi工具链接](https://pan.baidu.com/s/1j_Jui0piQ6rMOXM0GJtqTg) 提取码:b0lw )
|
||||
|
||||
**如果只有钢琴的谱子需要分离,有一个完美的选择**:[这里](https://zhuanlan.zhihu.com/p/270999354)
|
||||
|
||||
如果不然有其他的乐器也需要分离,那么可能就有点困难,像cakewalk就确实也可以吧音频变成mid,但是可能要
|
||||
**先把原MP3分离成人声音轨、贝斯音轨等再傅里叶变换。**
|
||||
|
||||
当然我也可能了解的不全,没准现在已经有传新的技术可以分离的更好了,那就太棒了!(〃'▽'〃)
|
||||
|
||||
另外,我们开发者也象征性的找了一些mp3转mid的网站,我们没使用过,不担保效果。
|
||||
[https://www.serocs.cn/transcription/](https://www.serocs.cn/transcription/)
|
||||
|
||||
同时,midishow论坛里有一些大佬也提供了解决方案,看看他们的发言也是一个不错的选择。
|
||||
|
||||
我就只给个论坛链接了,经常有人问这种问题,你可以去那里随便找到一篇帖子看看。
|
||||
[论坛](https://www.midishow.com/question)
|
||||
|
||||
### 2.4 输出格式的问题
|
||||
|
||||
在前面说到,输出主要有`.mcpack`和`.bdx`文件的输出,接下来我会围绕这两个文件进行简单的说明。
|
||||
|
||||
#### 2.4.1 .mcpack是什么
|
||||
|
||||
输出.mcpack文件其实对于一个**资深基岩版我的世界玩家**应该并不陌生。
|
||||
|
||||
.mcpack文件其实就是我的世界基岩版的附加包,里面一般分为行为包和材质包
|
||||
|
||||
我们生成的命令组属于**行为包** (下图就是一个例子)
|
||||
|
||||
<img src="https://foruda.gitee.com/images/1672647779755793187/884abaa9_10062986.png">
|
||||
|
||||
如果你是国际电脑版基岩玩家就像我一样,是可以直接打开这个文件,并将这个包导入我的世界的。
|
||||
|
||||
关于怎么使用,请看[**这里**](https://gitee.com/EillesWan/Musicreater/blob/pkgver/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是什么
|
||||
|
||||
.bdx 文件其实是FastBuilder这款软件的结构文件,可以导入到我的世界。
|
||||
|
||||
由于这不属于官方文件,且我并不是很熟悉这个结构,所以请对这个格式有问题的好兄弟加一下QQ群,问问群里负责导入的大佬。
|
||||
|
||||
## 第三部分 关于其他问题
|
||||
|
||||
**由于开发者们都很忙,群友们的耐心也都有限,所以恳请大家提出有意义的问题。这里附一个关于提问方法的链接,大家可以看看。**
|
||||
|
||||
[提问的智慧](https://github.com/tvvocold/How-To-Ask-Questions-The-Smart-Way)
|
||||
|
||||
希望不要我把这个文件在聊天中甩给你,那说明我可能已经没有耐心了。
|
||||
|
||||
看完这份说明,如果你打算开始使用我们的工具的话,请移步至[这里](https://gitee.com/EillesWan/Musicreater/blob/pkgver/docs/%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md)。
|
||||
|
||||
## 结尾
|
||||
|
||||
### 作者\<*金羿*\>(Eilles)联系方式
|
||||
|
||||
1. QQ 2647547478
|
||||
2. 电邮 EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
3. 微信 WYI_DoctorYI
|
||||
4. Telegram [@EillesWan](https://t.me/EillesWan)
|
||||
|
||||
### 作者\<*诸葛亮与八卦阵*\>(bgArray)联系方式
|
||||
|
||||
1. QQ 4740437765
|
||||
|
||||
**欢迎加群:[861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)**
|
||||
|
||||
**欢迎加群:[861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)**
|
||||
|
||||
**欢迎加群:[861684859](https://jq.qq.com/?_wv=1027&k=hpeRxrYr)**
|
||||
|
||||
(重要的事情说三遍)
|
||||
|
||||
**(有能力的同志麻烦给仓库star一下)**
|
||||
|
||||
**(有能力的同志麻烦给仓库star一下)**
|
||||
|
||||
**(有能力的同志麻烦给仓库star一下)**
|
||||
@@ -1,32 +0,0 @@
|
||||
<h1 align="center">音·创 Musicreater</h1>
|
||||
|
||||
<h2 align="center">库版 Package Version</h2>
|
||||
|
||||
<p align="center">
|
||||
<img width="128" height="128" src="https://s1.ax1x.com/2022/05/06/Ouhghj.md.png" >
|
||||
</p>
|
||||
|
||||
# 生成文件的使用说明
|
||||
|
||||
*由于先前的 **读我文件**(README.md) 过于冗杂,现另辟蹊径来给大家全方位的教程。*
|
||||
|
||||
*这是本库生成后文件的相关说明,不是使用本库的教程,若要查看**本库的演示程序**使用教程,可点击[此处](%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E.md)*
|
||||
|
||||
## 文件格式
|
||||
|
||||
1. 附加包格式(`.mcpack`)
|
||||
|
||||
使用附加包格式导出音乐,则音乐会以指令函数文件(`.mcfunction`)存储于附加包内。在附加包中,函数文件的存储结构应为:
|
||||
|
||||
- `functions\`
|
||||
- `index.mcfunction`
|
||||
- `mscply\`
|
||||
- `progressShow.mcfunction`
|
||||
- `track1.mcfunction`
|
||||
- `track2.mcfunction`
|
||||
- ...
|
||||
- `trackN.mcfunction`
|
||||
|
||||
如图,其中,`index.mcfunction`文件和`mscply`文件夹存在于函数目录的根下;在`mscply`目录中,包含音乐导出的众多音轨播放文件(`trackX.mcfunction`),同时,若生成此包时选择了带有进度条的选项,则会包含`progressShow.mcfunction`文件。
|
||||
|
||||
`index.mcfunction`用于开始播放,其中包含打开各个音轨对应函数的指令,以及加分指令,这里的加分,是将**播放计分板的值大于等于`1`**的所有**玩家**的播放计分板分数增加`1`。同时,若生成此包时选择了自动重置计分板的选项,则会包含一条重置计分板的指令。
|
||||
@@ -1,18 +0,0 @@
|
||||
# THIS PROGRAM IS ONLY A TEST EXAMPLE
|
||||
|
||||
|
||||
from msctPkgver.main import *
|
||||
|
||||
convertion = midiConvert()
|
||||
convertion.convert(input('请输入midi文件路径:'), input('请输入输出路径:'))
|
||||
for i in convertion.toBDXfile(
|
||||
1,
|
||||
input('请输入作者:'),
|
||||
bool(int(input('是否开启进度条(1|0):'))),
|
||||
int(input('请输入指令结构最大生成高度:')),
|
||||
input('请输入计分板名称:'),
|
||||
float(input('请输入音量(0-1]:')),
|
||||
float(input('请输入速度倍率:')),
|
||||
bool(int(input('是否自动重置计分板(1|0):'))),
|
||||
):
|
||||
print(i)
|
||||
@@ -1,24 +0,0 @@
|
||||
# THIS PROGRAM IS ONLY A TEST EXAMPLE
|
||||
|
||||
|
||||
from msctPkgver.main import *
|
||||
|
||||
convertion = midiConvert()
|
||||
convertion.convert(input("请输入midi文件路径:"), input("请输入输出路径:"))
|
||||
print(
|
||||
convertion.tomcpack(
|
||||
3,
|
||||
bool(int(input("是否自动重置计分板(1|0):"))),
|
||||
bool(int(input("是否开启进度条(1|0):"))),
|
||||
input("请输入计分板名称:"),
|
||||
float(input("请输入音量(0-1):")),
|
||||
float(input("请输入速度倍率:")),
|
||||
)
|
||||
)
|
||||
|
||||
# for the test
|
||||
# if __name__ == '__main__':
|
||||
# convertion = midiConvert()
|
||||
# convertion.convert(r"C:\Users\lc\Documents\MuseScore3\乐谱\乐谱\victory.mid", ".")
|
||||
# convertion.tomcpack(
|
||||
# 1, True, True, "scb", 1, 1)
|
||||
@@ -1,22 +0,0 @@
|
||||
# THIS PROGRAM IS ONLY A TEST EXAMPLE
|
||||
|
||||
|
||||
from msctPkgver.main import *
|
||||
|
||||
convertion = midiConvert()
|
||||
convertion.convert(input('请输入midi文件路径:'), input('请输入输出路径:'))
|
||||
convertion.tomcpack(
|
||||
1,
|
||||
bool(int(input('是否自动重置计分板(1|0):'))),
|
||||
bool(int(input('是否开启进度条(1|0):'))),
|
||||
input('请输入计分板名称:'),
|
||||
float(input('请输入音量(0-1):')),
|
||||
float(input('请输入速度倍率:')),
|
||||
)
|
||||
|
||||
# for the test
|
||||
# if __name__ == '__main__':
|
||||
# convertion = midiConvert()
|
||||
# convertion.convert(r"C:\Users\lc\Documents\MuseScore3\乐谱\乐谱\victory.mid", ".")
|
||||
# convertion.tomcpack(
|
||||
# 1, True, True, "scb", 1, 1)
|
||||
170
fcwslib/__init__.py
Normal file
170
fcwslib/__init__.py
Normal file
@@ -0,0 +1,170 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
|
||||
# 统计:致命(三级)错误:2个---未解决;警告(二级)错误:2个;语法(一级)错误:17个
|
||||
|
||||
|
||||
__version__ = '0.0.1'
|
||||
__all__ = []
|
||||
__author__ = 'Fuckcraft <https://gitee.com/fuckcraft>'
|
||||
|
||||
'''
|
||||
Fuckcraft Websocket Library (FCWSLIB)
|
||||
A library to develop minecraft websocket server easily.
|
||||
|
||||
Copyright (C) 2021 Fuckcraft
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
'''
|
||||
|
||||
from main import *
|
||||
|
||||
# import os
|
||||
import json
|
||||
import uuid
|
||||
# import logging
|
||||
import asyncio
|
||||
import time
|
||||
import websockets
|
||||
|
||||
|
||||
# 写这段代码的时候,只有我和上帝知道这段代码是干什么的。
|
||||
# 现在只有上帝知道。
|
||||
# ----
|
||||
# 没毛病,我讨厌两种人:一种是要我写注释的人,一种是给我代码看但没有写注释的人。
|
||||
|
||||
# 此函数用于向 Minecraft 订阅请求
|
||||
async def subscribe(websocket, event_name):
|
||||
"""
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: event_name : 需要订阅的请求 :
|
||||
|
||||
返回:
|
||||
None
|
||||
"""
|
||||
|
||||
response = {
|
||||
'body': {
|
||||
'eventName': str(event_name) # 示例:PlayerMessage
|
||||
},
|
||||
'header': {
|
||||
'requestId': str(uuid.uuid4()),
|
||||
'messagePurpose': 'subscribe',
|
||||
'version': 1,
|
||||
'messageType': 'commandRequest'
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
|
||||
# 此函数用于向 Minecraft 消除订阅请求
|
||||
async def unsubscribe(webscket):
|
||||
"""
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: event_name : 需要消除订阅的请求 :
|
||||
|
||||
返回:
|
||||
None
|
||||
"""
|
||||
print(webscket)
|
||||
|
||||
response = {
|
||||
"body": {
|
||||
"eventName": str(event_name) # PlayerMessage
|
||||
},
|
||||
"header": {
|
||||
"requestId": str(uuid.uuid4()),
|
||||
"messagePurpose": "unsubscribe",
|
||||
"version": 1,
|
||||
"messageType": "commandRequest"
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
|
||||
# 此函数用于向 Minecraft 执行命令
|
||||
async def send_command(websocket, command):
|
||||
"""
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: command : 执行的命令 :
|
||||
|
||||
返回:
|
||||
None
|
||||
"""
|
||||
|
||||
response = {
|
||||
'body': {
|
||||
'origin': {
|
||||
'type': 'player'
|
||||
},
|
||||
'commandLine': str(command),
|
||||
'version': 1
|
||||
},
|
||||
'header': {
|
||||
'requestId': str(uuid.uuid4()),
|
||||
'messagePurpose': 'commandRequest',
|
||||
'version': 1,
|
||||
'messageType': 'commandRequest'
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
|
||||
# 此函数用于向 Minecraft 发送消息
|
||||
async def tellraw(websocket, message):
|
||||
"""
|
||||
参数:
|
||||
: websocket : websocket 对象 :
|
||||
: message : 发送的消息 :
|
||||
|
||||
返回:
|
||||
None
|
||||
"""
|
||||
|
||||
command = {
|
||||
'rawtext': [
|
||||
{
|
||||
'text': '[{}] {}'.format(time.asctime(), message)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# 增加 json 可读性
|
||||
# command = json.dumps(command, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
command = json.dumps(command)
|
||||
command = 'tellraw @a {}'.format(command)
|
||||
|
||||
await send_command(websocket, command)
|
||||
|
||||
|
||||
def run_server(function):
|
||||
# 修改 ip 地址和端口
|
||||
start_server = websockets.serve(function, 'localhost', 8080)
|
||||
asyncio.get_event_loop().run_until_complete(start_server)
|
||||
asyncio.get_event_loop().run_forever()
|
||||
160
fcwslib/main.py
Normal file
160
fcwslib/main.py
Normal file
@@ -0,0 +1,160 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
__version__ = '0.0.1'
|
||||
__all__ = ['run_server', 'subscribe', 'unsubscribe', 'send_command', 'tellraw']
|
||||
__author__ = 'Fuckcraft <https://gitee.com/fuckcraft>'
|
||||
|
||||
'''
|
||||
Fuckcraft Websocket Library (FCWSLIB)
|
||||
A library to develop minecraft websocket server easily.
|
||||
|
||||
Copyright (C) 2021 Fuckcraft
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
'''
|
||||
|
||||
import os
|
||||
import json
|
||||
import uuid
|
||||
import logging
|
||||
import asyncio
|
||||
import time
|
||||
import websockets
|
||||
|
||||
# 写这段代码的时候,只有我和上帝知道这段代码是干什么的。
|
||||
# 现在只有上帝知道。
|
||||
|
||||
# 此函数用于向 Minecraft 订阅请求
|
||||
async def subscribe(websocket, event_name):
|
||||
'''
|
||||
输入:
|
||||
: websocket : websocket 对象 :
|
||||
: event_name : 需要订阅的请求 :
|
||||
|
||||
输出:
|
||||
None
|
||||
'''
|
||||
|
||||
response = {
|
||||
'body': {
|
||||
'eventName': str(event_name) # 示例:PlayerMessage
|
||||
},
|
||||
'header': {
|
||||
'requestId': str(uuid.uuid4()),
|
||||
'messagePurpose': 'subscribe',
|
||||
'version': 1,
|
||||
'messageType': 'commandRequest'
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
# 此函数用于向 Minecraft 消除订阅请求
|
||||
async def unsubscribe(webscket):
|
||||
'''
|
||||
输入:
|
||||
: websocket : websocket 对象 :
|
||||
: event_name : 需要消除订阅的请求 :
|
||||
|
||||
输出:
|
||||
None
|
||||
'''
|
||||
|
||||
response = {
|
||||
"body": {
|
||||
"eventName": str(event_name) # 示例:PlayerMessage
|
||||
},
|
||||
"header": {
|
||||
"requestId": str(uuid.uuid4()),
|
||||
"messagePurpose": "unsubscribe",
|
||||
"version": 1,
|
||||
"messageType": "commandRequest"
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
# 我个人不负责这块的质量,因为他们逼迫我违心的写了这段代码
|
||||
|
||||
# 此函数用于向 Minecraft 执行命令
|
||||
async def send_command(websocket, command):
|
||||
'''
|
||||
输入:
|
||||
: websocket : websocket 对象 :
|
||||
: command : 执行的命令 :
|
||||
|
||||
输出:
|
||||
None
|
||||
'''
|
||||
|
||||
response = {
|
||||
'body': {
|
||||
'origin': {
|
||||
'type': 'player'
|
||||
},
|
||||
'commandLine': str(command),
|
||||
'version': 1
|
||||
},
|
||||
'header': {
|
||||
'requestId': str(uuid.uuid4()),
|
||||
'messagePurpose': 'commandRequest',
|
||||
'version': 1,
|
||||
'messageType': 'commandRequest'
|
||||
}
|
||||
}
|
||||
|
||||
# 增加 json 的可读性
|
||||
# response = json.dumps(response, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
response = json.dumps(response)
|
||||
|
||||
await websocket.send(response)
|
||||
|
||||
# 此函数用于向 Minecraft 发送消息
|
||||
async def tellraw(websocket, message):
|
||||
'''
|
||||
输入:
|
||||
: websocket : websocket 对象 :
|
||||
: message : 发送的消息 :
|
||||
|
||||
输出:
|
||||
None
|
||||
'''
|
||||
|
||||
command = {
|
||||
'rawtext':[
|
||||
{
|
||||
'text':'[{}] {}'.format(time.asctime(), message)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# 增加 json 可读性
|
||||
# command = json.dumps(command, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False)
|
||||
command = json.dumps(command)
|
||||
command = 'tellraw @a {}'.format(command)
|
||||
|
||||
await send_command(websocket, command)
|
||||
|
||||
def run_server(function):
|
||||
# 修改 ip 地址和端口
|
||||
start_server = websockets.serve(function, 'localhost', 8080)
|
||||
asyncio.get_event_loop().run_until_complete(start_server)
|
||||
asyncio.get_event_loop().run_forever()
|
||||
|
||||
BIN
fcwslib/版权声明.png
Normal file
BIN
fcwslib/版权声明.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
0
languages/__init__.py
Normal file
0
languages/__init__.py
Normal file
BIN
languages/__pycache__/__init__.cpython-37.pyc
Normal file
BIN
languages/__pycache__/__init__.cpython-37.pyc
Normal file
Binary file not shown.
BIN
languages/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
languages/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
BIN
languages/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
languages/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
languages/__pycache__/enGB.cpython-38.pyc
Normal file
BIN
languages/__pycache__/enGB.cpython-38.pyc
Normal file
Binary file not shown.
BIN
languages/__pycache__/lang.cpython-37.pyc
Normal file
BIN
languages/__pycache__/lang.cpython-37.pyc
Normal file
Binary file not shown.
BIN
languages/__pycache__/lang.cpython-38.pyc
Normal file
BIN
languages/__pycache__/lang.cpython-38.pyc
Normal file
Binary file not shown.
BIN
languages/__pycache__/lang.cpython-39.pyc
Normal file
BIN
languages/__pycache__/lang.cpython-39.pyc
Normal file
Binary file not shown.
BIN
languages/__pycache__/zhCN.cpython-37.pyc
Normal file
BIN
languages/__pycache__/zhCN.cpython-37.pyc
Normal file
Binary file not shown.
BIN
languages/__pycache__/zhCN.cpython-38.pyc
Normal file
BIN
languages/__pycache__/zhCN.cpython-38.pyc
Normal file
Binary file not shown.
BIN
languages/__pycache__/zhCN.cpython-39.pyc
Normal file
BIN
languages/__pycache__/zhCN.cpython-39.pyc
Normal file
Binary file not shown.
13
languages/autosave.tmp.txt
Normal file
13
languages/autosave.tmp.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
zh-ME
|
||||
喵喵文 中国大陆
|
||||
Meow Catsese, China Mainland
|
||||
喵喵喵~ 祖国喵~
|
||||
金羿,Email EillesWan@outlook.com,QQ 2647547478
|
||||
音创创喵~
|
||||
音·创 Musicreater
|
||||
音创创喵的主人们
|
||||
凌天之云创新我的世界开发团队\n×\n凌天之云创新计算机应用软件开发团队
|
||||
~ 主人们 ~
|
||||
~ 爸爸妈妈们 ~
|
||||
好哒~
|
||||
|
||||
99
languages/const2string.py
Normal file
99
languages/const2string.py
Normal file
@@ -0,0 +1,99 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
'''此功能已废弃'''
|
||||
|
||||
|
||||
|
||||
|
||||
# W-YI 金羿
|
||||
# QQ 2647547478
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 Team-Ryoun 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray")
|
||||
# 若需转载或借鉴 请附作者
|
||||
|
||||
|
||||
"""
|
||||
Copyright 2022 Team-Ryoun 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray")
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
# 代码写的并非十分的漂亮,还请大佬多多包涵;本软件源代码依照Apache软件协议公开
|
||||
|
||||
# -----------------------------分割线-----------------------------
|
||||
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
|
||||
# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:12个
|
||||
# 目前我的Pycharm并没有显示任何错误,有错误可以向:
|
||||
# bgArray 诸葛亮与八卦阵
|
||||
# QQ 474037765 或最好加入:音·创 开发交流群 861684859
|
||||
# ------------------------- split line-----------------------------
|
||||
# Zhuge Liang and Bagua array help to modify the grammar date: -- January 19, 2022
|
||||
# Statistics: fatal (Level 3) errors: 0; Warning (Level 2) errors: 15; Syntax (Level 1) error: 597
|
||||
# At present, my Pycham does not display any errors. If there are errors, you can report them to me
|
||||
# Bgarray Zhuge Liang and Bagua array
|
||||
# QQ 474037765 or better join: Musicreater development exchange group 861684859
|
||||
# ------------------------- split line-----------------------------
|
||||
|
||||
# 下面为正文
|
||||
|
||||
|
||||
# 将程序中用双引号""括起来的字符串
|
||||
# 转为字符串列表 list[str, str, ...]
|
||||
# 方便进行语言翻译支持。
|
||||
|
||||
import sys
|
||||
startWith = 0
|
||||
|
||||
|
||||
def __main__():
|
||||
textList = []
|
||||
for fileName in sys.argv[1:]:
|
||||
print('读取文件: {}'.format(fileName))
|
||||
fileText = []
|
||||
for line in open(fileName, 'r', encoding='utf-8'):
|
||||
while line.count('"') >= 2:
|
||||
# 只有上帝看得懂我在写什么。
|
||||
if line[
|
||||
line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])] in textList:
|
||||
thisText = textList.index(
|
||||
line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])])
|
||||
else:
|
||||
thisText = len(textList)
|
||||
textList.append(
|
||||
line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])])
|
||||
line = line.replace(
|
||||
line[line.index('"'):2 + line[line.index('"') + 1:].index('"') + len(line[:line.index('"')])],
|
||||
'READABLETEXT[{}]'.format(thisText + startWith)
|
||||
)
|
||||
fileText.append(line)
|
||||
|
||||
open(fileName + '_C', 'w', encoding='utf-8').writelines(fileText)
|
||||
|
||||
outFile = open('lang__.py', 'w', encoding='utf-8')
|
||||
outFile.write('''# -*- coding:utf-8 -*-
|
||||
|
||||
# 由金羿翻译工具生成字符串列表
|
||||
# 请在所需翻译文件前from 此文件 import READABLETEXT
|
||||
|
||||
|
||||
|
||||
READABLETEXT = {
|
||||
''')
|
||||
for i in range(len(textList)):
|
||||
outFile.write(" {}:{},\n".format(i + startWith, textList[i]))
|
||||
outFile.write('}')
|
||||
outFile.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
__main__()
|
||||
180
languages/enGB.py
Normal file
180
languages/enGB.py
Normal file
@@ -0,0 +1,180 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
# 由金羿翻译工具生成字符串列表
|
||||
# 请在所需翻译的文件前from 此文件 import READABLETEXT
|
||||
|
||||
|
||||
READABLETEXT = {
|
||||
'Translator': (("Eilles Wan (金羿)", True),),
|
||||
# 此处是语言翻译者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字
|
||||
0: "ERROR❌",
|
||||
1: "TIPS❗",
|
||||
2: "Clearing log(this wont be in the file)",
|
||||
3: "Could not clear the temporary files or logs",
|
||||
4: "saved",
|
||||
5: "New Musicreater Project",
|
||||
6: "Select old-type project",
|
||||
7: "Select Musicreater Project",
|
||||
8: "Cant open:{}, please check if youve entered the right name",
|
||||
9: "Musicreat - About",
|
||||
10: "Musicreater",
|
||||
11: "Ver. {}",
|
||||
12: """Team-Ryoun for Minecraft\n×\nTeam-Ryoun for Software Development""",
|
||||
13: "OK",
|
||||
14: "Inpute Notes",
|
||||
15: (("- Developers -", False),
|
||||
("Eilles Wan (金羿)", True), ("EillesWan@outlook.com", False), ("QQ 2647547478", False),
|
||||
("bgArray “诸葛亮与八卦阵”", True), ("QQ 474037765", False)),
|
||||
# 此处是开发者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字
|
||||
16: "- Translators -",
|
||||
# 17:"",
|
||||
18: "QQ Group: 861684859",
|
||||
19: "Musicreater - Help",
|
||||
20: "Select sound file",
|
||||
21: "Select MIDI file",
|
||||
22: "Select NoteText file",
|
||||
23: "Get Note info",
|
||||
24: "Write in Note info: {}",
|
||||
25: "Select generating file",
|
||||
26: "Select generating folder",
|
||||
27: "Select generating .mcpack file",
|
||||
28: "Input position info",
|
||||
29: "Select generating world folder",
|
||||
30: "Select generating Function Pack",
|
||||
31: "Select .mcfunction file ",
|
||||
32: "Select .bdx file ",
|
||||
33: "DONE✔",
|
||||
34: "Input playing rate",
|
||||
35: "Generating",
|
||||
36: "Select a world folder",
|
||||
37: "Make sure",
|
||||
38: "Generate .RyStruct file",
|
||||
39: "FAILED❌",
|
||||
40: "Report message inpution",
|
||||
41: "Musicreater - {}",
|
||||
42: "ExecutingEntityName: {}",
|
||||
43: "ScoreboardName: {}",
|
||||
44: "Instrument: {}",
|
||||
45: "TrackName: {}",
|
||||
46: "PackName: {}",
|
||||
47: "MusicTitle: {}",
|
||||
48: "IsRepeat?: {}",
|
||||
49: "Player'sTargetSelector: {}",
|
||||
50: "Modify Main Option",
|
||||
51: "Modify Track Option",
|
||||
52: "Default Instrument: Enter English\n",
|
||||
53: "Open...",
|
||||
54: "Open Old Project...",
|
||||
55: "Save",
|
||||
56: "Save as...",
|
||||
57: "Exit",
|
||||
58: "File",
|
||||
59: "Load tracks from sound",
|
||||
60: "Load tracks from Midi",
|
||||
61: "Load tracks from Text",
|
||||
62: "Input notes to track",
|
||||
63: "Edit",
|
||||
64: "Generate file...",
|
||||
65: "Generate function pack...",
|
||||
66: "Generate .mcpack file...",
|
||||
67: "Functions(Pack)",
|
||||
68: "Save music as blocks into a map",
|
||||
69: "Save music as blocks into a exist map...",
|
||||
70: "Save music as commands into a map",
|
||||
71: "Save music as commands into a exist map...",
|
||||
72: "Save music as notebox into a map",
|
||||
73: "Save music as notebox into a exist map...",
|
||||
74: "World",
|
||||
75: "Generate a function that fits current music...",
|
||||
76: "Export selected track as commands in .bdx...",
|
||||
77: "Export .bdx file from map...",
|
||||
78: "Export .RyStruct file from map...",
|
||||
79: "Load functions into a world...",
|
||||
80: "Separate long .mcfunction file into small ones and set them into a world as a chain...",
|
||||
81: "Additional Functions",
|
||||
82: "Show generating result",
|
||||
83: "Set a websocket server on localhost:8080 and play the selected track",
|
||||
84: "Experimental Functions",
|
||||
85: "Clear log file",
|
||||
86: "Clear save file(obsolete)",
|
||||
87: "Help",
|
||||
88: "About",
|
||||
89: "Send a bug report",
|
||||
90: "Q&A",
|
||||
91: "Main Options",
|
||||
92: "Export music as .BDX...",
|
||||
93: "请输入指令链生成最高相对高度(≥5)",
|
||||
94: "❌You should input a number which is not lower then 4, please reinput again.",
|
||||
95: "Structure",
|
||||
96: "Reset Main Options",
|
||||
97: "Track Options",
|
||||
# 98:"",
|
||||
# 99:"",
|
||||
# 100:"",
|
||||
# 101:"",
|
||||
102: "Delete Selected Track",
|
||||
# 103:"",
|
||||
# 104:"",
|
||||
|
||||
105: "Error with finding or reading file😢:{}",
|
||||
106: "Project is unsaved, save before close?",
|
||||
107: "Saved in: {}",
|
||||
108: ("Musicreater 0.0.X Project","Musicreater 0.1+ Project","Musicreater 0.1+ TESTver Project"),
|
||||
109: "Any Type",
|
||||
110: "NoteFunCreater Project",
|
||||
111: "MMFM (V0.0.6) Project",
|
||||
112: "All Types",
|
||||
113: ".MP3 file(piano sound)",
|
||||
114: "Midi file",
|
||||
115: "Text file",
|
||||
116: "Position Inpution",
|
||||
117: "Format Error❌, please Reinput!",
|
||||
118: ".MCFUNCTION",
|
||||
119: "The position of the ChainCB for execution:",
|
||||
# 120: "",
|
||||
121: "您的函数文件不大于一万条指令,无需进行分割操作。",
|
||||
122: "请输入执行链生成相对坐标:",
|
||||
123: "FastBuilder Structure",
|
||||
124: "Done!\n{}",
|
||||
125: "一秒,音乐走几拍?",
|
||||
126: "按下确认后,在游戏中使用connect指令连接localhost:8080,即可播放",
|
||||
127: "请输入区域选择的开始坐标:",
|
||||
128: "请输入区域选择的结束坐标:",
|
||||
129: "Whether air block remain when export?",
|
||||
130: "Musicreater Structure",
|
||||
131: "Done😃\n{}",
|
||||
132: "Failed❌\n{}\n{}",
|
||||
133: "Have not developed yet...",
|
||||
134: "Your name",
|
||||
135: "Your contact",
|
||||
136: "Your description of Problem",
|
||||
137: "Log file will be cleared when you exit.",
|
||||
138: "Log file will NOT be cleared when you exit.",
|
||||
139: "修改包名",
|
||||
140: "修改音乐标题",
|
||||
141: "修改玩家选择器\n注意!要加上中括号“[]”",
|
||||
142: "修改本音轨的执行实体名",
|
||||
143: "修改本音轨所用的积分板",
|
||||
144: "修改本音轨所用乐器",
|
||||
145: "您输入的乐器并非游戏内置乐器,是否继续用您输入的字符作为乐器?",
|
||||
146: "修改本音轨生成的文件名",
|
||||
# -----2022.1.25更新
|
||||
147: "生成新文件至...",
|
||||
148: "从midi导入音轨且用新方法解析",
|
||||
149: "Open New: Musicreater Project...",
|
||||
150: "保存为新项目",
|
||||
151: "另存为新项...",
|
||||
152: "(开发调试)关闭本次日志记录",
|
||||
153: "生成新函数包至...",
|
||||
154: "生成新函数附加包文件至...",
|
||||
155: "生成新函数附加包文件,并将神羽资源包以散包形式放置至...",
|
||||
156: "Select [MiraclePlumeResourcePack]...",
|
||||
157: "没有路径文件(.rpposi文件),请仔细阅读Readme或先试用:帮助与疑问->[神羽资源包位置选择]:选择文件夹... 方法添加路径文件吧!",
|
||||
158: "有路径文件(.rpposi文件),但路径指示错误,请仔细阅读Readme或先用:帮助与疑问->[神羽资源包位置选择]:选择文件夹... 更改路径!",
|
||||
159: "更改路径文件(.rpposi文件)成功!!",
|
||||
160: "从midi导入音轨且用类方法解析",
|
||||
161: "打开 类方法: 音·创项目...",
|
||||
162: "保存为类方法项目",
|
||||
163: "另存为类方法项...",
|
||||
|
||||
}
|
||||
206
languages/lang.py
Normal file
206
languages/lang.py
Normal file
@@ -0,0 +1,206 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
'''对于音·创的语言支持兼语言文件编辑器'''
|
||||
|
||||
"""
|
||||
Copyright 2022 Team-Ryoun
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
DEFAULTLANGUAGE = 'zh-CN'
|
||||
|
||||
LANGUAGELIST = {
|
||||
# 第一个是语言的中文名称和地区
|
||||
# 第二个是语言的英文名称和地区
|
||||
# 第三个是语言的本地名称和地区
|
||||
'zh-CN': (
|
||||
"简体中文 中国大陆",
|
||||
"Simplified Chinese - China Mainland",
|
||||
"简体中文 中国大陆",
|
||||
),
|
||||
'zh-TW': (
|
||||
"繁体中文 中国台湾省",
|
||||
"Traditional Chinese - Taiwan, China",
|
||||
"正體中文,中国台灣省",
|
||||
),
|
||||
# 'zh-HK': (
|
||||
# "繁体中文 香港",
|
||||
# "Traditional Chinese - the Hong Kong Special Administrative Region",
|
||||
# "繁體中文,香港特別行政區",
|
||||
# ),
|
||||
# 'zh-MO': (
|
||||
# "繁体中文 澳门",
|
||||
# "Traditional Chinese - the Macao Special Administrative Region",
|
||||
# "繁體中文,澳門特別行政區",
|
||||
# ),
|
||||
'en-GB': (
|
||||
"英语 英国",
|
||||
"British English - the United Kingdom",
|
||||
"British English - the United Kingdom",
|
||||
),
|
||||
'zh-ME' : (
|
||||
"喵喵文 中国大陆",
|
||||
"Meow Catsese - China Mainland"
|
||||
"喵喵喵~ 祖国喵~"
|
||||
)
|
||||
}
|
||||
|
||||
# 对于旧版本音·创的语言支持
|
||||
# 重构之后将停止使用
|
||||
try:
|
||||
from languages.zhCN import READABLETEXT
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
from msctLib.log import log
|
||||
|
||||
def __loadLanguage(languageFilename: str):
|
||||
with open(languageFilename, 'r', encoding='utf-8') as languageFile:
|
||||
_text = {}
|
||||
for line in languageFile:
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
line = line.split(' ', 1)
|
||||
_text[line[0]] = line[1].replace('\n', '')
|
||||
langkeys = _text.keys()
|
||||
with open(languageFilename.replace(languageFilename[-10:-5], 'zh-CN'), 'r', encoding='utf-8') as defaultLangFile:
|
||||
for line in defaultLangFile:
|
||||
if line.startswith('#'):
|
||||
continue
|
||||
line = line.split(' ', 1)
|
||||
if not line[0] in langkeys:
|
||||
_text[line[0]] = line[1].replace('\n', '')
|
||||
from msctLib.log import log
|
||||
log(f'丢失对于 {line[0]} 的本地化文本', 'WARRING')
|
||||
langkeys = _text.keys()
|
||||
# print(_text)
|
||||
return _text
|
||||
|
||||
|
||||
if not DEFAULTLANGUAGE == 'zh-CN':
|
||||
if DEFAULTLANGUAGE in LANGUAGELIST.keys():
|
||||
_TEXT = __loadLanguage('./languages/' + DEFAULTLANGUAGE + '.lang')
|
||||
else:
|
||||
raise KeyError(f'无法打开默认语言{DEFAULTLANGUAGE}')
|
||||
|
||||
|
||||
def wordTranslate(singleWord: str, debug: bool = False):
|
||||
import requests
|
||||
try:
|
||||
return \
|
||||
requests.post('https://fanyi.baidu.com/sug', data={'kw': f'{singleWord}'}).json()['data'][0]['v'].split(
|
||||
'; ')[0]
|
||||
except:
|
||||
log(f"无法翻译文本{singleWord}", level='WARRING', isPrinted=debug)
|
||||
return None
|
||||
|
||||
|
||||
def _(text: str, debug: bool = False):
|
||||
try:
|
||||
return _TEXT[text]
|
||||
except:
|
||||
if debug:
|
||||
raise KeyError(f'无法找到翻译文本{text}')
|
||||
else:
|
||||
log(f'无法找到本地化文本{text}','ERROR')
|
||||
return ''
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 启动语言编辑器
|
||||
import tkinter as tk
|
||||
from tkinter.filedialog import askopenfilename as askfilen
|
||||
|
||||
LANGNAME = _('LANGLOCALNAME')
|
||||
|
||||
|
||||
def _changeDefaultLang():
|
||||
global _TEXT
|
||||
global DEFAULTLANGUAGE
|
||||
|
||||
fileName = askfilen(title='选择所翻译的语言文件', initialdir=r'./',
|
||||
filetypes=[('音·创语言文件', '.lang'), ('所有文件', '*')],
|
||||
defaultextension='.lang',
|
||||
initialfile='.lang')
|
||||
_TEXT = __loadLanguage(fileName)
|
||||
DEFAULTLANGUAGE = _('LANGKEY')
|
||||
LANGNAME = _('LANGLOCALNAME')
|
||||
|
||||
orignText = ''
|
||||
transText = ''
|
||||
for i, j in _TEXT.items():
|
||||
orignText += i + '\n'
|
||||
transText += j + '\n'
|
||||
|
||||
Origntextbar.insert('end', orignText)
|
||||
Translatetextbar.insert('end', transText)
|
||||
|
||||
global setlangbutton
|
||||
setlangbutton['text'] = f'对标语言{LANGNAME}'
|
||||
|
||||
|
||||
def _autoSave(event=None):
|
||||
with open('autosave.tmp.txt', 'w', encoding='utf-8') as f:
|
||||
f.write(Translatetextbar.get(1.0, 'end'))
|
||||
print(str(event))
|
||||
|
||||
|
||||
root = tk.Tk()
|
||||
|
||||
root.geometry('600x500')
|
||||
|
||||
root.bind("<Motion>", _autoSave)
|
||||
|
||||
nowText = ''
|
||||
|
||||
Orignrame = tk.Frame(root, bd=2)
|
||||
Translaterame = tk.Frame(root, bd=2)
|
||||
|
||||
Orignscrollbar = tk.Scrollbar(Orignrame)
|
||||
Origntextbar = tk.Text(Orignrame, width=35, height=40)
|
||||
|
||||
Translatetextbar = tk.Text(Translaterame, width=40, height=37, undo=True)
|
||||
Translatescrollbar = tk.Scrollbar(Translaterame)
|
||||
|
||||
def ctrlZ():
|
||||
Translatetextbar.edit_undo()
|
||||
Translatetextbar.bind("<Control-z>", ctrlZ)
|
||||
|
||||
def ctrlY():
|
||||
Translatetextbar.edit_redo()
|
||||
Translatetextbar.bind("<Control-y>", ctrlY)
|
||||
|
||||
Translatetextbar.bind("<Control-s>", _autoSave)
|
||||
|
||||
tk.Button(Translaterame, text='保存', command=_autoSave).pack(side='bottom', fill='x')
|
||||
|
||||
tk.Label(Orignrame, text='中文原文').pack(side='top')
|
||||
Origntextbar.pack(side='left', fill='y')
|
||||
Orignscrollbar.pack(side='left', fill='y')
|
||||
|
||||
setlangbutton = tk.Button(Translaterame, text=f'对标语言{LANGNAME}', command=_changeDefaultLang)
|
||||
setlangbutton.pack(side='top')
|
||||
Translatescrollbar.pack(side='right', fill='y')
|
||||
Translatetextbar.pack(side='right', fill='y')
|
||||
|
||||
Orignscrollbar.config(command=Origntextbar.yview)
|
||||
Origntextbar.config(yscrollcommand=Orignscrollbar.set)
|
||||
|
||||
Translatescrollbar.config(command=Translatetextbar.yview)
|
||||
Translatetextbar.config(yscrollcommand=Translatescrollbar.set)
|
||||
|
||||
Orignrame.pack(side='left')
|
||||
Translaterame.pack(side='right')
|
||||
|
||||
tk.mainloop()
|
||||
16
languages/zh-CN.lang
Normal file
16
languages/zh-CN.lang
Normal file
@@ -0,0 +1,16 @@
|
||||
# 音·创 本地化语言文件
|
||||
# 使用 空格 把键与对应文本隔开
|
||||
# 使用 井字符 在每一行的开头编写注释
|
||||
# 注意!井字符请开头放,切勿含有空格
|
||||
# 也切勿在正文结尾放!
|
||||
LANGKEY zh-CN
|
||||
LANGCHINESENAME 简体中文 中国大陆
|
||||
LANGENGLIFHNAME Simplified Chinese, Chinese Mainland
|
||||
LANGLOCALNAME 简体中文 中国大陆
|
||||
MSCT 音·创
|
||||
F音创 音·创 Musicreater
|
||||
关于 音·创 - 关于
|
||||
凌云pairs 凌天之云创新我的世界开发团队\n×\n凌天之云创新计算机应用软件开发团队
|
||||
开发者 - 开发人员 -
|
||||
译者 - 翻译人员 -
|
||||
确定 确定
|
||||
17
languages/zh-ME.lang
Normal file
17
languages/zh-ME.lang
Normal file
@@ -0,0 +1,17 @@
|
||||
# 音创创喵的 本地化语言文件
|
||||
# 使用 空格 把键与对应文本隔开
|
||||
# 使用 井字符 在每一行的开头编写注释
|
||||
# 注意!井字符请开头放,切勿含有空格
|
||||
# 也切勿在正文结尾放!
|
||||
LANGKEY zh-ME
|
||||
LANGCHINESENAME 喵喵文 中国大陆
|
||||
LANGENGLIFHNAME Meow Catsese, China Mainland
|
||||
LANGLOCALNAME 喵喵喵~ 祖国喵~
|
||||
TRANSLATERS 金羿,Email EillesWan@outlook.com,QQ 2647547478
|
||||
MSCT 音创创喵~
|
||||
F音创 音·创 Musicreater
|
||||
关于 音创创喵的主人们
|
||||
凌云pairs 凌天之云创新我的世界开发团队\n×\n凌天之云创新计算机应用软件开发团队
|
||||
开发者 ~ 主人们 ~
|
||||
译者 ~ 爸爸妈妈们 ~
|
||||
确定 好哒~
|
||||
185
languages/zhCN.py
Normal file
185
languages/zhCN.py
Normal file
@@ -0,0 +1,185 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
# 由金羿翻译工具生成字符串列表
|
||||
# 请在所需翻译文件前from 此文件 import READABLETEXT
|
||||
|
||||
|
||||
READABLETEXT = {
|
||||
'Translator': (("金羿 Eilles 原稿", True),),
|
||||
# 此处是语言翻译者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字
|
||||
0: "错误❌",
|
||||
1: "提示❗",
|
||||
2: "清除log(此句不载入日志)",
|
||||
3: "无法清除日志及临时文件",
|
||||
4: "已存储",
|
||||
5: "新建 音·创 项目",
|
||||
6: "请选择旧类型的项目",
|
||||
7: "请选择 音·创 项目",
|
||||
8: "无法打开文件:{},请查看您是否输入正确",
|
||||
9: "音·创 - 关于",
|
||||
10: "音·创 Musicreater",
|
||||
11: "当前版本:{}",
|
||||
12: """凌云我的世界开发团队\n×\n凌云计算机应用软件开发团队""",
|
||||
13: "确定",
|
||||
14: "请输入音符",
|
||||
15: (("- 开发者 -", False),
|
||||
("金羿 Eilles", True), ("EillesWan@outlook.com", False), ("QQ 2647547478", False),
|
||||
("bgArray “诸葛亮与八卦阵”", True), ("QQ 474037765", False),
|
||||
),
|
||||
# 此处是开发者列表,其中每个元组第一项为显示文本,第二项为此文本是否为开发者名字
|
||||
16: "- 翻译者 -",
|
||||
# 17:"",
|
||||
18: "讨论群: 861684859",
|
||||
19: "音·创 - 帮助",
|
||||
20: "请选择钢琴声音的音乐文件",
|
||||
21: "请选择 MIDI 文件",
|
||||
22: "请选择 音符文本 文件",
|
||||
23: "获取音符信息",
|
||||
24: "音符数据写入{}",
|
||||
25: "请选择文件生成的位置",
|
||||
26: "请选择文件夹生成的位置",
|
||||
27: "请选择.mcpack文件生成的位置",
|
||||
28: "坐标信息输入",
|
||||
29: "请选择世界文件夹生成的位置",
|
||||
30: "请选择函数包生成的位置",
|
||||
31: "请选择 .mcfunction 文件",
|
||||
32: "请选择需要生成的.bdx文件",
|
||||
33: "完成✔",
|
||||
34: "输入播放速度",
|
||||
35: "创建中",
|
||||
36: "请选择世界文件夹所在的位置",
|
||||
37: "请确认",
|
||||
38: "生成.RyStruct文件",
|
||||
39: "失败❌",
|
||||
40: "邮件反馈信息输入",
|
||||
41: "音·创 - {}",
|
||||
42: "执行实体名:{}",
|
||||
43: "使用计分板:{}",
|
||||
44: "所用的乐器:{}",
|
||||
45: "当前音轨名:{}",
|
||||
46: "包名:{}",
|
||||
47: "音乐标题:{}",
|
||||
48: "是否重复:{}",
|
||||
49: "玩家选择器:{}",
|
||||
50: "修改主设置",
|
||||
51: "修改节设置",
|
||||
52: "游戏内置乐器如下:请输入英文\n",
|
||||
53: "打开音·创项目...",
|
||||
54: "打开旧项目...",
|
||||
55: "保存项目",
|
||||
56: "另存为...",
|
||||
57: "退出",
|
||||
58: "文件",
|
||||
59: "从钢琴MP3导入音轨",
|
||||
60: "从midi导入音轨",
|
||||
61: "从文本文件导入音轨",
|
||||
62: "输入音符至音轨",
|
||||
63: "编辑",
|
||||
64: "生成文件至...",
|
||||
65: "生成函数包至...",
|
||||
66: "生成附加包文件至...",
|
||||
67: "函数(包)",
|
||||
68: "将音乐以方块存储生成地图",
|
||||
69: "将音乐以方块存储载入地图…",
|
||||
70: "将音乐以指令存储生成地图",
|
||||
71: "将音乐以指令存储载入地图…",
|
||||
72: "将音乐以音符盒存储生成地图",
|
||||
73: "将音乐以音符盒存储载入地图…",
|
||||
74: "世界",
|
||||
75: "生成符合当前音乐的函数播放器…",
|
||||
76: "将选中音轨以指令存储生成.bdx文件…",
|
||||
77: "由地图导出至.bdx文件…",
|
||||
78: "由地图导出至.RyStruct文件…",
|
||||
79: "将函数载入世界…",
|
||||
80: "将大函数分割并建立执行链…",
|
||||
81: "辅助功能",
|
||||
82: "展示生成结果",
|
||||
83: "建立位于localhost:8080上的websocket服务器播放选中音轨",
|
||||
84: "实验性功能",
|
||||
85: "清除日志文件",
|
||||
86: "清除早期版本的存储文件",
|
||||
87: "帮助",
|
||||
88: "关于",
|
||||
89: "发送错误日志反馈",
|
||||
90: "帮助与疑问",
|
||||
91: "音乐总设置(项目设置)",
|
||||
# =============================================================此处有新增
|
||||
92: "将音乐导出为BDX",
|
||||
93: "请输入指令链生成最高相对高度(≥5)",
|
||||
94: "您输入的数据有误❌,相对高度请输入一个不小于4的值,请重新输入。",
|
||||
95: "结构操作",
|
||||
96: "重置项目设置",
|
||||
97: "当前音轨设置(段落设置)",
|
||||
# 98:"",
|
||||
# 99:"",
|
||||
# 100:"",
|
||||
# 101:"",
|
||||
102: "删除选中音轨",
|
||||
# 103:"",
|
||||
# 104:"",
|
||||
105: "找不到或无法读取文件😢:{}",
|
||||
106: "您当前的项目已修改但未存储,是否先保存当前项目?",
|
||||
107: "项目已经存储至:{}",
|
||||
108: ("音·创0.0.X工程文件", "音·创0.1+工程文件", "音·创0.1+TEST工程文件"),
|
||||
109: "任意类型",
|
||||
110: "函数音创工程文件",
|
||||
111: "MMFM0.0.6版本工程文件",
|
||||
112: "全部类型",
|
||||
113: "钢琴声音的音频文件",
|
||||
114: "Midi文件",
|
||||
115: "文本文件",
|
||||
116: "请输入坐标:",
|
||||
117: "您输入的格式有误❌,请重新输入。",
|
||||
118: "我的世界指令函数文件",
|
||||
119: "请输入执行链生成坐标:",
|
||||
# 120: "",
|
||||
121: "您的函数文件不大于一万条指令,无需进行分割操作。",
|
||||
122: "请输入执行链生成相对坐标:",
|
||||
123: "FastBuilder结构文件",
|
||||
124: "转换结束!\n{}",
|
||||
125: "一秒,音乐走几拍?",
|
||||
126: "按下确认后,在游戏中使用connect指令连接localhost:8080,即可播放",
|
||||
127: "请输入区域选择的开始坐标:",
|
||||
128: "请输入区域选择的结束坐标:",
|
||||
129: "所选区块导出时是否需要保留空气方块?",
|
||||
130: "音·创结构文件",
|
||||
131: "文件已生成\n{}",
|
||||
132: "文件无法生成\n{}\n{}",
|
||||
133: "本功能尚未开发。",
|
||||
134: "您的称呼",
|
||||
135: "您的联系方式",
|
||||
136: "您对问题的描述",
|
||||
137: "在程序结束后将清除日志及临时文件信息。",
|
||||
138: "在程序结束后将不会清除日志及临时文件信息。",
|
||||
139: "修改包名",
|
||||
140: "修改音乐标题",
|
||||
141: "修改玩家选择器\n注意!要加上中括号“[]”",
|
||||
142: "修改本音轨的执行实体名",
|
||||
143: "修改本音轨所用的积分板",
|
||||
144: "修改本音轨所用乐器",
|
||||
145: "您输入的乐器并非游戏内置乐器,是否继续用您输入的字符作为乐器?",
|
||||
146: "修改本音轨生成的文件名",
|
||||
# -----2022.1.25更新
|
||||
147: "生成乐器文件至...",
|
||||
148: "从midi导入音轨且用新方法解析",
|
||||
# 149: "打开 新: 音·创项目...",
|
||||
# 150: "保存为新项目",
|
||||
# 151: "另存为新项...",
|
||||
152: "(开发调试)关闭本次日志记录",
|
||||
153: "生成乐器函数包至...",
|
||||
154: "生成乐器函数附加包文件至...",
|
||||
155: "生成乐器函数附加包文件,并将神羽资源包以散包形式放置至...",
|
||||
156: "[神羽资源包位置选择]:选择文件夹...",
|
||||
157: "没有路径文件(.rpposi文件),请仔细阅读Readme或先试用:帮助与疑问->[神羽资源包位置选择]:选择文件夹... 方法添加路径文件吧!",
|
||||
158: "有路径文件(.rpposi文件),但路径指示错误,请仔细阅读Readme或先用:帮助与疑问->[神羽资源包位置选择]:选择文件夹... 更改路径!",
|
||||
159: "更改路径文件(.rpposi文件)成功!!",
|
||||
160: "从midi导入音轨且用类方法解析",
|
||||
# 161: "打开 类方法: 音·创项目...",
|
||||
# 162: "保存为类方法项目",
|
||||
# 163: "另存为类方法项...",
|
||||
164: "生成新文件至...",
|
||||
165: "生成新函数包至...",
|
||||
166: "生成新函数附加包文件至...",
|
||||
167: "!!!这个midi文件读取不了,mido解析报错!!!"
|
||||
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB |
343
magicDemo.py
343
magicDemo.py
@@ -1,343 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
|
||||
|
||||
|
||||
"""
|
||||
音·创 库版 MIDI转换示例程序
|
||||
Musicreater Package Version : Demo for Midi Conversion
|
||||
|
||||
Copyright 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 ./Lisence.md
|
||||
Terms & Conditions: ./Lisence.md
|
||||
"""
|
||||
|
||||
languages = {
|
||||
"ZH_CN": {
|
||||
"MSCT": "音·创",
|
||||
"ChooseLang": "选择语言",
|
||||
"LangChd": "当前语言已经切换为",
|
||||
"ZH_CN": "简体中文",
|
||||
"ZH_TW": "繁体中文(台湾)",
|
||||
"EN_GB": "英语(英国)",
|
||||
"EN_US": "英语(美国)",
|
||||
":": ":",
|
||||
",": ",",
|
||||
".": "。",
|
||||
"ChooseFileFormat": "请输入输出格式[BDX(1)或MCPACK(0)]",
|
||||
"ChoosePlayer": "请选择播放方式[计分板(1) 或 延迟(0)]",
|
||||
"ChoosePath": "请输入MIDI路径或所在文件夹",
|
||||
"WhetherArgEntering": "是否为文件夹内文件的转换统一参数[是(1) 或 否(0)]",
|
||||
"EnterArgs": "请输入转换参数",
|
||||
"noteofArgs": "注:文件夹内的全部midi将统一以此参数转换",
|
||||
"ChooseSbReset": "是否自动重置计分板[是(1) 或 否(0)]",
|
||||
"WhetherCstmProgressBar": "是否自定义进度条[是(1) 或 否(0)]",
|
||||
"EnterProgressBarStyle": "请输入进度条样式",
|
||||
"EnterSbName": "请输入计分板名称",
|
||||
"EnterVolume": "请输入音量大小(0~1)",
|
||||
"EnterSpeed": "请输入速度倍率",
|
||||
"EnterAuthor": "请输入作者",
|
||||
"EnterMaxHeight": "请输入指令结构最大生成高度",
|
||||
"ErrEnter": "输入错误",
|
||||
"Re-Enter": "请重新输入",
|
||||
"Dealing": "正在处理",
|
||||
"FileNotFound": "文件(夹)不存在",
|
||||
"ChooseOutPath": "请输入结果输出路径",
|
||||
"EnterSelecter": "请输入播放者选择器",
|
||||
"Saying": "言·论",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
if sys.argv.__len__() > 0:
|
||||
currentLang = sys.argv[0]
|
||||
if not currentLang in languages.keys():
|
||||
currentLang = "ZH_CN"
|
||||
else:
|
||||
currentLang = "ZH_CN"
|
||||
|
||||
|
||||
def _(__):
|
||||
'''
|
||||
`languages`
|
||||
'''
|
||||
return languages[currentLang][__]
|
||||
|
||||
|
||||
import os
|
||||
import random
|
||||
import datetime
|
||||
|
||||
from msctPkgver.main import *
|
||||
|
||||
try:
|
||||
from rich.console import Console
|
||||
except ModuleNotFoundError as E:
|
||||
if input("您需要安装 Rich 模块才能使用这个样例\n请问是否安装?(y/n)").lower() in ('y', '1'):
|
||||
os.system("pip install Rich -i https://mirrors.aliyun.com/pypi/")
|
||||
from rich.console import Console
|
||||
else:
|
||||
raise E
|
||||
|
||||
try:
|
||||
import zhdate
|
||||
except ModuleNotFoundError as E:
|
||||
if input("您需要安装 zhdate 模块才能使用这个样例\n请问是否安装?(y/n)").lower() in ('y', '1'):
|
||||
os.system("pip install zhdate -i https://mirrors.aliyun.com/pypi/")
|
||||
import zhdate
|
||||
else:
|
||||
raise E
|
||||
|
||||
|
||||
try:
|
||||
import requests
|
||||
except ModuleNotFoundError as E:
|
||||
if input("您需要安装 requests 模块才能使用这个样例\n请问是否安装?(y/n)").lower() in ('y', '1'):
|
||||
os.system("pip install requests -i https://mirrors.aliyun.com/pypi/")
|
||||
import requests
|
||||
else:
|
||||
raise E
|
||||
|
||||
|
||||
MainConsole = Console()
|
||||
|
||||
MainConsole.print(
|
||||
"[#121110 on #F0F2F4] ",
|
||||
style="#121110 on #F0F2F4",
|
||||
justify="center",
|
||||
)
|
||||
|
||||
|
||||
# 显示大标题
|
||||
MainConsole.rule(title="[bold #AB70FF]欢迎使用音·创独立转换器", characters="=", style="#26E2FF")
|
||||
MainConsole.rule(
|
||||
title="[bold #AB70FF]Welcome to Independent Musicreater Convernter", characters="-"
|
||||
)
|
||||
|
||||
|
||||
# 显示箴言部分
|
||||
MainConsole.print(
|
||||
"[#121110 on #F0F2F4]"
|
||||
+ random.choice(
|
||||
requests.get(
|
||||
"https://gitee.com/EillesWan/Musicreater/raw/master/resources/myWords.txt"
|
||||
)
|
||||
.text.strip("\r\n")
|
||||
.split("\r\n")
|
||||
),
|
||||
style="#121110 on #F0F2F4",
|
||||
justify="center",
|
||||
)
|
||||
|
||||
|
||||
from typing import Any, Literal, Optional, TextIO
|
||||
|
||||
JustifyMethod = Literal["default", "left", "center", "right", "full"]
|
||||
OverflowMethod = Literal["fold", "crop", "ellipsis", "ignore"]
|
||||
|
||||
# 高级的打印函数
|
||||
def prt(
|
||||
*objects: Any,
|
||||
sep: str = " ",
|
||||
end: str = "\n",
|
||||
justify: Optional[JustifyMethod] = None,
|
||||
overflow: Optional[OverflowMethod] = None,
|
||||
no_wrap: Optional[bool] = None,
|
||||
emoji: Optional[bool] = None,
|
||||
markup: Optional[bool] = None,
|
||||
highlight: Optional[bool] = None,
|
||||
width: Optional[int] = None,
|
||||
height: Optional[int] = None,
|
||||
crop: bool = True,
|
||||
soft_wrap: Optional[bool] = None,
|
||||
new_line_start: bool = False,
|
||||
) -> None:
|
||||
"""打印到控制台。
|
||||
|
||||
Args:
|
||||
objects (位置性的args): 要记录到终端的对象。
|
||||
sep (str, 可选): 要在打印数据之间写入的字符串。默认为""。
|
||||
end (str, optio可选nal): 在打印数据结束时写入的字符串。默认值为"\\\\n"。
|
||||
style (Union[str, Style], 可选): 应用于输出的样式。默认为`None`。
|
||||
justify (str, 可选): 校正位置,可为"default", "left", "right", "center" 或 "full". 默认为`None`。
|
||||
overflow (str, 可选): 控制溢出:"ignore"忽略, "crop"裁剪, "fold"折叠, "ellipsis"省略号。默认为`None`。
|
||||
no_wrap (Optional[bool], 可选): 禁用文字包装。默认为`None`。
|
||||
emoji (Optional[bool], 可选): 启用表情符号代码,或使用控制台默认的`None`。默认为`None`。
|
||||
markup (Optional[bool], 可选): 启用标记,或`None`使用控制台默认值。默认为`None`。
|
||||
highlight (Optional[bool], 可选): 启用自动高亮,或`None`使用控制台默认值。默认为`None`。
|
||||
width (Optional[int], 可选): 输出的宽度,或`None`自动检测。默认为`None`。
|
||||
crop (Optional[bool], 可选): 裁剪输出到终端的宽度。默认为`True`。
|
||||
soft_wrap (bool, 可选): 启用软包装模式,禁止文字包装和裁剪,或`None``用于 控制台默认值。默认为`None`。
|
||||
new_line_start (bool, False): 如果输出包含多行,在开始时插入一个新行。默认值为`False`。
|
||||
"""
|
||||
MainConsole.print(
|
||||
*objects,
|
||||
sep=sep,
|
||||
end=end,
|
||||
style="#F0F2F4 on #121110",
|
||||
justify=justify,
|
||||
overflow=overflow,
|
||||
no_wrap=no_wrap,
|
||||
emoji=emoji,
|
||||
markup=markup,
|
||||
highlight=highlight,
|
||||
width=width,
|
||||
height=height,
|
||||
crop=crop,
|
||||
soft_wrap=soft_wrap,
|
||||
new_line_start=new_line_start,
|
||||
)
|
||||
|
||||
|
||||
prt(f"{_('LangChd')}{_(':')}{_(currentLang)}")
|
||||
|
||||
# 高级的输入函数
|
||||
def ipt(
|
||||
*objects: Any,
|
||||
sep: str = " ",
|
||||
justify: Optional[JustifyMethod] = None,
|
||||
overflow: Optional[OverflowMethod] = None,
|
||||
no_wrap: Optional[bool] = None,
|
||||
emoji: Optional[bool] = None,
|
||||
markup: Optional[bool] = None,
|
||||
highlight: Optional[bool] = None,
|
||||
width: Optional[int] = None,
|
||||
height: Optional[int] = None,
|
||||
crop: bool = True,
|
||||
soft_wrap: Optional[bool] = None,
|
||||
new_line_start: bool = False,
|
||||
password: bool = False,
|
||||
stream: Optional[TextIO] = None,
|
||||
) -> str:
|
||||
"""显示一个提示并等待用户的输入。
|
||||
|
||||
它的工作方式与Python内建的 :func:`input` 函数相同,如果Python内建的 :mod:`readline` 模块先前已经加载,则提供详细的行编辑和历史功能。
|
||||
|
||||
Args:
|
||||
objects (位置性的args): 要记录到终端的对象。
|
||||
sep (str, 可选): 要在打印数据之间写入的字符串。默认为""。
|
||||
end (str, optio可选nal): 在打印数据结束时写入的字符串。默认值为"\\\\n"。
|
||||
style (Union[str, Style], 可选): 应用于输出的样式。默认为`None`。
|
||||
justify (str, 可选): 校正位置,可为"default", "left", "right", "center" 或 "full". 默认为`None`。
|
||||
overflow (str, 可选): 控制溢出:"ignore"忽略, "crop"裁剪, "fold"折叠, "ellipsis"省略号。默认为`None`。
|
||||
no_wrap (Optional[bool], 可选): 禁用文字包装。默认为`None`。
|
||||
emoji (Optional[bool], 可选): 启用表情符号代码,或使用控制台默认的`None`。默认为`None`。
|
||||
markup (Optional[bool], 可选): 启用标记,或`None`使用控制台默认值。默认为`None`。
|
||||
highlight (Optional[bool], 可选): 启用自动高亮,或`None`使用控制台默认值。默认为`None`。
|
||||
width (Optional[int], 可选): 输出的宽度,或`None`自动检测。默认为`None`。
|
||||
crop (Optional[bool], 可选): 裁剪输出到终端的宽度。默认为`True`。
|
||||
soft_wrap (bool, 可选): 启用软包装模式,禁止文字包装和裁剪,或`None``用于 控制台默认值。默认为`None`。
|
||||
new_line_start (bool, False): 如果输出包含多行,在开始时插入一个新行。默认值为`False`。
|
||||
password (bool, 可选): 隐藏已经输入的文案,默认值为`False`。
|
||||
stream (TextIO, 可选): 可选从文件中读取(而非控制台),默认为 `None`。
|
||||
|
||||
Returns:
|
||||
str: 从stdin读取的字符串
|
||||
"""
|
||||
MainConsole.print(
|
||||
*objects,
|
||||
sep=sep,
|
||||
end="",
|
||||
style="#F0F2F4 on #121110",
|
||||
justify=justify,
|
||||
overflow=overflow,
|
||||
no_wrap=no_wrap,
|
||||
emoji=emoji,
|
||||
markup=markup,
|
||||
highlight=highlight,
|
||||
width=width,
|
||||
height=height,
|
||||
crop=crop,
|
||||
soft_wrap=soft_wrap,
|
||||
new_line_start=new_line_start,
|
||||
)
|
||||
|
||||
return MainConsole.input("", password=password, stream=stream)
|
||||
|
||||
|
||||
def formatipt(notice: str, fun, errnote: str = "", *extraArg):
|
||||
'''循环输入,以某种格式
|
||||
notice: 输入时的提示
|
||||
fun: 格式函数
|
||||
errnote: 输入不符格式时的提示
|
||||
*extraArg: 对于函数的其他参数'''
|
||||
while True:
|
||||
result = ipt(notice)
|
||||
try:
|
||||
funresult = fun(result, *extraArg)
|
||||
break
|
||||
except:
|
||||
prt(errnote)
|
||||
continue
|
||||
return result, funresult
|
||||
|
||||
|
||||
# 获取midi列表
|
||||
while True:
|
||||
midipath = ipt(f"{_('ChoosePath')}{_(':')}").lower()
|
||||
if os.path.exists(midipath):
|
||||
if os.path.isfile(midipath):
|
||||
midis = (midipath,)
|
||||
elif os.path.isdir(midipath):
|
||||
midis = tuple(
|
||||
(
|
||||
os.path.join(midipath, i)
|
||||
for i in os.listdir(midipath)
|
||||
if i.lower().endswith('.mid') or i.lower().endswith('.midi')
|
||||
)
|
||||
)
|
||||
else:
|
||||
prt(f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}")
|
||||
continue
|
||||
else:
|
||||
prt(f"{_('FileNotFound')}{_(',')}{_('Re-Enter')}{_('.')}")
|
||||
continue
|
||||
break
|
||||
|
||||
# 获取输出地址
|
||||
outpath = formatipt(
|
||||
f"{_('ChooseOutPath')}{_(':')}",
|
||||
os.path.exists,
|
||||
f"{_('FileNotFound')}{_(',')}{_('Re-Enter')}{_('.')}",
|
||||
).lower()
|
||||
|
||||
|
||||
# 选择输出格式
|
||||
while True:
|
||||
fileFormat = ipt(f"{_('ChooseFileFormat')}{_(':')}").lower()
|
||||
if fileFormat in ('0', 'mcpack'):
|
||||
fileFormat = 0
|
||||
prt(_("EnterArgs"))
|
||||
if len(midis) > 1:
|
||||
prt(_("noteofArgs"))
|
||||
|
||||
elif fileFormat in ('1', 'bdx'):
|
||||
fileFormat = 1
|
||||
while True:
|
||||
playerFormat = ipt(f"{_('ChoosePlayer')}{_(':')}").lower()
|
||||
if playerFormat in ('0', '延迟'):
|
||||
playerFormat = 0
|
||||
elif playerFormat in ('1', '计分板'):
|
||||
playerFormat = 1
|
||||
else:
|
||||
prt(f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}")
|
||||
continue
|
||||
break
|
||||
else:
|
||||
prt(f"{_('ErrEnter')}{_(',')}{_('Re-Enter')}{_('.')}")
|
||||
continue
|
||||
break
|
||||
|
||||
|
||||
if fileFormat == 0:
|
||||
pass
|
||||
|
||||
|
||||
MainConsole.input()
|
||||
67
magicFun.py
67
magicFun.py
@@ -1,67 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需转载或借鉴 请依照 Apache 2.0 许可证进行许可
|
||||
|
||||
|
||||
"""
|
||||
音·创 库版 MIDI转换示例程序
|
||||
Musicreater Package Version : Demo for Midi Conversion
|
||||
|
||||
Copyright 2022 all the developers of Musicreater
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
from rich.console import Console
|
||||
|
||||
|
||||
MainConsole = Console()
|
||||
|
||||
import requests
|
||||
import random
|
||||
|
||||
|
||||
# 欸嘿!
|
||||
while True:
|
||||
|
||||
MainConsole.print(
|
||||
"[#121110 on #F0F2F4] ",
|
||||
style="#121110 on #F0F2F4",
|
||||
justify="center",
|
||||
)
|
||||
|
||||
|
||||
MainConsole.rule(title="[bold #AB70FF]欢迎使用音·创独立转换器", characters="=", style="#26E2FF")
|
||||
MainConsole.rule(
|
||||
title="[bold #AB70FF]Welcome to Independent Musicreater Convernter", characters="-"
|
||||
)
|
||||
|
||||
|
||||
MainConsole.print(
|
||||
"[#121110 on #F0F2F4]"
|
||||
+ random.choice(
|
||||
requests.get(
|
||||
"https://gitee.com/EillesWan/Musicreater/raw/master/resources/myWords.txt"
|
||||
)
|
||||
.text.strip("\r\n")
|
||||
.split("\r\n")
|
||||
),
|
||||
style="#121110 on #F0F2F4",
|
||||
justify="center",
|
||||
)
|
||||
|
||||
MainConsole.print()
|
||||
153
mid_analyse.py
153
mid_analyse.py
@@ -1,153 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################################################################
|
||||
# Form generated from reading UI file 'mid_analyse.ui'
|
||||
##
|
||||
# Created by: Qt User Interface Compiler version 6.4.1
|
||||
##
|
||||
# WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||
##########################################################################
|
||||
|
||||
# from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||
# QMetaObject, QObject, QPoint, QRect,
|
||||
# QSize, QTime, QUrl, Qt)
|
||||
# from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||
# QFont, QFontDatabase, QGradient, QIcon,
|
||||
# QImage, QKeySequence, QLinearGradient, QPainter,
|
||||
# QPalette, QPixmap, QRadialGradient, QTransform)
|
||||
# from PySide6.QtWidgets import (QApplication, QGroupBox, QHBoxLayout, QLabel,
|
||||
# QLineEdit, QPushButton, QSizePolicy, QWidget)
|
||||
|
||||
import sys
|
||||
from PySide6.QtWidgets import QApplication, QWidget, QGroupBox, QPushButton, \
|
||||
QLabel, QLineEdit, QHBoxLayout, QFileDialog
|
||||
from PySide6.QtCore import QRect, QMetaObject, Slot
|
||||
|
||||
|
||||
class Ui_Form(QWidget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.groupBox = None
|
||||
self.horizontalLayout = None
|
||||
self.horizontalLayoutWidget = None
|
||||
self.close_button = None
|
||||
self.fileChoseButton = None
|
||||
self.input_button = None
|
||||
self.note_count_label = None
|
||||
self.note_count_shower = None
|
||||
self.output_button = None
|
||||
|
||||
def setupUi(self, Form):
|
||||
if not Form.objectName():
|
||||
Form.setObjectName(u"Form")
|
||||
Form.resize(582, 355)
|
||||
self.groupBox = QGroupBox(Form)
|
||||
self.groupBox.setObjectName(u"groupBox")
|
||||
self.groupBox.setGeometry(QRect(10, 0, 561, 311))
|
||||
self.fileChoseButton = QPushButton(self.groupBox)
|
||||
self.fileChoseButton.setObjectName(u"file_chose_button")
|
||||
self.fileChoseButton.setGeometry(QRect(10, 20, 75, 24))
|
||||
self.note_count_label = QLabel(self.groupBox)
|
||||
self.note_count_label.setObjectName(u"note_count_label")
|
||||
self.note_count_label.setGeometry(QRect(20, 50, 54, 16))
|
||||
self.note_count_shower = QLineEdit(self.groupBox)
|
||||
self.note_count_shower.setObjectName(u"note_count_shower")
|
||||
self.note_count_shower.setGeometry(QRect(70, 50, 113, 20))
|
||||
self.horizontalLayoutWidget = QWidget(Form)
|
||||
self.horizontalLayoutWidget.setObjectName(u"horizontalLayoutWidget")
|
||||
self.horizontalLayoutWidget.setGeometry(QRect(10, 310, 561, 41))
|
||||
self.horizontalLayout = QHBoxLayout(self.horizontalLayoutWidget)
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||
self.input_button = QPushButton(self.horizontalLayoutWidget)
|
||||
self.input_button.setObjectName(u"input_button")
|
||||
|
||||
self.horizontalLayout.addWidget(self.input_button)
|
||||
|
||||
self.output_button = QPushButton(self.horizontalLayoutWidget)
|
||||
self.output_button.setObjectName(u"output_button")
|
||||
|
||||
self.horizontalLayout.addWidget(self.output_button)
|
||||
|
||||
self.close_button = QPushButton(self.horizontalLayoutWidget)
|
||||
self.close_button.setObjectName(u"close_button")
|
||||
|
||||
self.horizontalLayout.addWidget(self.close_button)
|
||||
|
||||
Form.setWindowTitle("Mid解析器")
|
||||
|
||||
self.groupBox.setTitle("mid信息")
|
||||
self.fileChoseButton.setText("选择文件")
|
||||
self.note_count_label.setText("音符数")
|
||||
self.input_button.setText("导入")
|
||||
self.output_button.setText("导出分析")
|
||||
self.close_button.setText("关闭")
|
||||
|
||||
QMetaObject.connectSlotsByName(Form)
|
||||
|
||||
# self.ui.btnCalculate.clicked.connect(self.fileLoading)
|
||||
|
||||
def fileLoading(self):
|
||||
filePath, _ = QFileDialog.getOpenFileName(
|
||||
self.groupBox, # 父窗口对象
|
||||
"选择文件", # 标题
|
||||
r"./", # 起始目录
|
||||
"mid类型 (*.mid *.midi)" # 选择类型过滤项,过滤内容在括号中
|
||||
)
|
||||
print(filePath)
|
||||
|
||||
@Slot()
|
||||
def on_fileChoseButton_clicked(self):
|
||||
filePath, _ = QFileDialog.getOpenFileName(
|
||||
self.groupBox, # 父窗口对象
|
||||
"选择文件", # 标题
|
||||
r"./", # 起始目录
|
||||
"mid类型 (*.mid *.midi)" # 选择类型过滤项,过滤内容在括号中
|
||||
)
|
||||
print(filePath)
|
||||
|
||||
|
||||
class MidAnalyseGui(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.ui = Ui_Form()
|
||||
self.ui.setupUi(self)
|
||||
self.ui.fileChoseButton.clicked.connect(self.fileLoading)
|
||||
|
||||
def fileLoading(self):
|
||||
filePath, _ = QFileDialog.getOpenFileName(
|
||||
self.ui.groupBox, # 父窗口对象
|
||||
"选择文件", # 标题
|
||||
r"./", # 起始目录
|
||||
"mid类型 (*.mid *.midi)" # 选择类型过滤项,过滤内容在括号中
|
||||
)
|
||||
print(filePath)
|
||||
|
||||
@Slot()
|
||||
def on_fileChoseButton_clicked(self):
|
||||
filePath, _ = QFileDialog.getOpenFileName(
|
||||
self.ui.groupBox, # 父窗口对象
|
||||
"选择文件", # 标题
|
||||
r"./", # 起始目录
|
||||
"mid类型 (*.mid *.midi)" # 选择类型过滤项,过滤内容在括号中
|
||||
)
|
||||
print(filePath)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication(sys.argv) # 创建一个QApplication,也就是你要开发的软件app
|
||||
# MainWindow = QMainWindow() # 创建一个QMainWindow,用来装载你需要的各种组件、控件
|
||||
# MainWindow = QWidget() # 创建一个QMainWindow,用来装载你需要的各种组件、控件
|
||||
ui = MidAnalyseGui() # ui是你创建的ui类的实例化对象
|
||||
# ui.setupUi(MainWindow) # 执行类中的setupUi方法,方法的参数是第二步中创建的QMainWindow
|
||||
ui.show() # 执行QMainWindow的show()方法,显示这个QMainWindow
|
||||
sys.exit(app.exec()) # 使用exit()或者点击关闭按钮退出QApplication
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QApplication(sys.argv)
|
||||
MainWindow = QWidget()
|
||||
ui = Ui_Form()
|
||||
ui.setupUi(MainWindow)
|
||||
ui.show()
|
||||
sys.exit(app.exec())
|
||||
101
mid_analyse.ui
101
mid_analyse.ui
@@ -1,101 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>582</width>
|
||||
<height>355</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>0</y>
|
||||
<width>561</width>
|
||||
<height>311</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>mid信息</string>
|
||||
</property>
|
||||
<widget class="QPushButton" name="file_chose_button">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>20</y>
|
||||
<width>75</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>选择文件</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="note_count_label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>50</y>
|
||||
<width>54</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>音符数</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="note_count_shower">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>50</y>
|
||||
<width>113</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="horizontalLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>310</y>
|
||||
<width>561</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="input_button">
|
||||
<property name="text">
|
||||
<string>导入</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="output_button">
|
||||
<property name="text">
|
||||
<string>导出分析</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="close_button">
|
||||
<property name="text">
|
||||
<string>关闭</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
BIN
msctLib/UI设计图.pdn
Normal file
BIN
msctLib/UI设计图.pdn
Normal file
Binary file not shown.
BIN
msctLib/UI设计图.png
Normal file
BIN
msctLib/UI设计图.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
0
msctLib/__init__.py
Normal file
0
msctLib/__init__.py
Normal file
BIN
msctLib/__pycache__/__init__.cpython-37.pyc
Normal file
BIN
msctLib/__pycache__/__init__.cpython-37.pyc
Normal file
Binary file not shown.
BIN
msctLib/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
msctLib/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctLib/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
msctLib/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
msctLib/__pycache__/data.cpython-38.pyc
Normal file
BIN
msctLib/__pycache__/data.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctLib/__pycache__/display.cpython-38.pyc
Normal file
BIN
msctLib/__pycache__/display.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctLib/__pycache__/function.cpython-38.pyc
Normal file
BIN
msctLib/__pycache__/function.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctLib/__pycache__/log.cpython-37.pyc
Normal file
BIN
msctLib/__pycache__/log.cpython-37.pyc
Normal file
Binary file not shown.
BIN
msctLib/__pycache__/log.cpython-38.pyc
Normal file
BIN
msctLib/__pycache__/log.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctLib/__pycache__/log.cpython-39.pyc
Normal file
BIN
msctLib/__pycache__/log.cpython-39.pyc
Normal file
Binary file not shown.
BIN
msctLib/bugExecution.exe
Normal file
BIN
msctLib/bugExecution.exe
Normal file
Binary file not shown.
50
msctLib/buildIN.py
Normal file
50
msctLib/buildIN.py
Normal file
@@ -0,0 +1,50 @@
|
||||
# -*- coding: UTF-8 -*-
|
||||
"""音·创的核心内置组件功能集合"""
|
||||
|
||||
|
||||
|
||||
class version:
|
||||
libraries = (
|
||||
'mido', 'amulet', 'amulet-core', 'amulet-nbt', 'piano_transcription_inference', 'pypinyin',
|
||||
'pyinstaller', 'py7zr','websockets', 'torch', 'requests'
|
||||
)
|
||||
"""当前所需库"""
|
||||
|
||||
version = ('0.2.0', 'Delta',)
|
||||
"""当前版本"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
||||
self.libraries = version.libraries
|
||||
"""当前所需库"""
|
||||
|
||||
self.version = version.version
|
||||
"""当前版本"""
|
||||
|
||||
|
||||
def installLibraries(self,index:str = 'https://pypi.tuna.tsinghua.edu.cn/simple'):
|
||||
"""安装全部开发用库"""
|
||||
from sys import platform
|
||||
import os
|
||||
if platform == 'win32':
|
||||
import shutil
|
||||
try:
|
||||
shutil.rmtree(os.getenv('APPDATA') + '\\Musicreater\\')
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
for i in self.libraries:
|
||||
print("安装库:" + i)
|
||||
os.system(f"python -m pip install {i} -i {index}")
|
||||
elif platform == 'linux':
|
||||
os.system("sudo apt-get install python3-pip")
|
||||
os.system("sudo apt-get install python3-tk")
|
||||
os.system("sudo apt-get install python3-tkinter")
|
||||
for i in self.libraries:
|
||||
print("安装库:" + i)
|
||||
os.system(f"sudo python3 -m pip install {i} -i {index}")
|
||||
|
||||
|
||||
def __call__(self):
|
||||
'''直接安装库,顺便返回一下当前版本'''
|
||||
self.installLibraries()
|
||||
return self.version
|
||||
151
msctLib/data.py
Normal file
151
msctLib/data.py
Normal file
@@ -0,0 +1,151 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
import pickle
|
||||
import json
|
||||
from typing import Any, Iterable
|
||||
|
||||
|
||||
|
||||
|
||||
class pickleIO:
|
||||
|
||||
def __init__(self,fileName:str,data: Any = None) -> None:
|
||||
'''简单的pickle操作功能'''
|
||||
self.file = fileName
|
||||
if data:
|
||||
self._data = data
|
||||
else:
|
||||
with open (self.file, 'rb') as f:
|
||||
self._data = pickle.load(f)
|
||||
|
||||
def __call__(self, *args: Any, **kwds: Any) -> Any:
|
||||
return self.data
|
||||
|
||||
def write(self):
|
||||
'''将数据写入pickle'''
|
||||
with open (self.file, 'wb') as f:
|
||||
pickle.dump(self._data, f)
|
||||
|
||||
|
||||
def load(self) -> Any:
|
||||
'''从文件读取数据'''
|
||||
with open (self.file, 'rb') as f:
|
||||
self._data = pickle.load(f)
|
||||
return self.data
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
'''返回数据值'''
|
||||
if self._data is None:
|
||||
raise ValueError('无可用值载入或值为None')
|
||||
else:
|
||||
return self._data
|
||||
|
||||
|
||||
|
||||
class jsonIO:
|
||||
|
||||
def __init__(self,fileName:str,data: Any = None) -> None:
|
||||
'''简单的json操作功能'''
|
||||
self.file = fileName
|
||||
if data:
|
||||
self._data = data
|
||||
else:
|
||||
with open (self.file, 'r', encoding='utf-8') as f:
|
||||
self._data = json.load(f)
|
||||
|
||||
def __call__(self, *args: Any, **kwds: Any) -> Any:
|
||||
return self.data
|
||||
|
||||
def write(self):
|
||||
'''将数据写入json'''
|
||||
with open (self.file, 'w', encoding='utf-8') as f:
|
||||
json.dump(self._data, f)
|
||||
|
||||
|
||||
def load(self) -> Any:
|
||||
'''从文件读取数据'''
|
||||
with open (self.file, 'r', encoding='utf-8') as f:
|
||||
self._data = json.load(f)
|
||||
return self.data
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
'''返回数据值'''
|
||||
return self._data
|
||||
|
||||
|
||||
class uniteIO:
|
||||
|
||||
def __init__(self,fileName:str,fileType = None,data: Any = None) -> None:
|
||||
'''简单的文件数据IO操作功能'''
|
||||
self.filename = fileName
|
||||
if not fileType is None:
|
||||
self._type = fileType
|
||||
else:
|
||||
try:
|
||||
with open (self.filename, 'r', encoding='utf-8') as f:
|
||||
self._type = json
|
||||
except:
|
||||
with open (self.file, 'rb') as f:
|
||||
self._type = pickle
|
||||
|
||||
|
||||
|
||||
if not data is None:
|
||||
self._data = data
|
||||
else:
|
||||
self._data = self.load()
|
||||
|
||||
|
||||
def __call__(self, *args: Any, **kwds: Any) -> Any:
|
||||
return self.data
|
||||
|
||||
def write(self):
|
||||
'''将数据写入文件'''
|
||||
if self._type == json:
|
||||
self._wfile = open(self.filename, 'w', encoding='utf-8')
|
||||
elif self._type == pickle:
|
||||
self._wfile = open(self.file, 'wb')
|
||||
self._type.dump(self._data, self._wfile)
|
||||
|
||||
|
||||
def load(self) -> Any:
|
||||
'''从文件读取数据'''
|
||||
if self._type == json:
|
||||
self._rfile = open(self.filename, 'r', encoding='utf-8')
|
||||
elif self._type == pickle:
|
||||
self._rfile = open(self.file, 'rb')
|
||||
self._data = self._type.load(self._rfile)
|
||||
return self.data
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
'''返回数据值'''
|
||||
return self._data
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from sys import argv
|
||||
|
||||
if argv[1]:
|
||||
input(uniteIO(argv[1]).data)
|
||||
326
msctLib/display.py
Normal file
326
msctLib/display.py
Normal file
@@ -0,0 +1,326 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''音·创的GUI窗口界面显示库
|
||||
:若要使用其他界面显示,请详见:
|
||||
:开发说明|指南'''
|
||||
|
||||
|
||||
import tkinter as tk
|
||||
import tkinter.simpledialog as sdialog
|
||||
import tkinter.filedialog as fdialog
|
||||
from msctLib.log import log
|
||||
|
||||
|
||||
DEFAULTBLUE = (0, 137, 242)
|
||||
# 0089F2
|
||||
|
||||
WEAKBLUE = (0, 161, 231)
|
||||
LIGHTBLUE = (38, 226, 255)
|
||||
# 26E2FF
|
||||
|
||||
RED = (255, 52, 50)
|
||||
PURPLE = (171, 112, 255)
|
||||
GREEN = (0, 255, 33)
|
||||
WHITE = (242, 244, 246)
|
||||
BLACK = (18, 17, 16)
|
||||
|
||||
|
||||
backgroundColor = WHITE
|
||||
frontgroundColor = BLACK
|
||||
loadingColor = DEFAULTBLUE
|
||||
errorColor = RED
|
||||
okColor = GREEN
|
||||
tipsColor = PURPLE
|
||||
|
||||
# 注:UI界面字体、代码字体
|
||||
fontPattern = ('DengXian Light', 'Fira Code')
|
||||
|
||||
|
||||
class disp:
|
||||
'''音·创 的基本Tk窗口显示库'''
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
root: tk.Tk = tk.Tk(),
|
||||
debug: bool = False,
|
||||
title: str = '音·创',
|
||||
geometry: str = '0x0',
|
||||
iconbitmap: tuple = ('', ''),
|
||||
menuWidget: dict = {},
|
||||
wordView: str = '音·创 Musicreater',
|
||||
buttons: list = [],
|
||||
settingBox: list = [],
|
||||
notemap: list = [],
|
||||
infobar:str = '就绪',
|
||||
) -> None:
|
||||
'''使用参数建立基本的 音·创 窗口
|
||||
:param root 根窗口
|
||||
:param debug 是否将日志输出到控制台
|
||||
:param title 窗口标题
|
||||
wordview: str #言论部分显示的字样
|
||||
button: list = [ # 操作按钮部分
|
||||
dict = {
|
||||
按钮名称 : tuple(按钮图标,执行函数)
|
||||
},
|
||||
],
|
||||
settingbox: list = [ # 设置部分显示的字样及其对应的设置函数
|
||||
(
|
||||
设置名称:str,
|
||||
值类型:tuple,
|
||||
显示内容:str,
|
||||
设置操作函数:<function>,
|
||||
)
|
||||
],
|
||||
map: list = [ # 一首曲目的音符数据
|
||||
音符数据
|
||||
]
|
||||
:param infobar 显示信息用
|
||||
'''
|
||||
|
||||
# 载入参量 注意!图标将不被载入参数
|
||||
self.__root = root
|
||||
'''窗口根'''
|
||||
|
||||
self.title = title
|
||||
'''窗口标题'''
|
||||
|
||||
self.menuWidgets = menuWidget
|
||||
'''菜单设定项'''
|
||||
|
||||
self.wordView = wordView
|
||||
'''言·论'''
|
||||
|
||||
self.buttons = buttons
|
||||
'''快捷功能按钮'''
|
||||
|
||||
self.settingBox = settingBox
|
||||
'''设置框'''
|
||||
|
||||
self.notemap = notemap
|
||||
'''音符列表'''
|
||||
|
||||
self.infoBar = infobar
|
||||
'''信息显示版'''
|
||||
|
||||
|
||||
|
||||
self.debug = debug
|
||||
'''是否打开调试模式'''
|
||||
|
||||
self.setTitle()
|
||||
self.setGeometry(geometry)
|
||||
self.setIcon(*iconbitmap)
|
||||
|
||||
self.setMenu()
|
||||
|
||||
self.initWidget()
|
||||
|
||||
# =========================================================
|
||||
# 设定函数部分
|
||||
# =========================================================
|
||||
|
||||
def setTitle(self) -> None:
|
||||
'''设置窗口标题'''
|
||||
self.__root.title = self.title
|
||||
if self.debug:
|
||||
log(f"设置窗口标题{self.title}")
|
||||
|
||||
def setGeometry(self,geometry:str = '0x0') -> None:
|
||||
'''设置窗口大小'''
|
||||
self.__root.geometry(geometry)
|
||||
if self.debug:
|
||||
log(f"设置窗口大小{geometry}")
|
||||
|
||||
def setIcon(
|
||||
self, bitmap: str = './musicreater.ico', default: str = ''
|
||||
) -> None:
|
||||
'''设置窗口图标
|
||||
注意,default参数仅在Windows下有效,其意为将所有没有图标的窗口设置默认图标
|
||||
如果在非Windows环境使用default参数,一个Error将被升起'''
|
||||
if not self.debug:
|
||||
try:
|
||||
if default:
|
||||
self.__root.iconbitmap(bitmap, default)
|
||||
log(f'设置图标为{bitmap},默认为{default}')
|
||||
else:
|
||||
self.__root.iconbitmap(bitmap)
|
||||
log(f'设置图标为{bitmap}')
|
||||
return True
|
||||
except Exception as e:
|
||||
log(str(e), 'ERROR')
|
||||
return False
|
||||
else:
|
||||
self.__root.iconbitmap(bitmap, default)
|
||||
return
|
||||
|
||||
def setMenu(self) -> None:
|
||||
'''设置根菜单'''
|
||||
if not self.menuWidgets:
|
||||
# 如果传入空参数则返回当前菜单
|
||||
try:
|
||||
return self.RootMenu
|
||||
except Exception as E:
|
||||
if self.debug:
|
||||
raise E
|
||||
else:
|
||||
log('无法读取菜单信息', 'WARRING')
|
||||
# 如果不是空参数则新建菜单
|
||||
self.RootMenu = {}
|
||||
self.mainMenuBar = tk.Menu(self.__root)
|
||||
for menuName, menuCmd in self.menuWidgets.items():
|
||||
# 取得一个菜单名和一堆菜单函数及其显示名称
|
||||
menu = tk.Menu(self.mainMenuBar, tearoff=0)
|
||||
for cmdName, cmdFunc in menuCmd.items():
|
||||
if cmdName:
|
||||
menu.add_command(label=cmdName, command=cmdFunc)
|
||||
else:
|
||||
menu.add_separator()
|
||||
self.mainMenuBar.add_cascade(label=menuName, menu=menu)
|
||||
self.RootMenu[menuName] = menu
|
||||
self.__root.config(menu=self.mainMenuBar)
|
||||
|
||||
def addMenu(self, menuRoot: str = '', menuLabel: str = '', menuCommand=None):
|
||||
'''增加一个菜单项
|
||||
:param menuRoot : str
|
||||
菜单的根菜单,即所属的菜单上的文字
|
||||
:param menuLabel : str
|
||||
所需要增加的项目显示的文字
|
||||
:param menuCommand : <function>
|
||||
'''
|
||||
if menuRoot in self.RootMenu.keys:
|
||||
# 如果已经有父菜单
|
||||
if menuLabel:
|
||||
# 增加菜单指令
|
||||
self.RootMenu[menuRoot].add_command(
|
||||
label=menuLabel, command=menuCommand
|
||||
)
|
||||
else:
|
||||
# 增加分隔栏
|
||||
self.RootMenu[menuRoot].add_separator()
|
||||
else:
|
||||
# 没有父菜单则新增一个父菜单
|
||||
menu = tk.Menu(self.mainMenuBar, tearoff=False)
|
||||
if menuLabel:
|
||||
menu.add_command(label=menuLabel, command=menuCommand)
|
||||
else:
|
||||
menu.add_separator()
|
||||
self.mainMenuBar.add_cascade(label=menuRoot, menu=menu)
|
||||
self.RootMenu[menuRoot] = menu
|
||||
|
||||
def initWidget(self,) -> None:
|
||||
'''设置窗口小部件,分为:
|
||||
:言·论 WordView
|
||||
:快捷按钮面板 ButtonBar
|
||||
:设置框 SettingBar
|
||||
:音轨框 TrackBar
|
||||
:各个音轨的显示框 TrackFrame
|
||||
:信息显示版 InfoBar
|
||||
'''
|
||||
self._wordviewBar = tk.Label(
|
||||
self.__root, bg='white', fg='black', text=self.wordView, font=(fontPattern[0], 30)
|
||||
)
|
||||
|
||||
self.setWordView(self.wordView)
|
||||
|
||||
def setWordView(self, text: str) -> None:
|
||||
self._wordviewBar['text'] = text
|
||||
|
||||
|
||||
# =========================================================
|
||||
# 预置函数部分
|
||||
# =========================================================
|
||||
|
||||
def authorWindowStarter(
|
||||
authors: tuple = (
|
||||
('金羿', 'Email EillesWan@outlook.com', 'QQ 2647547478'),
|
||||
('诸葛亮与八卦阵', 'QQ 474037765'),
|
||||
)
|
||||
):
|
||||
'''自定义作者界面'''
|
||||
from languages.lang import _
|
||||
from languages.lang import DEFAULTLANGUAGE
|
||||
from msctLib.buildIN import version
|
||||
|
||||
authorWindow = tk.Tk()
|
||||
authorWindow.title(_('关于'))
|
||||
authorWindow.geometry('550x600') # 像素
|
||||
tk.Label(authorWindow, text='', font=('', 15)).pack()
|
||||
tk.Label(authorWindow, text=_('F音创'), font=('', 35)).pack()
|
||||
tk.Label(
|
||||
authorWindow,
|
||||
text='{} {}'.format(version.version[1] + version.version[0]),
|
||||
font=('', 15),
|
||||
).pack()
|
||||
# pack 的side可以赋值为LEFT RTGHT TOP BOTTOM
|
||||
# grid 的row 是列数、column是行排,注意,这是针对空间控件本身大小来的,即是指向当前控件的第几个。
|
||||
# place的 x、y是(x,y)坐标
|
||||
tk.Label(
|
||||
authorWindow,
|
||||
image=tk.PhotoImage(file='./resources/RyounLogo.png'),
|
||||
width=200,
|
||||
height=200,
|
||||
).pack()
|
||||
tk.Label(authorWindow, text=_('凌云pairs'), font=('', 20)).pack()
|
||||
tk.Label(authorWindow, text='', font=('', 15)).pack()
|
||||
tk.Label(authorWindow, text=_('开发者'), font=('', 15)).pack()
|
||||
for i in authors:
|
||||
for j in i:
|
||||
tk.Label(
|
||||
authorWindow,
|
||||
text=j,
|
||||
font=(
|
||||
'',
|
||||
17 if i.index(j) == 0 else 15,
|
||||
'bold' if i.index(j) == 0 else '',
|
||||
),
|
||||
).pack()
|
||||
tk.Label(authorWindow, text='', font=('', 5)).pack()
|
||||
if DEFAULTLANGUAGE != 'zh-CN':
|
||||
tk.Label(authorWindow, text=_('译者'), font=('', 15)).pack()
|
||||
for i in _('TRANSLATERS').split(';'):
|
||||
for j in i.split(','):
|
||||
tk.Label(
|
||||
authorWindow,
|
||||
text=j,
|
||||
font=(
|
||||
'',
|
||||
17 if i.split(',').index(j) == 0 else 15,
|
||||
'bold' if i.split(',').index(j) == 0 else '',
|
||||
),
|
||||
).pack()
|
||||
|
||||
def exitAboutWindow():
|
||||
authorWindow.destroy()
|
||||
|
||||
tk.Button(authorWindow, text=_('确定'), command=exitAboutWindow).pack()
|
||||
|
||||
authorWindow.mainloop()
|
||||
|
||||
|
||||
class ProgressBar:
|
||||
def __init__(
|
||||
self,
|
||||
root: tk.Tk = tk.Tk(),
|
||||
style: tuple = (DEFAULTBLUE, BLACK, WHITE),
|
||||
type: bool = False,
|
||||
info: str = '',
|
||||
debug: bool = False,
|
||||
) -> None:
|
||||
'''建立一个进度条或者加载等待界面
|
||||
:param root : tk.Tk
|
||||
建立进度条的根窗口
|
||||
:param style : tuple
|
||||
设置主题颜色,第一个参数为进度条或者等待转圈圈的颜色,第二个参数为前景色,第三个是背景色
|
||||
:param type : bool
|
||||
类型,为 False 时为进度条,为 True 时为等待板
|
||||
:param info : str
|
||||
显示的附加信息
|
||||
:param debug : bool
|
||||
是否输出日志到控制台'''
|
||||
self.root = root
|
||||
|
||||
|
||||
if __name__ == '__mian__':
|
||||
import os
|
||||
|
||||
os.chdir('../')
|
||||
disp.authorMenu()
|
||||
6
msctLib/function.py
Normal file
6
msctLib/function.py
Normal file
@@ -0,0 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''音·创的内置功能库
|
||||
:若要加入其他功能,详见:
|
||||
:开发说明|指南'''
|
||||
|
||||
|
||||
82
msctLib/log.py
Normal file
82
msctLib/log.py
Normal file
@@ -0,0 +1,82 @@
|
||||
"""音·创的日志消息处理"""
|
||||
# 诸葛亮与八卦阵帮忙修改语法 日期:---2022年1月19日
|
||||
# 统计:致命(三级)错误:0个;警告(二级)错误:0个;语法(一级)错误:9个
|
||||
|
||||
# 对开发者说的话:
|
||||
#
|
||||
# 请不要修改这里的日志,日志是给开发者和专业人士看的
|
||||
# 而不是给普通用户看的,因此,没必要使用开发者自己也
|
||||
# 不习惯的日志系统,比如说,之前诸葛亮与八卦阵 (bgArray)
|
||||
# 用了 logging 库来改写我原来的日志支持,但是我反
|
||||
# 而找不到我想要的信息了,所以,日志系统给我们开发者
|
||||
# 自己看得好就可以了昂,真的别改了。而且,诸葛八卦改
|
||||
# 了之后并没有多好,喵喵喵,所以我就换回来了。我知道
|
||||
# logging 库比较常用,而且功能也好,但是我们毕竟没
|
||||
# 这个必要,就别用那个库了昂,球球了~
|
||||
# ——金羿 Eilles
|
||||
# 2022 03 09
|
||||
|
||||
# To ALL the developers who will change this part:
|
||||
#
|
||||
# Please do NOT change anything in this file!
|
||||
# The log file is only for developers or
|
||||
# someone who knows a lot about our program
|
||||
# to see, but not the common users. So it
|
||||
# is NOT NECESSARY to use a logging system
|
||||
# that we do not familiar or we do not like.
|
||||
# Take bgAray “诸葛亮与八卦阵” as a example,
|
||||
# he once change this `log.py` into
|
||||
# logging-library-based log support system.
|
||||
# But after the change had done, I could NOT
|
||||
# find useful infomation according to the
|
||||
# log file... So use this file but not to
|
||||
# make changes PLEASE!!! I know some libraries
|
||||
# like logging is usually better than the
|
||||
# simple system in this file and it is normal
|
||||
# to use but, I think it is not necessery,
|
||||
# so PLEASE DO NOT USE OTHER LIBs TO
|
||||
# OVERWRITE MY LIBRARY, THANKS.
|
||||
# ——Eilles 金羿
|
||||
# 03/09/2022
|
||||
|
||||
|
||||
|
||||
import datetime,os
|
||||
|
||||
#载入日志功能
|
||||
StrStartTime = str(datetime.datetime.now()).replace(':', '_')[:-7]
|
||||
'''字符串型的程序开始时间'''
|
||||
|
||||
|
||||
def log(info:str = '',level : str = 'INFO', isPrinted:bool = True):
|
||||
'''将信息连同当前时间载入日志
|
||||
:param info : str
|
||||
日志信息
|
||||
:param level : str['INFO','WARRING','ERROR','CRASH']
|
||||
或 int[ 1, 2, 3, 4 ]
|
||||
信息等级
|
||||
:param isPrinted : bool
|
||||
是否在控制台打印
|
||||
|
||||
:return bool
|
||||
表示是否完成任务'''
|
||||
|
||||
if type(level) == type(1):
|
||||
level = ['INFO','WARRING','ERROR','CRASH'][level-1]
|
||||
|
||||
try:
|
||||
|
||||
if not os.path.exists('./logs/'):
|
||||
os.makedirs('./logs/')
|
||||
|
||||
outputinfo = f'{str(datetime.datetime.now())[11:19]}-[{level}] {info}'
|
||||
|
||||
with open('./logs/'+StrStartTime+'.msct.log', 'a',encoding='UTF-8') as f:
|
||||
f.write(outputinfo+'\n')
|
||||
|
||||
if isPrinted:
|
||||
print(outputinfo)
|
||||
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
25
msctLib/settings.py
Normal file
25
msctLib/settings.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
DEFAULTBLUE = (0, 137, 242)
|
||||
WEAKBLUE = (0, 161, 231)
|
||||
LIGHTBLUE = (38, 226, 255)
|
||||
RED = (255, 52, 50)
|
||||
PURPLE = (171, 112, 255)
|
||||
GREEN = (0, 255, 33)
|
||||
WHITE = (242, 244, 246)
|
||||
BLACK = (18, 17, 16)
|
||||
|
||||
settings = {
|
||||
'language' : 'zh-CN',
|
||||
'theme' : {
|
||||
'' : '',
|
||||
},
|
||||
}
|
||||
|
||||
class msctSetting:
|
||||
def __init__(self,**settings) -> None:
|
||||
pass
|
||||
|
||||
def __call__(self, **kwds):
|
||||
pass
|
||||
243
msctLib/开发说明兼指南.md
Normal file
243
msctLib/开发说明兼指南.md
Normal file
@@ -0,0 +1,243 @@
|
||||
开发说明\|指南
|
||||
==============
|
||||
|
||||
此文件旨在使后期欲参与开发之人员减轻其开发负担,同时也为了我们正在开发的人员详细说明功能与用法
|
||||
掌握开发指南之后,在调用函数等的过程中将会更加方便
|
||||
|
||||
文件结构
|
||||
--------
|
||||
|
||||
从主文件调用display.py以实现显示,调用functions.py以使用功能
|
||||
|
||||
functions.py中会调取./addon/目录下的全部功能文件,这些功能文件必须先由./addon/addons.pkl来预先定义好
|
||||
|
||||
详细说明
|
||||
--------
|
||||
|
||||
### msctLib
|
||||
|
||||
用于支持主要功能
|
||||
|
||||
#### display.py
|
||||
|
||||
1. class disp
|
||||
|
||||
- 参数
|
||||
|
||||
1. `**kwgs`对窗口的基础设定 `{ '组件名称' : 函数自设定 }` 例如:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ python
|
||||
{
|
||||
'version': '0.0.1', # version指的是当前配置格式的版本
|
||||
'title': "音·创",
|
||||
'geometry': '1200x900',
|
||||
'iconbitmap': ('./resources/musicreater.ico', './resources/musicreater.ico'),
|
||||
'menu' : { #对setMenu有特殊说明
|
||||
'文件': {
|
||||
'新建': <function>,
|
||||
'打开': <function>,
|
||||
},
|
||||
},
|
||||
'widget': { #对窗口部件又详细说明
|
||||
'wordview':{
|
||||
'text':'言·论',
|
||||
},
|
||||
'settingbox':{}, #后文详细说明
|
||||
'tracklist':{},
|
||||
'operation':{},
|
||||
'map':{},
|
||||
},
|
||||
}
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- 变量
|
||||
|
||||
1. `infoBar`
|
||||
|
||||
信息显示栏,一个字符串,用于显示一些信息。
|
||||
|
||||
|
||||
2. `title`
|
||||
|
||||
窗口标题,字符串
|
||||
|
||||
|
||||
3. `menuWidgets`
|
||||
|
||||
对于窗口菜单的设定,其格式如下:
|
||||
```python
|
||||
menuWidgets: dist = { # 菜单项目
|
||||
str"菜单名" : dict{
|
||||
str"选项名"|None : <function>选项函数
|
||||
},
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
注:
|
||||
`菜单名` : `str` 显示在菜单上的字符串
|
||||
`选项名` : `str` 显示在菜单选项上的字符串
|
||||
`选项函数` : `function` 菜单调取的函数(无返回值,无入参)
|
||||
当 `选项名` 的布尔值判定为 `False` 的时候,无论 `选项函数` 为何,皆插入一段分割线,但 `选项函数` 不得为空
|
||||
|
||||
|
||||
4. `wordView`
|
||||
|
||||
显示在言论上的文字,字符串
|
||||
|
||||
|
||||
5. `buttons`
|
||||
|
||||
快捷功能按钮的列表,列表的元素为字典,字典的键是按钮的名称,值为一个元组,元组中含有两个元素,其中元组的第1个元素为按钮图标,是一个图片的路径;第2个元素为执行的函数,其值应当是一个函数对象。
|
||||
|
||||
```python
|
||||
button: list = [ # 操作按钮部分
|
||||
dict{
|
||||
str"按钮名称" : tuple(
|
||||
按钮图标,
|
||||
执行函数
|
||||
)
|
||||
},
|
||||
...
|
||||
],
|
||||
```
|
||||
|
||||
|
||||
6. `settingBox`
|
||||
|
||||
设置框,用于设置音乐的基本属性,例如词作者,曲作者等,设置格式如下:
|
||||
|
||||
```python
|
||||
settingbox: list = [ #设置部分显示的字样及其对应的设置函数
|
||||
tuple(
|
||||
设置名称:str,
|
||||
值类型:tuple,
|
||||
显示内容:str,
|
||||
设置操作函数:<function>,
|
||||
),
|
||||
...
|
||||
]
|
||||
```
|
||||
|
||||
其中,值类型可以是如下几个项
|
||||
1. `('str',)` 字符串类型,使用文本框输入数据
|
||||
2. `('bool',)` 布尔类型,使用复选框输入数据
|
||||
3. `('num',最小值:float,最大值:float,步长:float = 1)` 数值类型,使用数值滑动条输入数据
|
||||
4. `('list',列表项:list)` 单选类型,即列表中多选一,使用单选框输入数据
|
||||
|
||||
其中,值操作函数需要有一个参数,用于传递用户提供的设置值。
|
||||
|
||||
|
||||
7. `notemap`
|
||||
|
||||
音符数据表,用于存储曲谱信息,存储格式如下
|
||||
```python
|
||||
notemap: list = [ # 音轨列表
|
||||
dict{ # 单个音轨
|
||||
'instrument' : str"乐器",
|
||||
'velocity' : int 响度,
|
||||
# 这里理论上需要写一个小节多少个X分音符
|
||||
# 以及小节里的都是几分音符
|
||||
# 但是这个留给以后来支持
|
||||
int 小节编号 : [ # 一个小节
|
||||
tuple( # 一个音符
|
||||
时间 : int,
|
||||
持续 : int,
|
||||
乐器 : str,
|
||||
采样 : float,
|
||||
响度 : int,
|
||||
),
|
||||
...
|
||||
],
|
||||
...
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
|
||||
其中,对于每个音符:
|
||||
1. 时间 单位:帧 当前音符开始时,距离当前小节开始所经过的帧数
|
||||
2. 持续 单位:帧 当前音符持续的帧数
|
||||
3. 乐器 当前音符使用的乐器,需要在乐器列表中有所注册
|
||||
4. 采样 当前音符在MC的采样音高(不含打击乐器)
|
||||
5. 响度 单位:格的-1次方 音符播放源距离播放者的距离的倒数
|
||||
|
||||
|
||||
- 函数
|
||||
|
||||
1. `setMenu`对菜单的基础设定
|
||||
|
||||
```python
|
||||
{
|
||||
菜单名 : {
|
||||
选项名 : 选项函数
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
注:
|
||||
`菜单名` : `str` 显示在菜单上的字符串
|
||||
`选项名` : `str` 显示在菜单选项上的字符串
|
||||
`选项函数` : `function` 菜单调取的函数(无返回值,无入参)
|
||||
当 `选项名` 的布尔值判定为 `False` 的时候,无论 `选项函数` 为何,皆插入一段分割线,但 `选项函数` 不得为空
|
||||
|
||||
2. `setWidget`对窗口部件的放置
|
||||
```python
|
||||
wordview: dict = { #言论部分显示的字样
|
||||
'text': str = 显示内容,
|
||||
# ... 即可用 tk.Label 的参数
|
||||
},
|
||||
button: list = [
|
||||
dict = {
|
||||
按钮名称 : tuple(按钮图标,执行函数)
|
||||
},
|
||||
],
|
||||
settingbox: list = [ #设置部分显示的字样及其对应的设置函数
|
||||
(
|
||||
设置名称:str,
|
||||
值类型:tuple,
|
||||
显示内容:str,
|
||||
设置操作函数:<function>,
|
||||
)
|
||||
],
|
||||
map: list = [
|
||||
音符数据
|
||||
]
|
||||
```
|
||||
注:
|
||||
|
||||
上文中,值类型可以是如下几个项
|
||||
1. `('str',)` 字符串类型,使用文本框输入数据
|
||||
2. `('bool',)` 布尔类型,使用复选框输入数据
|
||||
3. `('num',最小值:int,最大值:int,步长:int = 1)` 数值类型,使用数值滑动条输入数据
|
||||
4. `('list',列表项:list)` 单选类型,即列表中多选一,使用单选框输入数据
|
||||
|
||||
值得注意的是,在kwgs中修改的部件设置,可以在其变量中读取或热修改,对应的变量如下
|
||||
|
||||
| 参数 | 对应类中的变量 | 变量类型 | 说明 |
|
||||
|------------|------------------|---------------------------|---------------------|
|
||||
| wordview | wordview | str | 显示在 言·论 区域的文字 |
|
||||
| button | button | list[dict{}] | 操作按钮 |
|
||||
| settingbox | settings | list[ Any ] | 设置项目中的值 |
|
||||
| tracklist | tracknum | tuple(int,int) | 当前选择到的音轨与音轨总数|
|
||||
| map | notes | list[ class Note ] | 当前的音符列表 |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### ???
|
||||
|
||||
全曲的设置应该如下:
|
||||
```python
|
||||
标题 : str = '无名'
|
||||
副标题 : str = ''
|
||||
作曲 : str = '佚名'
|
||||
作词 : str = ''
|
||||
歌曲版权信息 : str = ''
|
||||
# bpm 暂时不需要
|
||||
|
||||
|
||||
```
|
||||
@@ -1,34 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""一个简单的基于音·创的我的世界音频操作工具"""
|
||||
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
|
||||
|
||||
|
||||
__version__ = '0.1.0'
|
||||
__all__ = []
|
||||
__author__ = (('金羿', 'Eilles Wan'), ('诸葛亮与八卦阵', 'bgArray'), ('鸣凤鸽子', 'MingFengPigeon'))
|
||||
|
||||
"""
|
||||
音·创 库版 (Musicreater Package Version)
|
||||
是一款免费开源的针对《我的世界:基岩版》的midi音乐转换库
|
||||
Musicreater pkgver (Package Version 音·创 库版)
|
||||
A free open source library used for convert midi file into formats that is suitable for **Minecraft: Bedrock Edition**.
|
||||
|
||||
Copyright 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 ../Lisence.md
|
||||
Terms & Conditions: ../Lisence.md
|
||||
"""
|
||||
|
||||
|
||||
|
||||
from .main import *
|
||||
|
||||
print('此Midi转换功能由音·创开发者开发,版权归参与开发的人员共同所有。')
|
||||
print('Copyright © 2022 all the developers of Musicreater')
|
||||
print("小贴:不妨试试Mid-BDX转换网页:在线的多功能Midi转换器")
|
||||
print("https://dislink.github.io/midi2bdx/")
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# 音·创 开发交流群 861684859
|
||||
# Email EillesWan2006@163.com W-YI_DoctorYI@outlook.com EillesWan@outlook.com
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需转载或借鉴 许可声明请查看仓库目录下的 Lisence.md
|
||||
|
||||
|
||||
"""
|
||||
音·创 库版 (Musicreater Package Version)
|
||||
是一款免费开源的针对《我的世界:基岩版》的midi音乐转换库
|
||||
Musicreater pkgver (Package Version 音·创 库版)
|
||||
A free open source library used for convert midi file into formats that is suitable for **Minecraft: Bedrock Edition**.
|
||||
|
||||
Copyright 2023 all the developers of Musicreater
|
||||
|
||||
开源相关声明请见 ../Lisence.md
|
||||
Terms & Conditions: ../Lisence.md
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
class MSCTBaseException(Exception):
|
||||
"""音·创库版本的所有错误均继承于此"""
|
||||
|
||||
def __init__(self, *args):
|
||||
super().__init__(*args)
|
||||
|
||||
def 喵(self,):
|
||||
for i in self.args:
|
||||
print(i+"喵!")
|
||||
|
||||
def crash_it(self):
|
||||
raise self
|
||||
|
||||
|
||||
class CrossNoteError(MSCTBaseException):
|
||||
'''同通道下同音符交叉出现所产生的错误'''
|
||||
pass
|
||||
|
||||
|
||||
class NotDefineTempoError(MSCTBaseException):
|
||||
'''没有Tempo设定导致时间无法计算的错误'''
|
||||
pass
|
||||
|
||||
|
||||
class MidiDestroyedError(MSCTBaseException):
|
||||
'''Midi文件损坏'''
|
||||
pass
|
||||
|
||||
class ChannelOverFlowError(MSCTBaseException):
|
||||
'''一个midi中含有过多的通道(数量应≤16)'''
|
||||
pass
|
||||
|
||||
class NotDefineProgramError(MSCTBaseException):
|
||||
'''没有Program设定导致没有乐器可以选择的错误'''
|
||||
pass
|
||||
|
||||
@@ -1,217 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# 音·创 开发交流群 861684859
|
||||
# 版权所有 金羿("Eilles Wan") & 诸葛亮与八卦阵("bgArray") & 鸣凤鸽子("MingFengPigeon")
|
||||
# 若需使用或借鉴 请依照 Apache 2.0 许可证进行许可
|
||||
|
||||
|
||||
"""
|
||||
音·创 库版 (Musicreater Package Version)
|
||||
是一款免费开源的针对《我的世界:基岩版》的midi音乐转换库
|
||||
注意!除了此源文件以外,任何属于此仓库以及此项目的文件均依照Apache许可证进行许可
|
||||
Musicreater pkgver (Package Version 音·创 库版)
|
||||
A free open source library used for convert midi file into formats that is suitable for **Minecraft: Bedrock Edition**.
|
||||
Note! Except for this source file, all the files in this repository and this project are licensed under Apache License 2.0
|
||||
|
||||
Copyright 2022 all the developers of Musicreater
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
|
||||
def _toCmdList_m1(
|
||||
self,
|
||||
scoreboardname: str = "mscplay",
|
||||
volume: float = 1.0,
|
||||
speed: float = 1.0) -> list:
|
||||
"""
|
||||
使用Dislink Sforza的转换思路,将midi转换为我的世界命令列表
|
||||
:param scoreboardname: 我的世界的计分板名称
|
||||
:param volume: 音量,注意:这里的音量范围为(0,1],如果超出将被处理为正确值,其原理为在距离玩家 (1 / volume -1) 的地方播放音频
|
||||
:param speed: 速度,注意:这里的速度指的是播放倍率,其原理为在播放音频的时候,每个音符的播放时间除以 speed
|
||||
:return: tuple(命令列表, 命令个数, 计分板最大值)
|
||||
"""
|
||||
tracks = []
|
||||
if volume > 1:
|
||||
volume = 1
|
||||
if volume <= 0:
|
||||
volume = 0.001
|
||||
|
||||
commands = 0
|
||||
maxscore = 0
|
||||
|
||||
for i, track in enumerate(self.midi.tracks):
|
||||
|
||||
ticks = 0
|
||||
instrumentID = 0
|
||||
singleTrack = []
|
||||
|
||||
for msg in track:
|
||||
ticks += msg.time
|
||||
# print(msg)
|
||||
if msg.is_meta:
|
||||
if msg.type == "set_tempo":
|
||||
tempo = msg.tempo
|
||||
else:
|
||||
if msg.type == "program_change":
|
||||
# print("TT")
|
||||
instrumentID = msg.program
|
||||
if msg.type == "note_on" and msg.velocity != 0:
|
||||
nowscore = round(
|
||||
(ticks * tempo)
|
||||
/ ((self.midi.ticks_per_beat * float(speed)) * 50000)
|
||||
)
|
||||
maxscore = max(maxscore, nowscore)
|
||||
soundID, _X = self.__Inst2soundIDwithX(instrumentID)
|
||||
singleTrack.append(
|
||||
"execute @a[scores={" +
|
||||
str(scoreboardname) +
|
||||
"=" +
|
||||
str(nowscore) +
|
||||
"}" +
|
||||
f"] ~ ~ ~ playsound {soundID} @s ~ ~{1 / volume - 1} ~ {msg.velocity * (0.7 if msg.channel == 0 else 0.9)} {2 ** ((msg.note - 60 - _X) / 12)}")
|
||||
commands += 1
|
||||
if len(singleTrack) != 0:
|
||||
tracks.append(singleTrack)
|
||||
|
||||
return [tracks, commands, maxscore]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ============================
|
||||
|
||||
|
||||
|
||||
|
||||
import mido
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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 = 60000000 / msg.tempo
|
||||
is_change_bpm = True
|
||||
|
||||
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"))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1547
msctPkgver/main.py
1547
msctPkgver/main.py
File diff suppressed because it is too large
Load Diff
0
msctspt/__init__.py
Normal file
0
msctspt/__init__.py
Normal file
BIN
msctspt/__pycache__/__init__.cpython-37.pyc
Normal file
BIN
msctspt/__pycache__/__init__.cpython-37.pyc
Normal file
Binary file not shown.
BIN
msctspt/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
msctspt/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
BIN
msctspt/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
msctspt/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
msctspt/__pycache__/bdxOpera_CP.cpython-38.pyc
Normal file
BIN
msctspt/__pycache__/bdxOpera_CP.cpython-38.pyc
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user