Skip to content

IepIweidieng/osu2tja

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

osu2tja

English|简体中文

An .osu ⟷ .tja converter, for Python 3.

.osu (osu! Beatmap) is the single-difficulty chart format for the game osu!. .osz (osu! Beatmap Archive) is the standard zipped form containing multiple .osu files and resources for a song entry in osu!.

.tja or TJA (unknown acronym, likely "Taiko (Tatsu)jin Another") is a Taiko chart format supported by many simulators, such as TaikoJiro, Taiko-san Daijiro, Malody, TJAPlayer3, OpenTaiko, and Project OutFox.

It contains 2 major tools: osz2tja & tja2osz.

Requirements

  • Python 3.x
  • ffmpeg (optional, for osz2tja)

ffmpeg

If ffmpeg is installed or placed under the same directory as osz2tja.py, osz2tja will automatically convert the audio file into .ogg format.

Get ffmpeg here: https://www.ffmpeg.org/download.html

After downloading, unzip it and copy bin/ffmpeg.exe into the same directory as osz2tja.py, and the conversion should now work.

osz2tja

Usage

python osz2tja.py [input_folder] [output_folder]

Example:

python osz2tja.py a_folder b_folder
  • [input_folder] is where your .osz files are located. Defaults to Songs if omitted.
  • [output_folder] is where the converted .tja files and audio files will be saved. Defaults to Output if omitted.

osz2tja will create a folder in [output_folder] for each generated .tja file.

Features

  • Batch conversion of .osz files to .tja files. (@MoshirMoshir)
  • Automatically maps osu! difficulties (up to 5 per .tja file) to TJA Edit (Taiko: Inner/Ura Oni or Extra Extreme), Oni (Taiko: Extreme), Hard, Normal, and Easy difficulties. (@MoshirMoshir; improved to 5)
  • Beatmaps with more than 5 difficulties are split into multiple .tja files (e.g., title - 1, title - 2). (@MoshirMoshir; improved to suffix only when necessary)
  • Difficulty stars are adjusted between split .tja files to keep higher stars for higher difficulties. (@MoshirMoshir)

    NOT accurate to the Taiko star ratings as the OverallDifficulty: (timing window strictness) is currently used for estimation.

  • Automatically copy and convert the audio file. (@SamLangTen; OGG conversion — @k2angel)

Conversion Details

  • Input: osu file format v4–14 (those tested; warns and continues to process for other versions) (improved)
  • TJA // comment ignoring
  • TJA Headers
    • Metadata Headers
      • osu2tja watermark (moved to the first line of the TJA file)
      • TitleUnicode:/Title:TITLE:
      • Source: AND/OR ArtistUnicode:/Artist:SUBTITLE: (@k2angel)
      • AudioFilename:WAVE:, with automatic file copy (@SamLangTen), with OGG conversion (@k2angel)
      • PreviewTime:DEMOSTART:
      • Creator:MAKER: (@MoshirMoshir)
      • Creator:AUTHOR: (for Malody) (TODO)
      • timing point: hitsound volume (max) → SEVOL: ÷ SONGVOL: (TODO)
    • Decoration Headers
      • Background event: filename → PREIMAGE: (TODO)
      • Background event: filename → BGIMAGE: (TODO)
      • Video event: filename → BGMOVIE: (TODO)
      • Video event: start time → MOVIEOFFSET: (TODO)
      • Storyboard event → TJAPlayer3-Extended OBJ commands (not planned)
    • Sync Headers
      • initial BPM → BPM: (for display only, rounded to 2 decimal digits), for each difficulty (new)
      • initial beat time position → OFFSET: (improved), for each difficulty (new)
        • The OFFSET: is set to the beginning time position of the last beat non-after the audio to mimic osu! behavior. It was the earliest of the first note or the timing point in delguoqing's version.
    • Difficulty Headers
      • Version: & Mode: → TJA comment (for reference only) (new)
      • Version:NOTEDESIGNER<n>: (for guest difficulties) (TODO)
      • Creator:NOTEDESIGNER<n>: (otherwise) (TODO)
      • Difficulties sorted by OverallDifficulty:COURSE: (@SamLangTen; automated — @MoshirMoshir; improved to include COURSE:Edit)
      • OverallDifficulty:LEVEL: (@SamLangTen)
        • TODO: Use the actual osu! star rating.
      • Spinner: Time length → BALLOON: (improved using the official formula to account for OverallDifficulty: (might still off by 1 or 2 hits))
  • TJA Commands
    • Uninherited timing point: BPM → #BPMCHANGE
    • Uninherited timing point: Beats per bar → #MEASURE
    • Incomplete bar → #MEASURE + optional #DELAY (crash fixed — @delguoqing; improved to ms-level accuracy)
    • Inherited timing point: Slider velocity change → #SCROLL (uncapped range)
    • Timing point: Kiai time → #GOGOSTART & #GOGOEND
    • Timing point: Omit first bar line → #BARLINEOFF & #BARLINEON (TODO)
  • TJA Note Definition
    • Timing
      • relative time offset to bar start and end → beat division
      • Mid-bar inter-note command insertion (improved, new)
      • ms-level timing accuracy (TODO)
        • Currently everything is pre-quantized to 1/96ths (1/24 beats).
    • Note Symbols
      • (std mode) short slider to circles (improved using the official algorithm)
      • Empty → 0 (blank)
      • Circle, normal non-finish hitsound → 1 (regular Don)
      • Circle, whistle/clap non-finish hitsound → 2 (regular Katsu)
      • Circle, normal finish hitsound → 3 (big Don)
      • Circle, whistle/clap finish hitsound → 4 (big Katsu)
      • Slider, non-finish hitsound → 5 + 8 (regular bar drumroll)
      • Slider, finish hitsound → 6 + 8 (big bar drumroll)
      • Spinner, ANY hitsound → 7 + 8 (regular balloon roll)
      • Spinner, finish hitsound → 9 + 8 (special balloon roll) (TODO)

