mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2024-11-11 01:27:35 +08:00
255 lines
8.6 KiB
Python
255 lines
8.6 KiB
Python
|
||
"""音创系列的转换功能"""
|
||
|
||
|
||
|
||
from nmcsup.log import log
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
# 输入一个列表 [ [str, float ], [], ... ] 音符str 值为持续时间float
|
||
def note2list(Notes : list) -> list:
|
||
from nmcsup.const import notes
|
||
def change(base):
|
||
enwo = {
|
||
'a': 'A',
|
||
'b': 'B',
|
||
'c': 'C',
|
||
'd': "D",
|
||
"e": "E",
|
||
'f': 'F',
|
||
'g': "G"
|
||
}
|
||
nuwo = {
|
||
'6': 'A',
|
||
'7': 'B',
|
||
'1': 'C',
|
||
'2': "D",
|
||
"3": "E",
|
||
'4': 'F',
|
||
'5': "G"
|
||
}
|
||
for k, v in enwo.items():
|
||
if k in base:
|
||
base = base.replace(k, v)
|
||
for k, v in nuwo.items():
|
||
if k in base:
|
||
base = base.replace(k, v)
|
||
return base
|
||
res = []
|
||
log(" === 音符列表=>音调列表")
|
||
for i in Notes:
|
||
s2 = change(i[0])
|
||
log(' === 正在操作音符'+i[0]+'->'+s2)
|
||
if s2 in notes.keys():
|
||
log(" === 找到此音符,加入:"+str(notes[s2][0]))
|
||
res.append([notes[s2][0], float(i[1])])
|
||
else:
|
||
log(' === '+s2+'不在音符表内,此处自动替换为 休止符0 ')
|
||
res.append(['0', float(i[1])])
|
||
log(' === 最终反回'+str(res))
|
||
return res
|
||
|
||
|
||
|
||
|
||
def mcnote2freq(Notes):
|
||
from nmcsup.const import notes
|
||
mcnback = {}
|
||
for i,j in notes.items():
|
||
mcnback[j[0]] = i
|
||
res = []
|
||
log(" === 我的世界音调表=>频率列表")
|
||
for i in Notes:
|
||
log(' === 正在操作音符'+i[0]+'->'+mcnback[i[0]])
|
||
res.append([notes[mcnback[i[0]]][1], float(i[1])])
|
||
log(' === 最终反回'+str(res))
|
||
return res
|
||
|
||
|
||
|
||
|
||
|
||
#MP3文件转midi文件
|
||
def Mp32Mid(mp3File, midFile):
|
||
from piano_transcription_inference import PianoTranscription, sample_rate, load_audio
|
||
# 加载
|
||
(audio, _) = load_audio(mp3File, sr=sample_rate, mono=True)
|
||
# 实例化并转换
|
||
PianoTranscription(device="cpu").transcribe(audio, midFile)
|
||
|
||
|
||
|
||
|
||
|
||
#传入一个音符列表转为指令列表
|
||
def Note2Cmd(Notes : list,ScoreboardName:str,Instrument:str, PlayerSelect:str='',isProsess:bool=False) -> list:
|
||
commands = []
|
||
a = 0.0
|
||
if isProsess:
|
||
length = len(Notes)
|
||
j = 1
|
||
for i in range(len(Notes)):
|
||
commands.append("execute @a"+PlayerSelect+" ~ ~ ~ execute @s[scores={"+ScoreboardName+"="+str(int((a+2)*5+int(Notes[i][1]*5)))+"}] ~ ~ ~ playsound "+Instrument+" @s ~ ~ ~ 1000 "+str(Notes[i][0])+" 1000\n")
|
||
a += Notes[i][1]
|
||
if isProsess:
|
||
commands.append("execute @a"+PlayerSelect+" ~ ~ ~ execute @s[scores={"+ScoreboardName+"="+str(int((a+2)*5+int(Notes[i][1]*5)))+"}] ~ ~ ~ title @s actionbar §e▶ 播放中: §a"+str(j)+"/"+str(length)+" || "+str(int(j/length*1000)/10)+"\n")
|
||
j+=1
|
||
commands.append("\n\n# 凌云我的世界开发团队 x 凌云软件开发团队 : W-YI(金羿)\n")
|
||
return commands
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
import amulet
|
||
import amulet_nbt
|
||
from amulet.api.block import Block
|
||
from amulet.api.block_entity import BlockEntity
|
||
from amulet.utils.world_utils import block_coords_to_chunk_coords
|
||
from amulet_nbt import TAG_String,TAG_Compound,TAG_Byte
|
||
|
||
|
||
|
||
#简单载入方块
|
||
#level.set_version_block(posx,posy,posz,"minecraft:overworld",("bedrock", (1, 16, 20)),Block(namespace, name))
|
||
|
||
|
||
|
||
#转入指令列表与位置信息转至世界
|
||
def Cmd2World(cmd:list,world:str,dire:list):
|
||
'''将指令以命令链的形式载入世界\n
|
||
cmd指令列表位为一个序列,中包含指令字符串\n
|
||
world为地图所在位置,需要指向文件夹,dire为指令方块生成之位置'''
|
||
level = amulet.load_level(world)
|
||
cdl = []
|
||
for i in cmd:
|
||
try:
|
||
if (i[:i.index('#')].replace(' ','') != '\n') and(i[:i.index('#')].replace(' ','') != ''):
|
||
cdl.append(i[:i.index('#')])
|
||
except:
|
||
cdl.append(i)
|
||
i = 0
|
||
#第一个是特殊
|
||
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('up'),'mode':TAG_String("repeating")})
|
||
cx, cz = block_coords_to_chunk_coords(dire[0], dire[2])
|
||
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
|
||
offset_x, offset_z = dire[0] - 16 * cx, dire[2] - 16 * cz
|
||
universal_block_entity = BlockEntity( 'universal_minecraft','command_block',dire[0],dire[1],dire[2],amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound({'auto': TAG_Byte(0),'Command': TAG_String(cdl.pop(0))}) })))
|
||
chunk.blocks[offset_x, dire[1], offset_z] = level.block_palette.get_add_block(universal_block)
|
||
chunk.block_entities[(dire[0], dire[1], dire[2])] = universal_block_entity
|
||
chunk.changed = True
|
||
#集体上移
|
||
dire[1]+=1;
|
||
#真正开始
|
||
down = False
|
||
for j in cdl:
|
||
if dire[1]+i >= 255:
|
||
dire[0]+=1
|
||
i=0
|
||
down = not down
|
||
#定义此方块
|
||
if dire[1]+i == 254 :
|
||
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('east'),'mode':TAG_String("chain")})
|
||
else:
|
||
if down:
|
||
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('down'),'mode':TAG_String("chain")})
|
||
else:
|
||
universal_block = Block('universal_minecraft','command_block',{'conditional':TAG_String("false"),'facing':TAG_String('up'),'mode':TAG_String("chain")})
|
||
cx, cz = block_coords_to_chunk_coords(dire[0], dire[2])
|
||
#获取区块
|
||
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
|
||
offset_x, offset_z = dire[0] - 16 * cx, dire[2] - 16 * cz
|
||
if down:
|
||
#定义方块实体
|
||
universal_block_entity = BlockEntity( 'universal_minecraft','command_block',dire[0],254-i,dire[2],amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound({'auto': TAG_Byte(1),'Command': TAG_String(j)}) })))
|
||
|
||
#将方块加入世界
|
||
chunk.blocks[offset_x, 254-i, offset_z] = level.block_palette.get_add_block(universal_block)
|
||
chunk.block_entities[(dire[0], 254-i, dire[2])] = universal_block_entity
|
||
else:
|
||
#定义方块实体
|
||
universal_block_entity = BlockEntity( 'universal_minecraft','command_block',dire[0],dire[1]+i,dire[2],amulet_nbt.NBTFile(TAG_Compound({'utags': TAG_Compound({'auto': TAG_Byte(1),'Command': TAG_String(j)}) })))
|
||
|
||
#将方块加入世界
|
||
chunk.blocks[offset_x, dire[1]+i, offset_z] = level.block_palette.get_add_block(universal_block)
|
||
chunk.block_entities[(dire[0], dire[1]+i, dire[2])] = universal_block_entity
|
||
#设置为已更新区块
|
||
chunk.changed = True
|
||
i+=1
|
||
del i, cdl
|
||
#保存世界并退出
|
||
level.save()
|
||
level.close()
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
#音符转成方块再加载到世界里头
|
||
def Blocks2World(world:str,dire:list,Datas:list):
|
||
from nmcsup.const import Blocks
|
||
level = amulet.load_level(world)
|
||
i = 0
|
||
def setblock(block:Block,pos:list):
|
||
'''pos : list[int,int,int]'''
|
||
cx, cz = block_coords_to_chunk_coords(pos[0], pos[2])
|
||
chunk = level.get_chunk(cx, cz, "minecraft:overworld")
|
||
offset_x, offset_z = pos[0] - 16 * cx, pos[2] - 16 * cz
|
||
chunk.blocks[offset_x, pos[1], offset_z] = level.block_palette.get_add_block(block)
|
||
chunk.changed = True
|
||
for j in Datas:
|
||
if dire[1]+1 >= 255:
|
||
i = 0
|
||
dire[0]+=1
|
||
setblock(Blocks[j[0]],[dire[0],dire[1]+i,dire[2]])
|
||
i = int(i+j[1]+0.5) #四舍五入
|
||
level.save()
|
||
level.close()
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
#传入音符列表制作播放器指令
|
||
def Notes2Player(Note,dire:list,CmdData:dict):
|
||
'''传入音符列表、坐标、指令数据,生成播放器指令'''
|
||
Notes = {}
|
||
for i in Note:
|
||
Notes[i[0]] = ''
|
||
Notes = list(Notes.keys())
|
||
from nmcsup.const import Blocks
|
||
Cmds = []
|
||
for j in Notes:
|
||
Cmds.append('execute @e[x='+str(dire[0])+',y='+str(dire[1])+',z='+str(dire[2])+',dy='+str(255-dire[1])+',name='+CmdData['Ent']+'] ~ ~ ~ detect ~ ~ ~ '+Blocks[j]+' 0 execute @a '+CmdData['Pls']+' ~ ~ ~ playsound '+CmdData['Ins']+' @s ~ ~ ~ 1000 '+str(j)+' 1000\n')
|
||
Cmds+=['#本函数由 金羿 音·创 生成\n','execute @e[y='+str(dire[1])+',dy='+str(255-dire[1])+',name='+CmdData['Ent']+'] ~ ~ ~ tp ~ ~1 ~\n','execute @e[y=255,dy=100,name='+CmdData['Ent']+'] ~ ~ ~ tp ~1 '+str(dire[1])+' ~\n','#音·创 开发交流群 861684859']
|
||
return Cmds
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
#传入音符列表生成方块至世界
|
||
def Datas2BlkWorld(NoteData,world:str,dire:list):
|
||
for i in range(len(NoteData)):
|
||
Blocks2World(world,[dire[0],dire[1],dire[2]+i],NoteData[i])
|
||
|
||
|