返回主页

LANGUAGE

English | 简体中文

Self-Compose Tutorial

Creating a New Track Template


Track Content Editing

Take the template file TwinkleTwinkleLittleStar as an example, please ensure that the track template was created correctly in the previous step.

WAV File

Track Image

Background Image

info.csv

Key Value (Default) Description
name Twinkle Twinkle Little Star The displayed name of the track, which can be different from the index name.
scale_name C The key of the track, which affects the solfege names of the notes. Enter the key string. See Scale Data.
slice_start 7 The starting seconds of the track's WAV file preview that will loop during the track preparation phase.
slice_end 24 The ending seconds of the track's WAV file preview.
keytype 1 Key type: 1->7 keys, 2->12 keys. If your track uses accidentals, please use the 12-key setting.
composer Wolfgang Amadeus Mozart The composer's name, displayed during the preparation phase.
lyrics Twinkle twinkle little star\nHow I wonder what you are!\nUp above the world so high\nLike a diamond in the sky Lyrics, displayed only in transitions, use \n for line breaks, and avoid using , (it will cause CSV parsing errors).
copyright Author: Elif Games Copyright information, viewable by clicking the info button during the preparation phase.
pic_pos 0|0|0.5 The position and scale of the track image on the circular disc in the preparation phase: x pixel offset|y pixel offset|scale ratio.
card_pos 0|0|0.7 The position and scale of the track image on the square music card in the selection interface: x pixel offset|y pixel offset|scale ratio.
video musicbg1 Video background, only supports built-in videos: musicbg1 - musicbg9.
fade_lose 0.2 The percentage the video darkens per second.
fade_hit 0.2 The percentage the video brightens with each triple hit.
alpha_area 0.05|0.4 The transparency range of the video: minimum transparency|maximum transparency.
version_info First version. Information on this version, and will be submitted to the Steam Workshop.

note.csv

config.xlsx

README.txt

Completion and Testing


Configuration Data

Scale Data

Scale Key Scale Value in game Description
C 1 C Major
C♯ 2 C♯ Major
D 3 D Major
D♯ 4 D♯ Major
E 5 E Major
F 6 F Major
F♯ 7 F♯ Major
G 8 G Major
G♯ 9 G♯ Major
A 10 A Major
A♯ 11 A♯ Major, B♭ Major should also be noted as A♯
B 12 B Major
a 1 a Minor
a♯ 2 a♯ Minor
b 3 b Minor
c 4 c Minor
c♯ 5 c♯ Minor
d 6 d Minor
d♯ 7 d♯ Minor
e 8 e Minor
f 9 f Minor
f♯ 10 f♯ Minor
g 11 g Minor
g♯ 12 g♯ Minor

Pitch Data

Pitch Key Chev System Italiano System Note Name Corresponding Piano Key
41 1, do, c C4
-41 #1, dod, #c
42 2, re, d D4
-42 #2, red, #d
43 3, mi, e E4
44 4, fa, f F4
-44 #4, fad, #f
45 5, sol, g G4
-45 #5, sold, #g
46 6, la, a A4
-46 b7, sib, #a
47 7, si, b B4
51 1 do c1 C5
-51 #1 dod #c1
52 2 re d1 D5
-52 #2 red #d1
53 3 mi e1 E5
54 4 fa f1 F5
-54 #4 fad #f1
55 5 sol g1 G5
-55 #5 sold #g1
56 6 la a1 A5
-56 b7 sib #a1
57 7 si b1 B5
61 1' do' c2 C6
-61 #1' dod' #c2
62 2' re' d2 D6
-62 #2' red' #d2
63 3' mi' e2 E6
64 4' fa' f2 F6
-64 #4' fad' #f2
65 5' sol' g2 G6
-65 #5' sold' #g2
66 6' la' a2 A6
-66 b7' sib' #a2
67 7' si' b2 B6

Other

Script to convert MIDI mono tracks to configuration