tja2osz

Usage

python tja2osz.py [input_folder] [output_folder]

Example:

python tja2osz.py a_folder b_folder
  • [input_folder] is where your .tja files are located (can be in any inner directories). Defaults to Songs if omitted.
  • [output_folder] is where the converted .osu files and audio files will be saved. Defaults to Output if omitted.

tja2osz will create a folder in [output_folder] for each processed .tja file. This folder will contain converted .osu files and audio file. tja2osz will also create an .osz file in [output_folder] for these .osu files.

Features

  • Batch conversion of .tja files to .osz files. (new)
  • Automatically split each TJA difficulty and each main branch route as a separate .osu difficulty file.
  • Automatically copy the audio file (new)

Conversion Details

  • Output: osu file format v14 (improved)
  • TJA // comment ignoring
    • FIXME: // comments do not disable commands when splitting TJAs.
  • TJA Headers
    • Metadata Headers
      • osu2tja watermark (new)
      • TITLE:Title:
        • FIXME: The encoding detection is usually wrong
      • SUBTITLE:Artist: (TODO) (Currently defaults to unknown)
      • MAKER:/AUTHOR:Creator: (TODO) (Currently defaults to unknown)
      • SUBTITLE:Source: (bug fixed)
        • FIXME: The encoding detection is usually wrong
      • ? → Tags: (defaults to taiko jiro tja)
      • WAVE:AudioFilename:, with automatic file copy (new)
      • ? → AudioLeadIn: (defaults to 0) (improved)
      • DEMOSTART:PreviewTime: (bug fixed)
      • ? → CountDown: (defaults to 0 (false))
      • ? → SampleSet: (defaults to Normal)
      • StackLeniency:0.7 (no effects)
      • ? → Mode: (defaults to 1 (Taiko))
      • ? → LetterboxInBreaks: (defaults to 0 (false)) (improved)
      • SEVOL: ÷ SONGVOL: → Timing point: hitsound volume (new)
    • Decoration Headers
      • PREIMAGE: → Background event: filename (TODO)
      • BGIMAGE: → Background event: filename (TODO)
      • BGMOVIE: → Video event: filename (TODO)
      • MOVIEOFFSET: → Video event: start time (TODO)
      • TJAPlayer3-Extended OBJ commands → Storyboard event (not planned)
    • Sync Headers
      • BPM: → initial uninherited timing point: BPM
      • OFFSET: → initial uninherited timing point: time
    • Difficulty Headers
      • STYLE:Version: (TODO)
      • COURSE:Version:
      • NOTESDESIGNER<n>:Version:<notesdesigner>'s <course> when <notesdesigner> isn't <maker>/<author> (TODO)
      • COURSE: + LEVEL:HPDrainRate (TODO) (defaults to 7 (roughly Taiko Oni 10 full gauge) (improved))
      • CircleSize:5 (no effects)
      • ApproachRate:5 (no effects)
      • COURSE: + LEVEL:OverallDifficulty: (TODO) (defaults to 8.333 (Taiko Hard & Oni GREAT/GOOD window) (improved))
      • ? → SliderMultiplier: (defaults to 1.47 (AC15– note spacing))
      • (Mostly-used) beat division → SliderTickRate: (TODO) (defaults to 4 (1/16th))
      • HEADSCROLL: → initial inherited timing point: Slider velocity change (TODO)
  • TJA Commands
    • #START → Uninherited timing point: Large beats per bar + omit first bar line + (optional) incomplete bar (TODO)
    • #START P<n> → Split into player-side TJA (TODO)
      • FIXME: When a multiple–player-side chart set has been defined for any difficulty, wrong difficulties will be notated for split difficulties.
    • #END → Uninherited timing point: Large beats per bar + omit first bar line (new)
    • #BRANCHSTART → Begin branch-split section
      • TODO: detect and avoid impossible branch routes
    • #N/#E/#M → Split into branch TJA
      • FIXME: Omitting some branches causes missing bars.
    • #BRANCHEND → Begin branch-common section
      • FIXME: #BRANCHEND is recognized but ignored.
    • #BPMCHANGE, positive → Uninherited timing point: BPM
    • #BPMCHANGE, negative, with positive (bar length ÷ BPM) → Uninherited timing point: absolute-valued BPM (TODO)
    • #MEASURE, positive integer beats → Uninherited timing point: Beats per bar (improved), float values (new)
    • #MEASURE, positive fraction beats → Uninherited timing point: Beats per bar + incomplete bar (improved), float values (new)
    • Negative (bar length ÷ BPM) → Notechart events are not in completely increasing time order, re-sorted by time (TODO)
    • #DELAY → move time of definition cursor
      • FIXME: The bar line after #DELAY will be wrongly displayed until the next uninherited timing point generated.
      • FIXME: The generated events might not be in the correct increasing time order if large negative #DELAYs are used.
    • #SCROLL, with positive (scroll × BPM) → Inherited timing point: Slider velocity change
      • FIXME: Use BPM changes to work around the slider velocity change being capped between 0.01x to 10x in osu!.
    • Non-positive/complex-valued (scroll × BPM) → Inherited timing point: Absolute-valued slider velocity change (TODO)
    • #SUDDEN, with positive stop duration → Inherited timing point: Scaled slider velocity change (TODO)
    • #GOGOSTART & #GOGOEND → Timing point: Kiai time
    • #BARLINEOFF & #BARLINEON → Timing point: Omit first bar line (new)
    • #BARLINE → Split bars into (possibly) incomplete bars (TODO)
    • #BARLINESCROLL → Inherited timing points: Slider velocity change for every bar line and every first note after bar line; split out a 1ms bar with omitted first bar line for notes on the original bar start (TODO)
  • TJA Note Definition
    • Timing
      • Measure with no note symbols (,) → Full measure (new bug fix)
      • Sum of (bar length ÷ beat division ÷ BPM at each division) → relative time offset to bar start (bug fixed for fractional-beat bars with #SCROLL)
      • ms-level timing accuracy (TODO)
        • Currently everything is pre-quantized to 1/96ths (1/24 beats).
    • Note Symbols
      • 0 (blank) → Empty
      • 1 (regular Don) → Circle, default hitsound
      • 2 (regular Katsu) → Circle, clap hitsound
      • F (ad-lib) → = regular Don/Katsu? (TODO)
      • C (bomb/mine) → = regular Don/Katsu? empty? (TODO)
      • 3 (big Don) → Circle, finish hitsound
      • A (handed big Don) → Circle, finish hitsound (TODO)
      • 4 (big Katsu) → Circle, clap finish hitsound
      • B (handed big Katsu) → Circle, clap finish hitsound (TODO)
      • G (Kadon) → = big Don/Katsu? (TODO)
      • 5 (head of regular bar drumroll) → Slider, default hitsound
      • I (head of regular/Katsu? bar drumroll) → = head of regular bar drumroll? (TODO)
      • 6 (head of big bar drumroll) → Slider, finish hitsound
      • H (head of big/Don? bar drumroll) → = head of big bar drumroll? (TODO)
      • 7 (head of regular balloon roll) → Spinner, default hitsound
      • 9 (head of special balloon roll) → Spinner, default hitsound
        • TODO: use finish hitsound to mark difference
      • D (head of fuze balloon roll) → = regular balloon roll? (TODO)
      • Head of any roll-type note, after unended roll-type notes → Empty (TODO)
      • 8 (explicit end of rolls), after unended roll-type notes → End of last slider/spinner
      • Any hit-type note, after unended roll-type notes → Forced end of last slider/spinner (TODO)
      • #END (command), after unended roll-type notes → Forced end of last slider/spinner (TODO)
      • 8, straying → Empty (TODO)
      • Any roll-type note, non-positive time duration → Empty (TODO)

Languages

  • Python 100.0%