<jupyter_start><jupyter_text>osumapper: create osu! map using Tensorflow and ColabFor mappers who don't know how this colaboratory thing works:- Press Ctrl+Enter in code blocks to run them one by one- It will ask you to upload .osu file and audio.mp3 after the third block of code- .osu file needs to have correct timing (you can use [statementreply](https://osu.ppy.sh/users/126198)'s TimingAnlyz tool)- After uploading them, wait for a few minutes until download popsGithub: https://github.com/kotritrona/osumapper  Step 1: InstallationFirst of all, check the Notebook Settings under Edit tab.Activate GPU to make the training faster.Then, clone the git repository and install dependencies.<jupyter_code>%cd /content/
!git clone https://github.com/kotritrona/osumapper.git
%cd osumapper/v7.0
!apt install -y ffmpeg
!apt install -y nodejs
!cp requirements_colab.txt requirements.txt
!cp package_colab.json package.json
!pip install -r requirements.txt
!npm install<jupyter_output><empty_output><jupyter_text>Step 2: Choose a pre-trained modelSet the select_model variable to one of:- "default": default model- "sota": model trained with Sota Fujimori music (☆>5.0)- "vtuber": model trained with VTuber music (☆4.0-5.3)- "inst": model trained with rhythm game instrumental music (☆3.5-6.5)- "tvsize": model trained with TV Size maps (☆3.5-5.0 BPM140-190)- "hard": model trained with Hard difficulties (☆<3.5 BPM140-190)- "normal": model trained with Normal difficulties (☆<2.7 BPM140-190)- "lowbpm": model trained with low BPM music (☆3-4.5 BPM<140)- "taiko": taiko mode model, experimental (☆3-6)- "catch": catch mode model, experimental (☆3-6)<jupyter_code>from setup_colab import *

select_model = "default"

model_params = load_pretrained_model(select_model);<jupyter_output><empty_output><jupyter_text>Step 3: Upload map and music fileMap file = .osu file with correct timingMusic file = the mp3 file in the osu folder<jupyter_code>from google.colab import files
print("Please upload the map file:")
mapfile_upload = files.upload()
for fn in mapfile_upload.keys():
  uploaded_osu_name = fn
  print('Uploaded map file: "{name}" {length} bytes'.format(name=fn, length=len(mapfile_upload[fn])))
print("Please upload the music file:")
music_upload = files.upload()
for fn in music_upload.keys():
  print('Uploaded music file: "{name}" {length} bytes'.format(name=fn, length=len(music_upload[fn])))<jupyter_output><empty_output><jupyter_text>Step 4: Read the map and convert to python readable format<jupyter_code>from act_newmap_prep import *

step4_read_new_map(uploaded_osu_name);<jupyter_output><empty_output><jupyter_text>Step 5: Use model to calculate map rhythmParameters:"note_density": how many notes will be placed on the timeline, range (0, 1)."slider_favor": how the model favors sliders against circles, range (-1.1, 1.1)."dist_multiplier": the distance snap. range (0, +∞). Of course 0/+∞ are not advisable."divisor_favor": how the model favors notes to be on each divisor starting from a beat (white, blue, red, blue), range (-1, 1) each."slider_max_ticks": the max amount of time a slider can slide, range (1, +∞).<jupyter_code>from act_rhythm_calc import *

model = step5_load_model(model_file=model_params["rhythm_model"]);
npz = step5_load_npz();
params = model_params["rhythm_param"]
# Or set the parameters here...
# params = step5_set_params(dist_multiplier=1, note_density=0.32, slider_favor=0, divisor_favor=[0] * 4, slider_max_ticks=8);

predictions = step5_predict_notes(model, npz, params);
converted = step5_convert_sliders(predictions, params);

step5_save_predictions(converted);<jupyter_output><empty_output><jupyter_text>Step 6: Map flow generatorGenerate the final map using a Generative Adversarial Network (GAN).Parameters:- note_distance_basis: the baseline for distance snap between notes- max_ticks_for_ds: max number of time ticks (each 1/4) that it uses the distance snap- next_from_slider_end: use slider end instead of slider head for calculating distance- box_loss_border, box_loss_value: it's like a barrier on the map edges that bounces off the circles- divisor, note_group_size: don't change unless you're using a special model built for it- good_epoch, max_epoch: controls the training time. less time makes it faster but risks less quality- g_\*, c_\*: hyperparameters used by GAN. No one knows how they work but they mysterically affect the result<jupyter_code>from act_gan import *;

GAN_PARAMS = model_params["gan"]
# Or manually set the parameters...
# GAN_PARAMS = {
#     "divisor" : 4,
#     "good_epoch" : 12,
#     "max_epoch" : 30,
#     "note_group_size" : 10,
#     "g_epochs" : 1,
#     "c_epochs" : 1,
#     "g_batch" : 50,
#     "g_input_size" : 50,
#     "c_true_batch" : 140,
#     "c_false_batch" : 5,
#     "c_randfalse_batch" : 5,
#     "note_distance_basis" : 200,
#     "next_from_slider_end" : False,
#     "max_ticks_for_ds" : 1,
#     "box_loss_border" : 0.1,
#     "box_loss_value" : 0.4,
#     "box_loss_weight" : 1
# };

step6_set_gan_params(GAN_PARAMS);
osu_a, data = step6_run_all(flow_dataset_npz=model_params["flow_dataset"]);<jupyter_output><empty_output><jupyter_text>Since the generation will take a while...we can appreciate a nice picture of Cute Sophie!! Do a little modding to the map.Parameters:- stream_regularizer: fix bad streams. integer for modes (0,1,2,3,4) 0=inactive- slider_mirror: mirror slider ends if they go outside map area. (0,1) 0=inactive 1=active<jupyter_code>from act_modding import *

modding_params = model_params["modding"]
# modding_params = {
#     "stream_regularizer" : 1,
#     "slider_mirror" : 1
# }

osu_a, data = step7_modding(osu_a, data, modding_params);<jupyter_output><empty_output><jupyter_text>Finally, save the data into an .osu file!<jupyter_code>from google.colab import files
from act_final import *
from act_taiko_hitsounds import *

if select_model == "taiko":
    taiko_hitsounds_params = step8_taiko_hitsounds_set_params(divisor=4, metronome_count=4)
    hitsounds = step8_apply_taiko_hitsounds(osu_a, data, hs_dataset=model_params["hs_dataset"], params=taiko_hitsounds_params)
    saved_osu_name = step8_save_osu_file(osu_a, data, hitsounds=hitsounds)
else:
    saved_osu_name = step8_save_osu_file(osu_a, data);

files.download(saved_osu_name)
# clean up if you want to make another map!
# colab_clean_up(uploaded_osu_name)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10676268002504696, 'fraction_numerical': 0.021603005635566688, 'mean_word_length': 5.648283038501561, 'pattern_counts': {'":': 16, '<': 36, '<?xml version=': 0, '>': 34, 'https://': 3, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '604236', 'license': 'Apache-2.0', 'n_tokens_mistral': 2254, 'n_tokens_neox': 2160, 'n_words': 645, 'path': 'v7.0/Colab.ipynb', 'repo_name': 'jsstwright/osumapper', 'size': '6388'}