# -*- coding: utf-8 -*-
# 将midi文件转化为moundofmusic数据
# pip install mido

# Midi文件名
MIDI_FILE = 'YOUR_MIDI.mid'
# 输出文件名
OUTPUT_FILE = 'note_raw.csv'
# midi音高:moundofmusic音高,音域三个八度
DIC_NOTES = {48: 41, 49: -41, 50: 42, 51: -42, 52: 43, 53: 44, 54: -44, 55: 45, 56: -45, 57: 46, 58: -46, 59: 47, 60: 51, 61: -51, 62: 52, 63: -52, 64: 53, 65: 54, 66: -54, 67: 55, 68: -55, 69: 56, 70: -56, 71: 57, 72: 61, 73: -61, 74: 62, 75: -62, 76: 63, 77: 64, 78: -64, 79: 65, 80: -65, 81: 66, 82: -66, 83: 67}
DIC_NOTES_OUT = {21: 16, 22: -16, 23: 17, 24: 21, 25: -21, 26: 22, 27: -22, 28: 23, 29: 24, 30: -24, 31: 25, 32: -25, 33: 26, 34: -26, 35: 27, 36: 31, 37: -31, 38: 32, 39: -32, 40: 33, 41: 34, 42: -34, 43: 35, 44: -35, 45: 36, 46: -36, 47: 37, 84: 71, 85: -71, 86: 72, 87: -72, 88: 73, 89: 74, 90: -74, 91: 75, 92: -75, 93: 76, 94: -76, 95: 77, 96: 81, 97: -81, 98: 82, 99: -82, 100: 83, 101: 84, 102: -84, 103: 85, 104: -85, 105: 86, 106: -86, 107: 87, 108: 91}

import mido
import csv

def midi_to_mom(filename_midi, filename_csv):
    # 读取MIDI文件
    midi_file = mido.MidiFile(filename_midi)
    # 获取MIDI文件的ticks_per_beat
    ticks_per_beat = midi_file.ticks_per_beat
    # 初始化tempo
    tempo = 1000000  # 默认tempo
    # 计算每个tick的时间(秒)
    tick_time = tempo / (ticks_per_beat * 1000000)
    # 准备CSV文件
    with open(filename_csv, 'w', newline='') as csvfile:
        count = 0
        result = []
        writer = csv.writer(csvfile)
        # 写入标题行
        writer.writerow(['id', 'pitch', 'time'])
        # 初始化变量
        total_time = 0.0
        notes_on = {}  # 存储音符的开始时间和音符号
        # 遍历MIDI文件中的每个轨道
        for track in midi_file.tracks:
            for msg in track:
                if msg.type == 'set_tempo': # 更新tick_time
                    tempo = msg.tempo
                    tick_time = tempo / (ticks_per_beat * 1000000)
                    # print(f'tempo change to: {tempo}')
                total_time += msg.time * tick_time  # 当前累积时间记录
                if msg.type == 'note_on' and msg.velocity > 0:  # 计算当前音符的开始时间
                    notes_on[msg.note] = total_time
                    count += 1
                elif msg.type == 'note_off' or (msg.type == 'note_on' and msg.velocity == 0):  # 计算当前音符的停止时间
                    if msg.note in notes_on:
                        play_time = notes_on[msg.note]
                        # 转化、记录数据
                        if (msg.note not in DIC_NOTES.keys()):
                            note = DIC_NOTES_OUT[msg.note]    # 超出音域的音符
                            print(f'WARNING! <id:{count} pitch:{note}> not in range, need to be transpose!')
                        else:
                            note = DIC_NOTES[msg.note]
                        result.append((count, note, play_time))
                        writer.writerow([count, note, round(play_time,3)])  # 时间只保留三位小数
    print(f'Successfully create midi data file: {filename_csv}')
    return midi_file, result

if __name__ == '__main__':
    midi_file, result = midi_to_mom(MIDI_FILE, OUTPUT_FILE)