Task 756: .USTX File Format

Task 756: .USTX File Format

File Format Specifications for .USTX

The .USTX file format is a text-based format used by OpenUtau, an open-source vocal synthesis software. It is structured as a YAML document that stores project data, including musical sequences, track configurations, and synthesis parameters. The format is human-readable and can be processed as valid YAML, allowing for easy editing with text editors. OpenUtau loads and saves projects in this format, and it supports compatibility with related formats like .UST from UTAU through import/export functions.

List of all the properties of this file format intrinsic to its file system:

  • version: Specifies the version of the .USTX format (string).
  • name: The name of the project (string).
  • comment: An optional comment or description for the project (string).
  • outputDir: The directory path for output files (string).
  • cacheDir: The directory path for cache files (string).
  • bpm: The initial tempo in beats per minute (float).
  • beatPerBar: The number of beats per bar in the time signature (integer).
  • beatUnit: The unit of the beat in the time signature (integer).
  • resolution: The number of ticks per beat, defining timing precision (integer).
  • modes: A dictionary containing mode settings for the project (dictionary/object).
  • expressions: A list of expression definitions, such as volume or timbre (list of dictionaries/objects).
  • tempos: A list of tempo changes, each with position and bpm (list of dictionaries/objects).
  • timeSignatures: A list of time signature changes, each with bar position, beat per bar, and beat unit (list of dictionaries/objects).
  • tracks: A list of tracks, each containing singer, phonemizer, renderer, mute status, solo status, volume, and pan (list of dictionaries/objects).
  • voiceParts: A list of voice parts, each with position, notes (including position, duration, tone, lyric, phonemes, pitch, vibrato, dynamics), and curves (list of dictionaries/objects).
  • waveParts: A list of wave parts for audio imports (list of dictionaries/objects).

Two direct download links for files of format .USTX:

Ghost blog embedded HTML JavaScript for drag-and-drop .USTX file dumping:

USTX File Property Dumper
Drag and drop a .USTX file here

This HTML can be embedded in a Ghost blog post. It creates a drag-and-drop zone that reads the .USTX file as text, parses it as JSON (assuming compatibility; for full YAML support, integrate a library like yaml.js via CDN), and displays the properties on the screen.

  1. Python class for handling .USTX files:
import yaml

class USTX:
    def __init__(self, path):
        with open(path, 'r', encoding='utf-8') as f:
            self.data = yaml.safe_load(f)

    def print_properties(self):
        properties = [
            'version', 'name', 'comment', 'outputDir', 'cacheDir', 'bpm', 
            'beatPerBar', 'beatUnit', 'resolution', 'modes', 'expressions', 
            'tempos', 'timeSignatures', 'tracks', 'voiceParts', 'waveParts'
        ]
        for prop in properties:
            value = self.data.get(prop, 'Not found')
            print(f"{prop}: {value}")

    def write(self, path):
        with open(path, 'w', encoding='utf-8') as f:
            yaml.safe_dump(self.data, f, allow_unicode=True)
  1. Java class for handling .USTX files:
import org.yaml.snakeyaml.Yaml;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

public class USTX {
    private Map<String, Object> data;

    public USTX(String path) throws IOException {
        Yaml yaml = new Yaml();
        try (InputStream in = new FileInputStream(path)) {
            data = yaml.load(in);
        }
    }

    public void printProperties() {
        String[] properties = {
            "version", "name", "comment", "outputDir", "cacheDir", "bpm", 
            "beatPerBar", "beatUnit", "resolution", "modes", "expressions", 
            "tempos", "timeSignatures", "tracks", "voiceParts", "waveParts"
        };
        for (String prop : properties) {
            Object value = data.getOrDefault(prop, "Not found");
            System.out.println(prop + ": " + value);
        }
    }

    public void write(String path) throws IOException {
        Yaml yaml = new Yaml();
        try (FileWriter writer = new FileWriter(path)) {
            yaml.dump(data, writer);
        }
    }
}
  1. JavaScript class for handling .USTX files (Node.js environment):
const fs = require('fs');
const YAML = require('yaml'); // Requires 'yaml' package installed via npm

class USTX {
    constructor(path) {
        const fileContent = fs.readFileSync(path, 'utf8');
        this.data = YAML.parse(fileContent);
    }

    printProperties() {
        const properties = [
            'version', 'name', 'comment', 'outputDir', 'cacheDir', 'bpm', 
            'beatPerBar', 'beatUnit', 'resolution', 'modes', 'expressions', 
            'tempos', 'timeSignatures', 'tracks', 'voiceParts', 'waveParts'
        ];
        properties.forEach(prop => {
            const value = JSON.stringify(this.data[prop] || 'Not found');
            console.log(`${prop}: ${value}`);
        });
    }

    write(path) {
        const yamlString = YAML.stringify(this.data);
        fs.writeFileSync(path, yamlString, 'utf8');
    }
}
  1. C++ class for handling .USTX files (requires yaml-cpp library):
#include <yaml-cpp/yaml.h>
#include <fstream>
#include <iostream>
#include <vector>
#include <string>

class USTX {
private:
    YAML::Node data;

public:
    USTX(const std::string& path) {
        data = YAML::LoadFile(path);
    }

    void printProperties() {
        std::vector<std::string> properties = {
            "version", "name", "comment", "outputDir", "cacheDir", "bpm", 
            "beatPerBar", "beatUnit", "resolution", "modes", "expressions", 
            "tempos", "timeSignatures", "tracks", "voiceParts", "waveParts"
        };
        for (const auto& prop : properties) {
            if (data[prop]) {
                std::cout << prop << ": " << data[prop] << std::endl;
            } else {
                std::cout << prop << ": Not found" << std::endl;
            }
        }
    }

    void write(const std::string& path) {
        std::ofstream fout(path);
        fout << data;
        fout.close();
    }
};