1.1.0 - TOML
This commit is contained in:
37
Cargo.lock
generated
37
Cargo.lock
generated
@ -684,7 +684,7 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "musicgen"
|
name = "musicgen"
|
||||||
version = "1.0.0"
|
version = "1.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"cpal 0.16.0",
|
"cpal 0.16.0",
|
||||||
@ -693,7 +693,7 @@ dependencies = [
|
|||||||
"rand",
|
"rand",
|
||||||
"rodio",
|
"rodio",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1148,6 +1148,15 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "0.6.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "shlex"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
@ -1265,11 +1274,26 @@ version = "0.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.8.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_edit",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml_datetime"
|
||||||
version = "0.6.11"
|
version = "0.6.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
|
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
@ -1278,10 +1302,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
|
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
|
"toml_write",
|
||||||
"winnow",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_write"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.18"
|
version = "1.0.18"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "musicgen"
|
name = "musicgen"
|
||||||
version = "1.0.0"
|
version = "1.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
authors = ["Atridad Lahiji <me@atri.dad>"]
|
authors = ["Atridad Lahiji <me@atri.dad>"]
|
||||||
description = "Generate electronic music without AI"
|
description = "Generate electronic music without AI"
|
||||||
@ -15,7 +15,7 @@ hound = "3.5"
|
|||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
clap = { version = "4.5", features = ["derive"] }
|
clap = { version = "4.5", features = ["derive"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
toml = "0.8"
|
||||||
|
|
||||||
# Real-time audio
|
# Real-time audio
|
||||||
rodio = "0.20"
|
rodio = "0.20"
|
||||||
|
145
README.md
145
README.md
@ -14,47 +14,45 @@ cd music
|
|||||||
cargo build --release
|
cargo build --release
|
||||||
```
|
```
|
||||||
|
|
||||||
## JSON Configuration
|
## TOML Configuration
|
||||||
|
|
||||||
Create declaritive songs with structured JSON:
|
Create declaritive songs with structured TOML:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cargo run --bin musicgen json examples/fantasy.json
|
cargo run --bin musicgen toml examples/enchanted.toml
|
||||||
```
|
```
|
||||||
|
|
||||||
### From Binary
|
### From Binary
|
||||||
```bash
|
```bash
|
||||||
./target/release/musicgen json examples/fantasy.json
|
./target/release/musicgen toml examples/enchanted.toml
|
||||||
```
|
```
|
||||||
|
|
||||||
### Basic JSON Structure
|
### Basic TOML Structure
|
||||||
|
|
||||||
```json
|
```toml
|
||||||
{
|
[composition]
|
||||||
"composition": {
|
key = 60
|
||||||
"key": 60,
|
scale = "minor"
|
||||||
"scale": "minor",
|
tempo = 85.0
|
||||||
"tempo": 85.0,
|
measures = 16
|
||||||
"measures": 16
|
|
||||||
},
|
[[tracks]]
|
||||||
"tracks": [
|
name = "bass"
|
||||||
{
|
instrument = "sine"
|
||||||
"name": "bass",
|
volume = 0.8
|
||||||
"instrument": "sine",
|
|
||||||
"volume": 0.8,
|
[tracks.pattern]
|
||||||
"pattern": {
|
type = "custom"
|
||||||
"type": "custom",
|
|
||||||
"steps": [
|
[[tracks.pattern.steps]]
|
||||||
{ "time": 0.0, "note": "C2", "duration": 0.75, "velocity": 0.9 }
|
time = 0.0
|
||||||
]
|
note = "C2"
|
||||||
}
|
duration = 0.75
|
||||||
}
|
velocity = 0.9
|
||||||
],
|
|
||||||
"export": {
|
[export]
|
||||||
"filename": "my_song",
|
filename = "my_song"
|
||||||
"format": "wav"
|
format = "wav"
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Definitions
|
### Definitions
|
||||||
@ -85,46 +83,55 @@ cargo run --bin musicgen json examples/fantasy.json
|
|||||||
|
|
||||||
### Track Configuration
|
### Track Configuration
|
||||||
|
|
||||||
```json
|
```toml
|
||||||
{
|
[[tracks]]
|
||||||
"tracks": [
|
name = "bass"
|
||||||
{
|
instrument = "sine"
|
||||||
"name": "bass",
|
volume = 0.8
|
||||||
"instrument": "sine",
|
|
||||||
"volume": 0.8,
|
[tracks.pattern]
|
||||||
"pattern": {
|
type = "custom"
|
||||||
"type": "custom",
|
loop_length = 4.0
|
||||||
"steps": [
|
|
||||||
{ "time": 0.0, "note": "C2", "duration": 0.75, "velocity": 0.9 },
|
[[tracks.pattern.steps]]
|
||||||
{ "time": 2.0, "note": "G2", "duration": 0.75, "velocity": 0.8 }
|
time = 0.0
|
||||||
],
|
note = "C2"
|
||||||
"loop_length": 4.0
|
duration = 0.75
|
||||||
},
|
velocity = 0.9
|
||||||
"effects": [
|
|
||||||
{
|
[[tracks.pattern.steps]]
|
||||||
"type": "lowpass",
|
time = 2.0
|
||||||
"cutoff": 400.0,
|
note = "G2"
|
||||||
"resonance": 1.8
|
duration = 0.75
|
||||||
}
|
velocity = 0.8
|
||||||
]
|
|
||||||
},
|
[[tracks.effects]]
|
||||||
{
|
type = "lowpass"
|
||||||
"name": "drums",
|
cutoff = 400.0
|
||||||
"instrument": "noise",
|
resonance = 1.8
|
||||||
"volume": 0.6,
|
|
||||||
"pattern": {
|
[[tracks]]
|
||||||
"type": "custom",
|
name = "drums"
|
||||||
"steps": [
|
instrument = "noise"
|
||||||
{ "time": 0.0, "note": "C1", "duration": 0.1, "velocity": 1.0 },
|
volume = 0.6
|
||||||
{ "time": 1.0, "note": "E3", "duration": 0.05, "velocity": 0.7 }
|
|
||||||
]
|
[tracks.pattern]
|
||||||
}
|
type = "custom"
|
||||||
}
|
|
||||||
]
|
[[tracks.pattern.steps]]
|
||||||
}
|
time = 0.0
|
||||||
|
note = "C1"
|
||||||
|
duration = 0.1
|
||||||
|
velocity = 1.0
|
||||||
|
|
||||||
|
[[tracks.pattern.steps]]
|
||||||
|
time = 1.0
|
||||||
|
note = "E3"
|
||||||
|
duration = 0.05
|
||||||
|
velocity = 0.7
|
||||||
```
|
```
|
||||||
|
|
||||||
See `examples` for complete examples and the full schema.
|
See `composition-schema` for a complete example and the full schema.
|
||||||
|
|
||||||
## Output
|
## Output
|
||||||
|
|
||||||
|
385
composition-schema.toml
Normal file
385
composition-schema.toml
Normal file
@ -0,0 +1,385 @@
|
|||||||
|
# MusicGen TOML Configuration Schema
|
||||||
|
# Complete reference for all available fields and options
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# METADATA SECTION
|
||||||
|
# Optional information about your composition
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
title = "My Composition" # Title of the track
|
||||||
|
artist = "Artist Name" # Your name or band name
|
||||||
|
description = "An electronic song" # Description of the composition
|
||||||
|
tags = ["electronic", "ambient", "chill"] # Genre tags or keywords
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# COMPOSITION SECTION
|
||||||
|
# Core musical settings that define the overall structure
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
[composition]
|
||||||
|
# Musical key - can be MIDI note number (60 = C4) or note name
|
||||||
|
key = "C4" # Options: MIDI numbers 0-127 OR note names like "C4", "F#3", "Bb5"
|
||||||
|
|
||||||
|
# Scale type - defines which notes are used
|
||||||
|
scale = "major" # Options: "major", "minor", "dorian", "phrygian", "lydian",
|
||||||
|
# "mixolydian", "aeolian", "locrian", "pentatonic",
|
||||||
|
# "blues", "chromatic"
|
||||||
|
|
||||||
|
# Tempo in beats per minute
|
||||||
|
tempo = 120.0 # Range: 40.0 - 300.0 BPM
|
||||||
|
|
||||||
|
# Time signature - how many beats per measure
|
||||||
|
[composition.time_signature]
|
||||||
|
numerator = 4 # Beats per measure (1-16)
|
||||||
|
denominator = 4 # Note value for one beat (2, 4, 8, or 16)
|
||||||
|
|
||||||
|
# Composition length and complexity
|
||||||
|
measures = 32 # Number of measures (1-1000)
|
||||||
|
complexity = 0.7 # Overall complexity (0.0-1.0, default: 0.6)
|
||||||
|
harmony_density = 0.8 # How much harmony/chords (0.0-1.0, default: 0.7)
|
||||||
|
rhythmic_density = 0.6 # How busy the rhythm is (0.0-1.0, default: 0.8)
|
||||||
|
seed = 12345 # Random seed for reproducible generation (optional)
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# TRACKS SECTION
|
||||||
|
# Each track is like one instrument in your band
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Example 1: Custom melody track
|
||||||
|
[[tracks]]
|
||||||
|
name = "main_melody"
|
||||||
|
instrument = "piano" # Options: "sine", "square", "sawtooth", "triangle", "noise", "piano"
|
||||||
|
volume = 0.8 # Track volume (0.0-1.0)
|
||||||
|
|
||||||
|
[tracks.pattern]
|
||||||
|
type = "custom" # Pattern type: "custom", "chord", "arpeggio", "sequence"
|
||||||
|
loop_length = 16.0 # How long before pattern repeats (in beats)
|
||||||
|
|
||||||
|
# Individual notes in the pattern
|
||||||
|
[[tracks.pattern.steps]]
|
||||||
|
time = 0.0 # When to play (in beats from start of loop)
|
||||||
|
note = "C5" # MIDI number or note name
|
||||||
|
duration = 1.5 # How long to hold the note (in beats)
|
||||||
|
velocity = 0.7 # How loud to play this note (0.0-1.0)
|
||||||
|
|
||||||
|
[[tracks.pattern.steps]]
|
||||||
|
time = 2.0
|
||||||
|
note = "E5"
|
||||||
|
duration = 1.0
|
||||||
|
velocity = 0.6
|
||||||
|
|
||||||
|
[[tracks.pattern.steps]]
|
||||||
|
time = 4.0
|
||||||
|
note = "G5"
|
||||||
|
duration = 2.0
|
||||||
|
velocity = 0.8
|
||||||
|
|
||||||
|
# Effects for this track
|
||||||
|
[[tracks.effects]]
|
||||||
|
type = "reverb"
|
||||||
|
room_size = 0.7 # Size of the reverb space (0.0-1.0)
|
||||||
|
damping = 0.5 # How much high frequencies are absorbed (0.0-1.0)
|
||||||
|
mix = 0.3 # How much effect to blend in (0.0-1.0)
|
||||||
|
|
||||||
|
[[tracks.effects]]
|
||||||
|
type = "delay"
|
||||||
|
time = 0.25 # Delay time in seconds (0.01-2.0)
|
||||||
|
feedback = 0.3 # How much delay repeats (0.0-0.95)
|
||||||
|
mix = 0.2 # How much effect to blend in (0.0-1.0)
|
||||||
|
|
||||||
|
# Example 2: Chord progression track
|
||||||
|
[[tracks]]
|
||||||
|
name = "harmony"
|
||||||
|
instrument = "sawtooth"
|
||||||
|
volume = 0.6
|
||||||
|
|
||||||
|
[tracks.pattern]
|
||||||
|
type = "chord"
|
||||||
|
loop_length = 16.0
|
||||||
|
voicing = "spread" # Options: "close", "spread", "drop2", "drop3"
|
||||||
|
octave = 3 # Which octave to play chords in (0-8)
|
||||||
|
|
||||||
|
# Chord progression
|
||||||
|
[[tracks.pattern.chord_progression]]
|
||||||
|
time = 0.0
|
||||||
|
chord = "Cmaj7" # Chord name (e.g., "C", "Am", "F#dim", "Bbmaj7")
|
||||||
|
duration = 4.0
|
||||||
|
|
||||||
|
[[tracks.pattern.chord_progression]]
|
||||||
|
time = 4.0
|
||||||
|
chord = "Am7"
|
||||||
|
duration = 4.0
|
||||||
|
|
||||||
|
[[tracks.pattern.chord_progression]]
|
||||||
|
time = 8.0
|
||||||
|
chord = "Fmaj7"
|
||||||
|
duration = 4.0
|
||||||
|
|
||||||
|
[[tracks.pattern.chord_progression]]
|
||||||
|
time = 12.0
|
||||||
|
chord = "G7"
|
||||||
|
duration = 4.0
|
||||||
|
|
||||||
|
# Effects for chord track
|
||||||
|
[[tracks.effects]]
|
||||||
|
type = "lowpass"
|
||||||
|
cutoff = 2000.0 # Cutoff frequency in Hz (20-20000)
|
||||||
|
resonance = 1.2 # Filter resonance (0.1-10.0)
|
||||||
|
|
||||||
|
# Example 3: Bass track
|
||||||
|
[[tracks]]
|
||||||
|
name = "bass"
|
||||||
|
instrument = "sine"
|
||||||
|
volume = 0.9
|
||||||
|
|
||||||
|
[tracks.pattern]
|
||||||
|
type = "custom"
|
||||||
|
loop_length = 8.0
|
||||||
|
|
||||||
|
[[tracks.pattern.steps]]
|
||||||
|
time = 0.0
|
||||||
|
note = "C2"
|
||||||
|
duration = 1.0
|
||||||
|
velocity = 0.9
|
||||||
|
|
||||||
|
[[tracks.pattern.steps]]
|
||||||
|
time = 2.0
|
||||||
|
note = "G2"
|
||||||
|
duration = 1.0
|
||||||
|
velocity = 0.8
|
||||||
|
|
||||||
|
[[tracks.pattern.steps]]
|
||||||
|
time = 4.0
|
||||||
|
note = "A2"
|
||||||
|
duration = 1.0
|
||||||
|
velocity = 0.8
|
||||||
|
|
||||||
|
[[tracks.pattern.steps]]
|
||||||
|
time = 6.0
|
||||||
|
note = "F2"
|
||||||
|
duration = 1.0
|
||||||
|
velocity = 0.9
|
||||||
|
|
||||||
|
# Bass effects
|
||||||
|
[[tracks.effects]]
|
||||||
|
type = "highpass"
|
||||||
|
cutoff = 80.0 # Remove very low frequencies
|
||||||
|
resonance = 0.7
|
||||||
|
|
||||||
|
# Example 4: Percussion track
|
||||||
|
[[tracks]]
|
||||||
|
name = "drums"
|
||||||
|
instrument = "noise"
|
||||||
|
volume = 0.7
|
||||||
|
|
||||||
|
[tracks.pattern]
|
||||||
|
type = "custom"
|
||||||
|
loop_length = 4.0
|
||||||
|
|
||||||
|
# Kick drum
|
||||||
|
[[tracks.pattern.steps]]
|
||||||
|
time = 0.0
|
||||||
|
note = "C1" # Low note for kick
|
||||||
|
duration = 0.1
|
||||||
|
velocity = 1.0
|
||||||
|
|
||||||
|
[[tracks.pattern.steps]]
|
||||||
|
time = 2.0
|
||||||
|
note = "C1"
|
||||||
|
duration = 0.1
|
||||||
|
velocity = 1.0
|
||||||
|
|
||||||
|
# Snare/hi-hat
|
||||||
|
[[tracks.pattern.steps]]
|
||||||
|
time = 1.0
|
||||||
|
note = "D4" # Higher note for snare
|
||||||
|
duration = 0.05
|
||||||
|
velocity = 0.7
|
||||||
|
|
||||||
|
[[tracks.pattern.steps]]
|
||||||
|
time = 3.0
|
||||||
|
note = "D4"
|
||||||
|
duration = 0.05
|
||||||
|
velocity = 0.7
|
||||||
|
|
||||||
|
# Drum effects
|
||||||
|
[[tracks.effects]]
|
||||||
|
type = "distortion"
|
||||||
|
drive = 1.5 # Amount of distortion (1.0-10.0)
|
||||||
|
tone = 0.6 # Tone control (0.0-1.0)
|
||||||
|
|
||||||
|
[[tracks.effects]]
|
||||||
|
type = "chorus"
|
||||||
|
rate = 1.2 # Modulation rate in Hz (0.1-10.0)
|
||||||
|
depth = 0.4 # Modulation depth (0.0-1.0)
|
||||||
|
layers = 3 # Number of chorus layers (1-8)
|
||||||
|
mix = 0.3
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# SECTIONS SECTION (Optional)
|
||||||
|
# For structured compositions with different parts
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
[[sections]]
|
||||||
|
name = "intro"
|
||||||
|
measures = 8
|
||||||
|
tempo = 100.0 # Optional tempo change for this section
|
||||||
|
complexity = 0.3 # Lower complexity for intro
|
||||||
|
repeat = 1 # How many times to repeat this section
|
||||||
|
|
||||||
|
[[sections]]
|
||||||
|
name = "verse"
|
||||||
|
measures = 16
|
||||||
|
complexity = 0.6
|
||||||
|
repeat = 2
|
||||||
|
|
||||||
|
[[sections]]
|
||||||
|
name = "chorus"
|
||||||
|
measures = 16
|
||||||
|
tempo = 125.0 # Faster tempo for chorus
|
||||||
|
complexity = 0.8
|
||||||
|
key = "F4" # Optional key change
|
||||||
|
scale = "major" # Optional scale change
|
||||||
|
repeat = 2
|
||||||
|
|
||||||
|
[[sections]]
|
||||||
|
name = "bridge"
|
||||||
|
measures = 8
|
||||||
|
complexity = 0.9
|
||||||
|
key = "Am" # Relative minor
|
||||||
|
repeat = 1
|
||||||
|
|
||||||
|
[[sections]]
|
||||||
|
name = "outro"
|
||||||
|
measures = 8
|
||||||
|
tempo = 90.0 # Slower outro
|
||||||
|
complexity = 0.2
|
||||||
|
repeat = 1
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# EXPORT SECTION
|
||||||
|
# How to save your finished composition
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
[export]
|
||||||
|
filename = "my_song" # Output filename (without extension)
|
||||||
|
format = "wav" # Only "wav" currently supported
|
||||||
|
sample_rate = 44100 # Options: 22050, 44100, 48000, 96000
|
||||||
|
bit_depth = 24 # Options: 16, 24, 32
|
||||||
|
stereo = true # true for stereo, false for mono
|
||||||
|
max_duration = 180.0 # Maximum length in seconds (optional)
|
||||||
|
|
||||||
|
# Optional: Generate variations of your composition
|
||||||
|
[export.variations]
|
||||||
|
count = 3 # Number of variations to generate
|
||||||
|
vary_complexity = true # Vary the complexity between versions
|
||||||
|
vary_rhythm = true # Vary the rhythmic patterns
|
||||||
|
vary_harmony = false # Vary the chord progressions
|
||||||
|
vary_tempo = false # Vary the tempo
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# EFFECT TYPES REFERENCE
|
||||||
|
# Complete list of all available effects and their parameters
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# FILTERS
|
||||||
|
# [[tracks.effects]]
|
||||||
|
# type = "lowpass" # Removes high frequencies (makes sound warmer/duller)
|
||||||
|
# cutoff = 1000.0 # Frequency cutoff in Hz (20-20000)
|
||||||
|
# resonance = 1.0 # Emphasis at cutoff frequency (0.1-10.0)
|
||||||
|
|
||||||
|
# [[tracks.effects]]
|
||||||
|
# type = "highpass" # Removes low frequencies (makes sound thinner/brighter)
|
||||||
|
# cutoff = 100.0 # Frequency cutoff in Hz (20-20000)
|
||||||
|
# resonance = 1.0 # Emphasis at cutoff frequency (0.1-10.0)
|
||||||
|
|
||||||
|
# TIME-BASED EFFECTS
|
||||||
|
# [[tracks.effects]]
|
||||||
|
# type = "delay" # Echo effect
|
||||||
|
# time = 0.25 # Delay time in seconds (0.01-2.0)
|
||||||
|
# feedback = 0.3 # How much delay feeds back (0.0-0.95)
|
||||||
|
# mix = 0.3 # Wet/dry mix (0.0-1.0)
|
||||||
|
|
||||||
|
# [[tracks.effects]]
|
||||||
|
# type = "reverb" # Spatial reverb
|
||||||
|
# room_size = 0.5 # Size of reverb space (0.0-1.0)
|
||||||
|
# damping = 0.5 # High frequency absorption (0.0-1.0)
|
||||||
|
# mix = 0.3 # Wet/dry mix (0.0-1.0)
|
||||||
|
|
||||||
|
# [[tracks.effects]]
|
||||||
|
# type = "chorus" # Thickening/modulation effect
|
||||||
|
# rate = 1.0 # Modulation rate in Hz (0.1-10.0)
|
||||||
|
# depth = 0.5 # Modulation depth (0.0-1.0)
|
||||||
|
# layers = 3 # Number of voices (1-8)
|
||||||
|
# mix = 0.3 # Wet/dry mix (0.0-1.0)
|
||||||
|
|
||||||
|
# DISTORTION
|
||||||
|
# [[tracks.effects]]
|
||||||
|
# type = "distortion" # Hard clipping distortion
|
||||||
|
# drive = 2.0 # Amount of distortion (1.0-10.0)
|
||||||
|
# tone = 0.5 # Tone control (0.0-1.0, 0=dark, 1=bright)
|
||||||
|
|
||||||
|
# LO-FI EFFECTS
|
||||||
|
# [[tracks.effects]]
|
||||||
|
# type = "vinyl" # Vinyl crackle and surface noise
|
||||||
|
# intensity = 0.5 # Crackle intensity (0.0-1.0)
|
||||||
|
# frequency = 0.5 # Crackle frequency (0.0-1.0)
|
||||||
|
# mix = 0.3 # Wet/dry mix (0.0-1.0)
|
||||||
|
|
||||||
|
# [[tracks.effects]]
|
||||||
|
# type = "tape" # Tape saturation and warmth
|
||||||
|
# drive = 2.0 # Saturation amount (1.0-10.0)
|
||||||
|
# warmth = 0.7 # Warmth/color (0.0-1.0)
|
||||||
|
# mix = 0.5 # Wet/dry mix (0.0-1.0)
|
||||||
|
|
||||||
|
# [[tracks.effects]]
|
||||||
|
# type = "bitcrusher" # Digital degradation
|
||||||
|
# bit_depth = 8.0 # Bit depth reduction (1.0-16.0)
|
||||||
|
# sample_rate_reduction = 2.0 # Sample rate reduction factor (1.0-10.0)
|
||||||
|
# mix = 0.5 # Wet/dry mix (0.0-1.0)
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# INSTRUMENT TYPES REFERENCE
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# instrument = "sine" # Pure sine wave - smooth, warm, flute-like
|
||||||
|
# instrument = "square" # Square wave - classic video game sound, punchy
|
||||||
|
# instrument = "sawtooth" # Sawtooth wave - bright, buzzy, good for leads
|
||||||
|
# instrument = "triangle" # Triangle wave - mellow, soft, like filtered square
|
||||||
|
# instrument = "noise" # White noise - for percussion and texture
|
||||||
|
# instrument = "piano" # Natural piano with harmonics
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# PATTERN TYPES REFERENCE
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# type = "custom" # Specify exact notes and timing
|
||||||
|
# type = "chord" # Play chord progressions
|
||||||
|
# type = "arpeggio" # Arpeggiate chords (play notes one after another)
|
||||||
|
# type = "sequence" # Step sequencer patterns
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# CHORD NAMES REFERENCE
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Basic triads: "C", "Dm", "E", "F#", "Bb"
|
||||||
|
# Seventh chords: "Cmaj7", "Dm7", "E7", "F#m7b5", "Bbmaj7"
|
||||||
|
# Extended chords: "C9", "Dm11", "E13"
|
||||||
|
# Altered chords: "C7#11", "Dm7b5", "E7alt"
|
||||||
|
# Diminished/Augmented: "Cdim", "Caug", "C°7", "C+7"
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# NOTE NAMES REFERENCE
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
# Format: [Note][Accidental][Octave]
|
||||||
|
# Notes: C, D, E, F, G, A, B
|
||||||
|
# Accidentals: # (sharp), b (flat), ♯, ♭
|
||||||
|
# Octaves: 0-9 (C4 = middle C = MIDI 60)
|
||||||
|
# Examples: "C4", "F#3", "Bb5", "A0", "G9"
|
||||||
|
|
||||||
|
# MIDI equivalents:
|
||||||
|
# C4 = 60, C#4 = 61, D4 = 62, D#4 = 63, E4 = 64, F4 = 65
|
||||||
|
# F#4 = 66, G4 = 67, G#4 = 68, A4 = 69, A#4 = 70, B4 = 71
|
||||||
|
# Add/subtract 12 for different octaves
|
@ -1,666 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"$id": "https://example.com/schemas/composition-config.json",
|
|
||||||
"title": "Generate electronic music without AI",
|
|
||||||
"description": "JSON schema for configuring musicgen",
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"metadata": {
|
|
||||||
"type": "object",
|
|
||||||
"description": "Metadata about the composition",
|
|
||||||
"properties": {
|
|
||||||
"title": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Composition title",
|
|
||||||
"default": ""
|
|
||||||
},
|
|
||||||
"artist": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Artist or composer name",
|
|
||||||
"default": ""
|
|
||||||
},
|
|
||||||
"description": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Description of the composition",
|
|
||||||
"default": ""
|
|
||||||
},
|
|
||||||
"tags": {
|
|
||||||
"type": "array",
|
|
||||||
"description": "Tags or genres",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"default": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"composition": {
|
|
||||||
"type": "object",
|
|
||||||
"description": "Global composition settings",
|
|
||||||
"required": ["key", "scale", "tempo", "measures"],
|
|
||||||
"properties": {
|
|
||||||
"key": {
|
|
||||||
"description": "Musical key",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 0,
|
|
||||||
"maximum": 127,
|
|
||||||
"description": "MIDI note number (60 = C4)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"pattern": "^[A-G][#b♯♭]?[0-9]$",
|
|
||||||
"description": "Note name (e.g., 'C4', 'F#3', 'Bb5')"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"scale": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Scale type",
|
|
||||||
"enum": [
|
|
||||||
"major",
|
|
||||||
"minor",
|
|
||||||
"dorian",
|
|
||||||
"phrygian",
|
|
||||||
"lydian",
|
|
||||||
"mixolydian",
|
|
||||||
"aeolian",
|
|
||||||
"locrian",
|
|
||||||
"pentatonic",
|
|
||||||
"blues",
|
|
||||||
"chromatic"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tempo": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Tempo in beats per minute (BPM)",
|
|
||||||
"minimum": 40,
|
|
||||||
"maximum": 300
|
|
||||||
},
|
|
||||||
"time_signature": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"numerator": {
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 1,
|
|
||||||
"maximum": 16,
|
|
||||||
"description": "Number of beats per measure"
|
|
||||||
},
|
|
||||||
"denominator": {
|
|
||||||
"type": "integer",
|
|
||||||
"enum": [2, 4, 8, 16],
|
|
||||||
"description": "Note value that gets one beat"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["numerator", "denominator"],
|
|
||||||
"additionalProperties": false,
|
|
||||||
"default": {
|
|
||||||
"numerator": 4,
|
|
||||||
"denominator": 4
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"measures": {
|
|
||||||
"type": "integer",
|
|
||||||
"description": "Number of measures in the composition",
|
|
||||||
"minimum": 1,
|
|
||||||
"maximum": 1000
|
|
||||||
},
|
|
||||||
"complexity": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Musical complexity level (0.0 = simple, 1.0 = complex)",
|
|
||||||
"minimum": 0.0,
|
|
||||||
"maximum": 1.0,
|
|
||||||
"default": 0.6
|
|
||||||
},
|
|
||||||
"harmony_density": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Harmonic density (0.0 = sparse, 1.0 = dense)",
|
|
||||||
"minimum": 0.0,
|
|
||||||
"maximum": 1.0,
|
|
||||||
"default": 0.7
|
|
||||||
},
|
|
||||||
"rhythmic_density": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Rhythmic density (0.0 = sparse, 1.0 = dense)",
|
|
||||||
"minimum": 0.0,
|
|
||||||
"maximum": 1.0,
|
|
||||||
"default": 0.8
|
|
||||||
},
|
|
||||||
"seed": {
|
|
||||||
"type": "integer",
|
|
||||||
"description": "Random seed for reproducible generation",
|
|
||||||
"minimum": 0,
|
|
||||||
"maximum": 18446744073709551615
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"tracks": {
|
|
||||||
"type": "array",
|
|
||||||
"description": "Individual track definitions",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"required": ["name", "instrument", "pattern"],
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Track name (e.g., 'bass', 'kick', 'hihat', 'pad')"
|
|
||||||
},
|
|
||||||
"instrument": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Instrument/waveform type",
|
|
||||||
"enum": ["sine", "square", "sawtooth", "triangle", "noise", "piano"]
|
|
||||||
},
|
|
||||||
"volume": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Track volume level (0.0 = silent, 1.0 = full)",
|
|
||||||
"minimum": 0.0,
|
|
||||||
"maximum": 1.0,
|
|
||||||
"default": 1.0
|
|
||||||
},
|
|
||||||
"pattern": {
|
|
||||||
"type": "object",
|
|
||||||
"description": "Pattern definition for this track",
|
|
||||||
"required": ["type"],
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Pattern type",
|
|
||||||
"enum": ["custom", "chord", "arpeggio", "sequence"]
|
|
||||||
},
|
|
||||||
"loop_length": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Pattern loop length in beats",
|
|
||||||
"minimum": 0.1,
|
|
||||||
"maximum": 64.0,
|
|
||||||
"default": 4.0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"if": {
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"const": "custom"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"then": {
|
|
||||||
"properties": {
|
|
||||||
"steps": {
|
|
||||||
"type": "array",
|
|
||||||
"description": "Individual pattern steps",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"required": ["time", "note", "duration", "velocity"],
|
|
||||||
"properties": {
|
|
||||||
"time": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Time in beats when note starts",
|
|
||||||
"minimum": 0.0
|
|
||||||
},
|
|
||||||
"note": {
|
|
||||||
"description": "Note to play",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 0,
|
|
||||||
"maximum": 127,
|
|
||||||
"description": "MIDI note number"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"pattern": "^[A-G][#b♯♭]?[0-9]$",
|
|
||||||
"description": "Note name (e.g., 'C4', 'F#3')"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"duration": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Note duration in beats",
|
|
||||||
"minimum": 0.01,
|
|
||||||
"maximum": 16.0
|
|
||||||
},
|
|
||||||
"velocity": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Note velocity/volume (0.0 to 1.0)",
|
|
||||||
"minimum": 0.0,
|
|
||||||
"maximum": 1.0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["steps"]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"if": {
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"const": "chord"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"then": {
|
|
||||||
"properties": {
|
|
||||||
"chord_progression": {
|
|
||||||
"type": "array",
|
|
||||||
"description": "Chord progression steps",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"required": ["time", "chord", "duration"],
|
|
||||||
"properties": {
|
|
||||||
"time": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Time in beats when chord starts",
|
|
||||||
"minimum": 0.0
|
|
||||||
},
|
|
||||||
"chord": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Chord name (e.g., 'Cm7', 'F', 'G#maj7')"
|
|
||||||
},
|
|
||||||
"duration": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Chord duration in beats",
|
|
||||||
"minimum": 0.1,
|
|
||||||
"maximum": 16.0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"voicing": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Chord voicing style",
|
|
||||||
"enum": ["close", "spread", "drop2", "drop3"],
|
|
||||||
"default": "close"
|
|
||||||
},
|
|
||||||
"octave": {
|
|
||||||
"type": "integer",
|
|
||||||
"description": "Base octave for chord",
|
|
||||||
"minimum": 0,
|
|
||||||
"maximum": 8,
|
|
||||||
"default": 4
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["chord_progression"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"effects": {
|
|
||||||
"type": "array",
|
|
||||||
"description": "Audio effects to apply to this track",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"required": ["type"],
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Effect type",
|
|
||||||
"enum": [
|
|
||||||
"lowpass",
|
|
||||||
"highpass",
|
|
||||||
"bandpass",
|
|
||||||
"delay",
|
|
||||||
"reverb",
|
|
||||||
"chorus",
|
|
||||||
"distortion",
|
|
||||||
"compressor"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"if": {
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"const": "lowpass"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"then": {
|
|
||||||
"properties": {
|
|
||||||
"cutoff": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Cutoff frequency in Hz",
|
|
||||||
"minimum": 20,
|
|
||||||
"maximum": 20000,
|
|
||||||
"default": 1000
|
|
||||||
},
|
|
||||||
"resonance": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Resonance factor",
|
|
||||||
"minimum": 0.1,
|
|
||||||
"maximum": 10.0,
|
|
||||||
"default": 1.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"if": {
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"const": "highpass"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"then": {
|
|
||||||
"properties": {
|
|
||||||
"cutoff": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Cutoff frequency in Hz",
|
|
||||||
"minimum": 20,
|
|
||||||
"maximum": 20000,
|
|
||||||
"default": 100
|
|
||||||
},
|
|
||||||
"resonance": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Resonance factor",
|
|
||||||
"minimum": 0.1,
|
|
||||||
"maximum": 10.0,
|
|
||||||
"default": 1.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"if": {
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"const": "delay"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"then": {
|
|
||||||
"properties": {
|
|
||||||
"time": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Delay time in seconds",
|
|
||||||
"minimum": 0.001,
|
|
||||||
"maximum": 2.0,
|
|
||||||
"default": 0.25
|
|
||||||
},
|
|
||||||
"feedback": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Feedback amount",
|
|
||||||
"minimum": 0.0,
|
|
||||||
"maximum": 0.95,
|
|
||||||
"default": 0.3
|
|
||||||
},
|
|
||||||
"mix": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Wet/dry mix",
|
|
||||||
"minimum": 0.0,
|
|
||||||
"maximum": 1.0,
|
|
||||||
"default": 0.3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"if": {
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"const": "reverb"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"then": {
|
|
||||||
"properties": {
|
|
||||||
"room_size": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Room size",
|
|
||||||
"minimum": 0.0,
|
|
||||||
"maximum": 1.0,
|
|
||||||
"default": 0.5
|
|
||||||
},
|
|
||||||
"damping": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "High frequency damping",
|
|
||||||
"minimum": 0.0,
|
|
||||||
"maximum": 1.0,
|
|
||||||
"default": 0.5
|
|
||||||
},
|
|
||||||
"mix": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Wet/dry mix",
|
|
||||||
"minimum": 0.0,
|
|
||||||
"maximum": 1.0,
|
|
||||||
"default": 0.3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"if": {
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"const": "chorus"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"then": {
|
|
||||||
"properties": {
|
|
||||||
"rate": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "LFO rate in Hz",
|
|
||||||
"minimum": 0.1,
|
|
||||||
"maximum": 10.0,
|
|
||||||
"default": 1.0
|
|
||||||
},
|
|
||||||
"depth": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Modulation depth",
|
|
||||||
"minimum": 0.0,
|
|
||||||
"maximum": 1.0,
|
|
||||||
"default": 0.5
|
|
||||||
},
|
|
||||||
"layers": {
|
|
||||||
"type": "integer",
|
|
||||||
"description": "Number of chorus layers",
|
|
||||||
"minimum": 1,
|
|
||||||
"maximum": 4,
|
|
||||||
"default": 2
|
|
||||||
},
|
|
||||||
"mix": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Wet/dry mix",
|
|
||||||
"minimum": 0.0,
|
|
||||||
"maximum": 1.0,
|
|
||||||
"default": 0.5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"if": {
|
|
||||||
"properties": {
|
|
||||||
"type": {
|
|
||||||
"const": "distortion"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"then": {
|
|
||||||
"properties": {
|
|
||||||
"drive": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Distortion amount",
|
|
||||||
"minimum": 0.0,
|
|
||||||
"maximum": 1.0,
|
|
||||||
"default": 0.5
|
|
||||||
},
|
|
||||||
"tone": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Tone control (0.0 = dark, 1.0 = bright)",
|
|
||||||
"minimum": 0.0,
|
|
||||||
"maximum": 1.0,
|
|
||||||
"default": 0.5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sections": {
|
|
||||||
"type": "array",
|
|
||||||
"description": "Section definitions for structured compositions",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"required": ["name", "measures"],
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Section name (e.g., 'intro', 'verse', 'chorus', 'bridge', 'outro')"
|
|
||||||
},
|
|
||||||
"measures": {
|
|
||||||
"type": "integer",
|
|
||||||
"description": "Number of measures in this section",
|
|
||||||
"minimum": 1,
|
|
||||||
"maximum": 1000
|
|
||||||
},
|
|
||||||
"tempo": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Tempo override for this section",
|
|
||||||
"minimum": 40,
|
|
||||||
"maximum": 300
|
|
||||||
},
|
|
||||||
"key": {
|
|
||||||
"description": "Key change for this section",
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"type": "integer",
|
|
||||||
"minimum": 0,
|
|
||||||
"maximum": 127
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"pattern": "^[A-G][#b♯♭]?[0-9]$"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"scale": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Scale override for this section",
|
|
||||||
"enum": [
|
|
||||||
"major",
|
|
||||||
"minor",
|
|
||||||
"dorian",
|
|
||||||
"phrygian",
|
|
||||||
"lydian",
|
|
||||||
"mixolydian",
|
|
||||||
"aeolian",
|
|
||||||
"locrian",
|
|
||||||
"pentatonic",
|
|
||||||
"blues",
|
|
||||||
"chromatic"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"complexity": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Complexity override for this section",
|
|
||||||
"minimum": 0.0,
|
|
||||||
"maximum": 1.0
|
|
||||||
},
|
|
||||||
"repeat": {
|
|
||||||
"type": "integer",
|
|
||||||
"description": "Number of times to repeat this section",
|
|
||||||
"minimum": 1,
|
|
||||||
"maximum": 100,
|
|
||||||
"default": 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"export": {
|
|
||||||
"type": "object",
|
|
||||||
"description": "Export settings",
|
|
||||||
"properties": {
|
|
||||||
"filename": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Output filename (without extension)",
|
|
||||||
"default": "output"
|
|
||||||
},
|
|
||||||
"format": {
|
|
||||||
"type": "string",
|
|
||||||
"description": "Export format",
|
|
||||||
"enum": ["wav", "mp3", "flac"],
|
|
||||||
"default": "wav"
|
|
||||||
},
|
|
||||||
"sample_rate": {
|
|
||||||
"type": "integer",
|
|
||||||
"description": "Sample rate in Hz",
|
|
||||||
"enum": [22050, 44100, 48000, 88200, 96000],
|
|
||||||
"default": 44100
|
|
||||||
},
|
|
||||||
"bit_depth": {
|
|
||||||
"type": "integer",
|
|
||||||
"description": "Bit depth",
|
|
||||||
"enum": [16, 24, 32],
|
|
||||||
"default": 16
|
|
||||||
},
|
|
||||||
"stereo": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Export in stereo (true) or mono (false)",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"max_duration": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Maximum duration in seconds (null for full composition)",
|
|
||||||
"minimum": 1.0,
|
|
||||||
"maximum": 3600.0
|
|
||||||
},
|
|
||||||
"variations": {
|
|
||||||
"type": "object",
|
|
||||||
"description": "Variation generation settings",
|
|
||||||
"properties": {
|
|
||||||
"count": {
|
|
||||||
"type": "integer",
|
|
||||||
"description": "Number of variations to generate",
|
|
||||||
"minimum": 1,
|
|
||||||
"maximum": 100
|
|
||||||
},
|
|
||||||
"vary_complexity": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Vary complexity between variations",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"vary_rhythm": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Vary rhythm between variations",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"vary_harmony": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Vary harmony between variations",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"vary_tempo": {
|
|
||||||
"type": "boolean",
|
|
||||||
"description": "Vary tempo between variations",
|
|
||||||
"default": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["count"],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"required": ["composition"],
|
|
||||||
"additionalProperties": false
|
|
||||||
}
|
|
@ -1,697 +0,0 @@
|
|||||||
{
|
|
||||||
"metadata": {
|
|
||||||
"title": "Enchanted",
|
|
||||||
"artist": "Enchanted",
|
|
||||||
"description": "A waltx in 3/4 time."
|
|
||||||
},
|
|
||||||
"composition": {
|
|
||||||
"key": "Bb3",
|
|
||||||
"scale": "major",
|
|
||||||
"tempo": 132,
|
|
||||||
"time_signature": {
|
|
||||||
"numerator": 3,
|
|
||||||
"denominator": 4
|
|
||||||
},
|
|
||||||
"measures": 64,
|
|
||||||
"complexity": 0.8,
|
|
||||||
"harmony_density": 0.9,
|
|
||||||
"rhythmic_density": 0.6
|
|
||||||
},
|
|
||||||
"tracks": [
|
|
||||||
{
|
|
||||||
"name": "piano_melody",
|
|
||||||
"instrument": "piano",
|
|
||||||
"volume": 0.8,
|
|
||||||
"pattern": {
|
|
||||||
"type": "custom",
|
|
||||||
"loop_length": 96.0,
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"time": 0.0,
|
|
||||||
"note": "D5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 1.5,
|
|
||||||
"note": "Eb5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 2.5,
|
|
||||||
"note": "F5",
|
|
||||||
"duration": 0.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 3.0,
|
|
||||||
"note": "G5",
|
|
||||||
"duration": 2.0,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 5.0,
|
|
||||||
"note": "F5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 6.0,
|
|
||||||
"note": "Eb5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 7.5,
|
|
||||||
"note": "D5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 9.0,
|
|
||||||
"note": "C5",
|
|
||||||
"duration": 2.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 11.0,
|
|
||||||
"note": "Bb4",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 12.0,
|
|
||||||
"note": "C5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 13.5,
|
|
||||||
"note": "D5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 14.5,
|
|
||||||
"note": "Eb5",
|
|
||||||
"duration": 0.5,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 15.0,
|
|
||||||
"note": "F5",
|
|
||||||
"duration": 2.0,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 17.0,
|
|
||||||
"note": "G5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 18.0,
|
|
||||||
"note": "A5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 19.5,
|
|
||||||
"note": "Bb5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 21.0,
|
|
||||||
"note": "A5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 22.0,
|
|
||||||
"note": "G5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 23.0,
|
|
||||||
"note": "F5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 24.0,
|
|
||||||
"note": "Eb5",
|
|
||||||
"duration": 2.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 26.0,
|
|
||||||
"note": "D5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 27.0,
|
|
||||||
"note": "C5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 28.5,
|
|
||||||
"note": "Bb4",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 30.0,
|
|
||||||
"note": "C5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 31.0,
|
|
||||||
"note": "D5",
|
|
||||||
"duration": 2.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 36.0,
|
|
||||||
"note": "G5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 37.5,
|
|
||||||
"note": "A5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 38.5,
|
|
||||||
"note": "Bb5",
|
|
||||||
"duration": 0.5,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 39.0,
|
|
||||||
"note": "C6",
|
|
||||||
"duration": 2.0,
|
|
||||||
"velocity": 0.8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 41.0,
|
|
||||||
"note": "Bb5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 42.0,
|
|
||||||
"note": "A5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 43.5,
|
|
||||||
"note": "G5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 45.0,
|
|
||||||
"note": "F5",
|
|
||||||
"duration": 2.0,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 47.0,
|
|
||||||
"note": "Eb5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 48.0,
|
|
||||||
"note": "F5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 49.5,
|
|
||||||
"note": "G5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 50.5,
|
|
||||||
"note": "A5",
|
|
||||||
"duration": 0.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 51.0,
|
|
||||||
"note": "Bb5",
|
|
||||||
"duration": 2.0,
|
|
||||||
"velocity": 0.8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 53.0,
|
|
||||||
"note": "C6",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 54.0,
|
|
||||||
"note": "D6",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.8
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 55.5,
|
|
||||||
"note": "C6",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 57.0,
|
|
||||||
"note": "Bb5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 58.0,
|
|
||||||
"note": "A5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 59.0,
|
|
||||||
"note": "G5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 60.0,
|
|
||||||
"note": "F5",
|
|
||||||
"duration": 2.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 62.0,
|
|
||||||
"note": "Eb5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 63.0,
|
|
||||||
"note": "D5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 64.5,
|
|
||||||
"note": "C5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 66.0,
|
|
||||||
"note": "Bb4",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 67.0,
|
|
||||||
"note": "C5",
|
|
||||||
"duration": 2.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 72.0,
|
|
||||||
"note": "F5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 73.5,
|
|
||||||
"note": "G5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 74.5,
|
|
||||||
"note": "A5",
|
|
||||||
"duration": 0.5,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 75.0,
|
|
||||||
"note": "Bb5",
|
|
||||||
"duration": 2.0,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 77.0,
|
|
||||||
"note": "A5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 78.0,
|
|
||||||
"note": "G5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 79.5,
|
|
||||||
"note": "F5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 81.0,
|
|
||||||
"note": "Eb5",
|
|
||||||
"duration": 2.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 83.0,
|
|
||||||
"note": "D5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 84.0,
|
|
||||||
"note": "Eb5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 85.5,
|
|
||||||
"note": "F5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 86.5,
|
|
||||||
"note": "G5",
|
|
||||||
"duration": 0.5,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 87.0,
|
|
||||||
"note": "A5",
|
|
||||||
"duration": 2.0,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 89.0,
|
|
||||||
"note": "Bb5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 90.0,
|
|
||||||
"note": "G5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 91.5,
|
|
||||||
"note": "F5",
|
|
||||||
"duration": 1.5,
|
|
||||||
"velocity": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 93.0,
|
|
||||||
"note": "Eb5",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 94.0,
|
|
||||||
"note": "D5",
|
|
||||||
"duration": 2.0,
|
|
||||||
"velocity": 0.6
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "reverb",
|
|
||||||
"room_size": 0.8,
|
|
||||||
"damping": 0.7,
|
|
||||||
"mix": 0.4
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "delay",
|
|
||||||
"time": 0.25,
|
|
||||||
"feedback": 0.15,
|
|
||||||
"mix": 0.2
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "string_harmony",
|
|
||||||
"instrument": "sawtooth",
|
|
||||||
"volume": 0.4,
|
|
||||||
"pattern": {
|
|
||||||
"type": "chord",
|
|
||||||
"loop_length": 48.0,
|
|
||||||
"chord_progression": [
|
|
||||||
{
|
|
||||||
"time": 0.0,
|
|
||||||
"chord": "Bb",
|
|
||||||
"duration": 6.0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 6.0,
|
|
||||||
"chord": "F",
|
|
||||||
"duration": 6.0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 12.0,
|
|
||||||
"chord": "Gm",
|
|
||||||
"duration": 6.0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 18.0,
|
|
||||||
"chord": "Eb",
|
|
||||||
"duration": 6.0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 24.0,
|
|
||||||
"chord": "Bb",
|
|
||||||
"duration": 6.0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 30.0,
|
|
||||||
"chord": "F",
|
|
||||||
"duration": 6.0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 36.0,
|
|
||||||
"chord": "Gm",
|
|
||||||
"duration": 6.0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 42.0,
|
|
||||||
"chord": "Bb",
|
|
||||||
"duration": 6.0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"voicing": "spread",
|
|
||||||
"octave": 3
|
|
||||||
},
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "lowpass",
|
|
||||||
"cutoff": 4000,
|
|
||||||
"resonance": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "reverb",
|
|
||||||
"room_size": 0.9,
|
|
||||||
"damping": 0.8,
|
|
||||||
"mix": 0.6
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "waltz_bass",
|
|
||||||
"instrument": "sine",
|
|
||||||
"volume": 0.6,
|
|
||||||
"pattern": {
|
|
||||||
"type": "custom",
|
|
||||||
"loop_length": 12.0,
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"time": 0.0,
|
|
||||||
"note": "Bb2",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 1.0,
|
|
||||||
"note": "F2",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 2.0,
|
|
||||||
"note": "F2",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 3.0,
|
|
||||||
"note": "F2",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 4.0,
|
|
||||||
"note": "C3",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 5.0,
|
|
||||||
"note": "C3",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 6.0,
|
|
||||||
"note": "G2",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 7.0,
|
|
||||||
"note": "D3",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 8.0,
|
|
||||||
"note": "D3",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 9.0,
|
|
||||||
"note": "Eb2",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 10.0,
|
|
||||||
"note": "Bb2",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 11.0,
|
|
||||||
"note": "Bb2",
|
|
||||||
"duration": 1.0,
|
|
||||||
"velocity": 0.5
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "lowpass",
|
|
||||||
"cutoff": 2000,
|
|
||||||
"resonance": 0.8
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "gentle_percussion",
|
|
||||||
"instrument": "triangle",
|
|
||||||
"volume": 0.25,
|
|
||||||
"pattern": {
|
|
||||||
"type": "custom",
|
|
||||||
"loop_length": 3.0,
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"time": 0.0,
|
|
||||||
"note": "C4",
|
|
||||||
"duration": 0.1,
|
|
||||||
"velocity": 0.4
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 1.0,
|
|
||||||
"note": "C4",
|
|
||||||
"duration": 0.1,
|
|
||||||
"velocity": 0.3
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 2.0,
|
|
||||||
"note": "C4",
|
|
||||||
"duration": 0.1,
|
|
||||||
"velocity": 0.3
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "highpass",
|
|
||||||
"cutoff": 2000,
|
|
||||||
"resonance": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "reverb",
|
|
||||||
"room_size": 0.6,
|
|
||||||
"damping": 0.9,
|
|
||||||
"mix": 0.5
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "atmospheric_pad",
|
|
||||||
"instrument": "sine",
|
|
||||||
"volume": 0.15,
|
|
||||||
"pattern": {
|
|
||||||
"type": "chord",
|
|
||||||
"loop_length": 24.0,
|
|
||||||
"chord_progression": [
|
|
||||||
{
|
|
||||||
"time": 0.0,
|
|
||||||
"chord": "Bbmaj7",
|
|
||||||
"duration": 12.0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"time": 12.0,
|
|
||||||
"chord": "Gm7",
|
|
||||||
"duration": 12.0
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"voicing": "spread",
|
|
||||||
"octave": 2
|
|
||||||
},
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "lowpass",
|
|
||||||
"cutoff": 1500,
|
|
||||||
"resonance": 0.4
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "reverb",
|
|
||||||
"room_size": 1.0,
|
|
||||||
"damping": 0.9,
|
|
||||||
"mix": 0.8
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"export": {
|
|
||||||
"filename": "enchanted",
|
|
||||||
"format": "wav",
|
|
||||||
"sample_rate": 44100,
|
|
||||||
"bit_depth": 24,
|
|
||||||
"stereo": true,
|
|
||||||
"max_duration": 88.0
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,231 +0,0 @@
|
|||||||
{
|
|
||||||
"metadata": {
|
|
||||||
"title": "Fantasy",
|
|
||||||
"artist": "Atridad Lahiji",
|
|
||||||
"description": "A generic fantasy beat."
|
|
||||||
},
|
|
||||||
"composition": {
|
|
||||||
"key": 60,
|
|
||||||
"scale": "minor",
|
|
||||||
"tempo": 85.0,
|
|
||||||
"time_signature": {
|
|
||||||
"numerator": 4,
|
|
||||||
"denominator": 4
|
|
||||||
},
|
|
||||||
"measures": 18
|
|
||||||
},
|
|
||||||
"tracks": [
|
|
||||||
{
|
|
||||||
"name": "deep_bass",
|
|
||||||
"instrument": "sine",
|
|
||||||
"volume": 0.7,
|
|
||||||
"pattern": {
|
|
||||||
"type": "custom",
|
|
||||||
"steps": [
|
|
||||||
{ "time": 0.0, "note": "C2", "duration": 0.75, "velocity": 0.9 },
|
|
||||||
{ "time": 1.0, "note": "C2", "duration": 0.75, "velocity": 0.8 },
|
|
||||||
{ "time": 2.0, "note": "G1", "duration": 0.75, "velocity": 0.85 },
|
|
||||||
{ "time": 3.0, "note": "G1", "duration": 0.75, "velocity": 0.8 }
|
|
||||||
],
|
|
||||||
"loop_length": 4.0
|
|
||||||
},
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "lowpass",
|
|
||||||
"cutoff": 400.0,
|
|
||||||
"resonance": 1.8
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "sub_bass",
|
|
||||||
"instrument": "square",
|
|
||||||
"volume": 0.5,
|
|
||||||
"pattern": {
|
|
||||||
"type": "custom",
|
|
||||||
"steps": [
|
|
||||||
{ "time": 0.5, "note": "C3", "duration": 0.25, "velocity": 0.6 },
|
|
||||||
{ "time": 1.5, "note": "Eb3", "duration": 0.25, "velocity": 0.6 },
|
|
||||||
{ "time": 2.5, "note": "G3", "duration": 0.25, "velocity": 0.6 },
|
|
||||||
{ "time": 3.5, "note": "F3", "duration": 0.25, "velocity": 0.6 }
|
|
||||||
],
|
|
||||||
"loop_length": 4.0
|
|
||||||
},
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "lowpass",
|
|
||||||
"cutoff": 800.0,
|
|
||||||
"resonance": 2.0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "lofi_kick",
|
|
||||||
"instrument": "sine",
|
|
||||||
"volume": 0.6,
|
|
||||||
"pattern": {
|
|
||||||
"type": "custom",
|
|
||||||
"steps": [
|
|
||||||
{ "time": 0.0, "note": "C1", "duration": 0.1, "velocity": 1.0 },
|
|
||||||
{ "time": 1.0, "note": "C1", "duration": 0.1, "velocity": 0.8 },
|
|
||||||
{ "time": 2.0, "note": "C1", "duration": 0.1, "velocity": 0.9 },
|
|
||||||
{ "time": 3.0, "note": "C1", "duration": 0.1, "velocity": 0.7 }
|
|
||||||
],
|
|
||||||
"loop_length": 4.0
|
|
||||||
},
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "lowpass",
|
|
||||||
"cutoff": 200.0,
|
|
||||||
"resonance": 1.0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "distortion",
|
|
||||||
"drive": 0.3,
|
|
||||||
"tone": 0.2
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "lofi_snare",
|
|
||||||
"instrument": "noise",
|
|
||||||
"volume": 0.3,
|
|
||||||
"pattern": {
|
|
||||||
"type": "custom",
|
|
||||||
"steps": [
|
|
||||||
{ "time": 1.0, "note": "E3", "duration": 0.05, "velocity": 0.7 },
|
|
||||||
{ "time": 3.0, "note": "E3", "duration": 0.05, "velocity": 0.8 }
|
|
||||||
],
|
|
||||||
"loop_length": 4.0
|
|
||||||
},
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "highpass",
|
|
||||||
"cutoff": 200.0,
|
|
||||||
"resonance": 1.0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "lowpass",
|
|
||||||
"cutoff": 600.0,
|
|
||||||
"resonance": 1.5
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "lofi_hihat",
|
|
||||||
"instrument": "noise",
|
|
||||||
"volume": 0.2,
|
|
||||||
"pattern": {
|
|
||||||
"type": "custom",
|
|
||||||
"steps": [
|
|
||||||
{ "time": 0.5, "note": "A4", "duration": 0.02, "velocity": 0.4 },
|
|
||||||
{ "time": 1.5, "note": "A4", "duration": 0.02, "velocity": 0.4 },
|
|
||||||
{ "time": 2.5, "note": "A4", "duration": 0.02, "velocity": 0.5 },
|
|
||||||
{ "time": 3.5, "note": "A4", "duration": 0.02, "velocity": 0.3 }
|
|
||||||
],
|
|
||||||
"loop_length": 4.0
|
|
||||||
},
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "highpass",
|
|
||||||
"cutoff": 1000.0,
|
|
||||||
"resonance": 1.0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "lowpass",
|
|
||||||
"cutoff": 2000.0,
|
|
||||||
"resonance": 1.0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "warm_pad",
|
|
||||||
"instrument": "sine",
|
|
||||||
"volume": 0.2,
|
|
||||||
"pattern": {
|
|
||||||
"type": "chord",
|
|
||||||
"chord_progression": [
|
|
||||||
{ "time": 0.0, "chord": "Cm7", "duration": 4.0 },
|
|
||||||
{ "time": 4.0, "chord": "Fm7", "duration": 4.0 },
|
|
||||||
{ "time": 8.0, "chord": "Gm7", "duration": 4.0 },
|
|
||||||
{ "time": 12.0, "chord": "Cm7", "duration": 4.0 }
|
|
||||||
],
|
|
||||||
"voicing": "spread",
|
|
||||||
"octave": 3
|
|
||||||
},
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "lowpass",
|
|
||||||
"cutoff": 600.0,
|
|
||||||
"resonance": 1.2
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "reverb",
|
|
||||||
"room_size": 0.8,
|
|
||||||
"damping": 0.8,
|
|
||||||
"mix": 0.4
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "peaceful_melody",
|
|
||||||
"instrument": "sine",
|
|
||||||
"volume": 0.9,
|
|
||||||
"pattern": {
|
|
||||||
"type": "custom",
|
|
||||||
"steps": [
|
|
||||||
{ "time": 16.0, "note": "Eb4", "duration": 1.0, "velocity": 0.6 },
|
|
||||||
{ "time": 17.5, "note": "G4", "duration": 1.0, "velocity": 0.5 },
|
|
||||||
{ "time": 19.0, "note": "C5", "duration": 1.5, "velocity": 0.7 },
|
|
||||||
{ "time": 21.0, "note": "Bb4", "duration": 0.75, "velocity": 0.5 },
|
|
||||||
{ "time": 22.0, "note": "Ab4", "duration": 1.0, "velocity": 0.6 },
|
|
||||||
{ "time": 23.5, "note": "F4", "duration": 0.75, "velocity": 0.5 },
|
|
||||||
{ "time": 24.0, "note": "G4", "duration": 2.0, "velocity": 0.6 },
|
|
||||||
{ "time": 26.5, "note": "Bb4", "duration": 0.75, "velocity": 0.5 },
|
|
||||||
{ "time": 27.5, "note": "D5", "duration": 1.0, "velocity": 0.7 },
|
|
||||||
{ "time": 29.0, "note": "C5", "duration": 1.5, "velocity": 0.6 },
|
|
||||||
{ "time": 31.0, "note": "G4", "duration": 1.0, "velocity": 0.5 },
|
|
||||||
{ "time": 32.5, "note": "Eb4", "duration": 1.5, "velocity": 0.6 },
|
|
||||||
{ "time": 34.5, "note": "C5", "duration": 1.0, "velocity": 0.7 },
|
|
||||||
{ "time": 36.0, "note": "G4", "duration": 2.0, "velocity": 0.5 },
|
|
||||||
{ "time": 38.5, "note": "Eb4", "duration": 1.0, "velocity": 0.4 },
|
|
||||||
{ "time": 40.0, "note": "C5", "duration": 1.5, "velocity": 0.6 },
|
|
||||||
{ "time": 42.0, "note": "Bb4", "duration": 0.75, "velocity": 0.5 },
|
|
||||||
{ "time": 43.0, "note": "Ab4", "duration": 1.0, "velocity": 0.6 },
|
|
||||||
{ "time": 44.5, "note": "F4", "duration": 1.25, "velocity": 0.5 },
|
|
||||||
{ "time": 46.0, "note": "G4", "duration": 1.0, "velocity": 0.6 },
|
|
||||||
{ "time": 47.5, "note": "Bb4", "duration": 0.75, "velocity": 0.5 },
|
|
||||||
{ "time": 48.5, "note": "D5", "duration": 1.0, "velocity": 0.7 },
|
|
||||||
{ "time": 50.0, "note": "C5", "duration": 1.5, "velocity": 0.6 },
|
|
||||||
{ "time": 52.0, "note": "G4", "duration": 1.0, "velocity": 0.5 },
|
|
||||||
{ "time": 53.5, "note": "Eb4", "duration": 1.5, "velocity": 0.6 },
|
|
||||||
{ "time": 55.5, "note": "C5", "duration": 1.0, "velocity": 0.7 },
|
|
||||||
{ "time": 57.0, "note": "G4", "duration": 2.0, "velocity": 0.5 },
|
|
||||||
{ "time": 60.0, "note": "Eb4", "duration": 1.0, "velocity": 0.4 },
|
|
||||||
{ "time": 62.0, "note": "C5", "duration": 2.0, "velocity": 0.6 },
|
|
||||||
{ "time": 65.0, "note": "G4", "duration": 2.0, "velocity": 0.5 },
|
|
||||||
{ "time": 68.0, "note": "Eb4", "duration": 4.0, "velocity": 0.4 }
|
|
||||||
],
|
|
||||||
"loop_length": 72.0
|
|
||||||
},
|
|
||||||
"effects": [
|
|
||||||
{
|
|
||||||
"type": "highpass",
|
|
||||||
"cutoff": 2000.0,
|
|
||||||
"resonance": 1.1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "reverb",
|
|
||||||
"room_size": 0.9,
|
|
||||||
"damping": 0.7,
|
|
||||||
"mix": 0.5
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"export": {
|
|
||||||
"filename": "fantasy",
|
|
||||||
"format": "wav",
|
|
||||||
"stereo": true
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
//! JSON configuration module for composition specifications
|
//! TOML configuration module for composition specifications
|
||||||
//!
|
//!
|
||||||
//! This module provides structures and parsing for JSON-based composition definitions,
|
//! This module provides structures and parsing for TOML-based composition definitions,
|
||||||
//! allowing users to specify complete compositions in a declarative format.
|
//! allowing users to specify complete compositions in a declarative format.
|
||||||
|
|
||||||
use crate::core::{CompositionParams, CompositionStyle};
|
use crate::core::{CompositionParams, CompositionStyle};
|
||||||
@ -235,7 +235,7 @@ pub struct PatternConfig {
|
|||||||
|
|
||||||
/// Pattern-specific parameters
|
/// Pattern-specific parameters
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub params: serde_json::Value,
|
pub params: toml::Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Effect configuration
|
/// Effect configuration
|
||||||
@ -255,7 +255,7 @@ pub struct EffectConfig {
|
|||||||
|
|
||||||
/// Effect parameters
|
/// Effect parameters
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub params: serde_json::Value,
|
pub params: toml::Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Export settings
|
/// Export settings
|
||||||
@ -409,29 +409,28 @@ fn parse_note_name(name: &str) -> Result<u8, String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CompositionConfig {
|
impl CompositionConfig {
|
||||||
/// Load configuration from a JSON file
|
/// Load configuration from a TOML file
|
||||||
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self, String> {
|
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self, String> {
|
||||||
let content =
|
let content =
|
||||||
fs::read_to_string(path).map_err(|e| format!("Failed to read config file: {}", e))?;
|
fs::read_to_string(path).map_err(|e| format!("Failed to read config file: {}", e))?;
|
||||||
|
|
||||||
Self::from_json(&content)
|
Self::from_toml(&content)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse configuration from JSON string
|
/// Parse configuration from TOML string
|
||||||
pub fn from_json(json: &str) -> Result<Self, String> {
|
pub fn from_toml(toml_str: &str) -> Result<Self, String> {
|
||||||
serde_json::from_str(json).map_err(|e| format!("Failed to parse JSON: {}", e))
|
toml::from_str(toml_str).map_err(|e| format!("Failed to parse TOML: {}", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Save configuration to a JSON file
|
/// Save configuration to a TOML file
|
||||||
pub fn to_file<P: AsRef<Path>>(&self, path: P) -> Result<(), String> {
|
pub fn to_file<P: AsRef<Path>>(&self, path: P) -> Result<(), String> {
|
||||||
let json = self.to_json_pretty()?;
|
let toml_str = self.to_toml_pretty()?;
|
||||||
fs::write(path, json).map_err(|e| format!("Failed to write config file: {}", e))
|
fs::write(path, toml_str).map_err(|e| format!("Failed to write config file: {}", e))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serialize configuration to pretty JSON
|
/// Serialize configuration to pretty TOML
|
||||||
pub fn to_json_pretty(&self) -> Result<String, String> {
|
pub fn to_toml_pretty(&self) -> Result<String, String> {
|
||||||
serde_json::to_string_pretty(self)
|
toml::to_string_pretty(self).map_err(|e| format!("Failed to serialize to TOML: {}", e))
|
||||||
.map_err(|e| format!("Failed to serialize to JSON: {}", e))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert to composition parameters (deprecated - use track-based generation instead)
|
/// Convert to composition parameters (deprecated - use track-based generation instead)
|
||||||
@ -534,8 +533,8 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_config_serialization() {
|
fn test_config_serialization() {
|
||||||
let config = CompositionConfig::example();
|
let config = CompositionConfig::example();
|
||||||
let json = config.to_json_pretty().unwrap();
|
let toml_str = config.to_toml_pretty().unwrap();
|
||||||
let parsed = CompositionConfig::from_json(&json).unwrap();
|
let parsed = CompositionConfig::from_toml(&toml_str).unwrap();
|
||||||
|
|
||||||
assert_eq!(parsed.composition.tempo, config.composition.tempo);
|
assert_eq!(parsed.composition.tempo, config.composition.tempo);
|
||||||
}
|
}
|
||||||
|
20
src/main.rs
20
src/main.rs
@ -19,16 +19,16 @@ struct Cli {
|
|||||||
|
|
||||||
#[derive(Subcommand)]
|
#[derive(Subcommand)]
|
||||||
enum Commands {
|
enum Commands {
|
||||||
/// Generate composition from JSON configuration file
|
/// Generate composition from TOML configuration file
|
||||||
Json {
|
Toml {
|
||||||
/// Path to JSON configuration file
|
/// Path to TOML configuration file
|
||||||
config: PathBuf,
|
config: PathBuf,
|
||||||
|
|
||||||
/// Override output filename
|
/// Override output filename
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
output: Option<String>,
|
output: Option<String>,
|
||||||
|
|
||||||
/// Print example JSON configuration
|
/// Print example TOML configuration
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
example: bool,
|
example: bool,
|
||||||
},
|
},
|
||||||
@ -53,11 +53,11 @@ fn main() {
|
|||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
let result = match cli.command {
|
let result = match cli.command {
|
||||||
Commands::Json {
|
Commands::Toml {
|
||||||
config,
|
config,
|
||||||
output,
|
output,
|
||||||
example,
|
example,
|
||||||
} => handle_json_command(config, output, example),
|
} => handle_toml_command(config, output, example),
|
||||||
|
|
||||||
Commands::Info {
|
Commands::Info {
|
||||||
scales,
|
scales,
|
||||||
@ -126,16 +126,16 @@ fn show_info(scales: bool, instruments: bool, all: bool) -> Result<(), Box<dyn s
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_json_command(
|
fn handle_toml_command(
|
||||||
config_path: PathBuf,
|
config_path: PathBuf,
|
||||||
output_override: Option<String>,
|
output_override: Option<String>,
|
||||||
show_example: bool,
|
show_example: bool,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if show_example {
|
if show_example {
|
||||||
let example = CompositionConfig::example();
|
let example = CompositionConfig::example();
|
||||||
println!("{}", example.to_json_pretty()?);
|
println!("{}", example.to_toml_pretty()?);
|
||||||
println!("\n# Save this to a .json file and run:");
|
println!("\n# Save this to a .toml file and run:");
|
||||||
println!("# cargo run --bin musicgen json your_config.json");
|
println!("# cargo run --bin musicgen toml your_config.toml");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,12 +87,12 @@ impl TrackState {
|
|||||||
let cutoff = effect_config
|
let cutoff = effect_config
|
||||||
.params
|
.params
|
||||||
.get("cutoff")
|
.get("cutoff")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(1000.0) as f32;
|
.unwrap_or(1000.0) as f32;
|
||||||
let resonance = effect_config
|
let resonance = effect_config
|
||||||
.params
|
.params
|
||||||
.get("resonance")
|
.get("resonance")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(1.0) as f32;
|
.unwrap_or(1.0) as f32;
|
||||||
Box::new(LowPassFilter::new(cutoff, resonance))
|
Box::new(LowPassFilter::new(cutoff, resonance))
|
||||||
}
|
}
|
||||||
@ -100,12 +100,12 @@ impl TrackState {
|
|||||||
let cutoff = effect_config
|
let cutoff = effect_config
|
||||||
.params
|
.params
|
||||||
.get("cutoff")
|
.get("cutoff")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(1000.0) as f32;
|
.unwrap_or(1000.0) as f32;
|
||||||
let resonance = effect_config
|
let resonance = effect_config
|
||||||
.params
|
.params
|
||||||
.get("resonance")
|
.get("resonance")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(1.0) as f32;
|
.unwrap_or(1.0) as f32;
|
||||||
Box::new(HighPassFilter::new(cutoff, resonance))
|
Box::new(HighPassFilter::new(cutoff, resonance))
|
||||||
}
|
}
|
||||||
@ -113,17 +113,17 @@ impl TrackState {
|
|||||||
let time = effect_config
|
let time = effect_config
|
||||||
.params
|
.params
|
||||||
.get("time")
|
.get("time")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(0.3) as f32;
|
.unwrap_or(0.3) as f32;
|
||||||
let feedback = effect_config
|
let feedback = effect_config
|
||||||
.params
|
.params
|
||||||
.get("feedback")
|
.get("feedback")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(0.3) as f32;
|
.unwrap_or(0.3) as f32;
|
||||||
let mix = effect_config
|
let mix = effect_config
|
||||||
.params
|
.params
|
||||||
.get("mix")
|
.get("mix")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(0.3) as f32;
|
.unwrap_or(0.3) as f32;
|
||||||
Box::new(Delay::new(time, feedback, mix))
|
Box::new(Delay::new(time, feedback, mix))
|
||||||
}
|
}
|
||||||
@ -131,17 +131,17 @@ impl TrackState {
|
|||||||
let room_size = effect_config
|
let room_size = effect_config
|
||||||
.params
|
.params
|
||||||
.get("room_size")
|
.get("room_size")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(0.5) as f32;
|
.unwrap_or(0.5) as f32;
|
||||||
let damping = effect_config
|
let damping = effect_config
|
||||||
.params
|
.params
|
||||||
.get("damping")
|
.get("damping")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(0.5) as f32;
|
.unwrap_or(0.5) as f32;
|
||||||
let mix = effect_config
|
let mix = effect_config
|
||||||
.params
|
.params
|
||||||
.get("mix")
|
.get("mix")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(0.3) as f32;
|
.unwrap_or(0.3) as f32;
|
||||||
Box::new(Reverb::new(room_size, damping, mix))
|
Box::new(Reverb::new(room_size, damping, mix))
|
||||||
}
|
}
|
||||||
@ -149,12 +149,12 @@ impl TrackState {
|
|||||||
let drive = effect_config
|
let drive = effect_config
|
||||||
.params
|
.params
|
||||||
.get("drive")
|
.get("drive")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(2.0) as f32;
|
.unwrap_or(2.0) as f32;
|
||||||
let tone = effect_config
|
let tone = effect_config
|
||||||
.params
|
.params
|
||||||
.get("tone")
|
.get("tone")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(0.5) as f32;
|
.unwrap_or(0.5) as f32;
|
||||||
Box::new(Distortion::new(drive, tone))
|
Box::new(Distortion::new(drive, tone))
|
||||||
}
|
}
|
||||||
@ -162,22 +162,22 @@ impl TrackState {
|
|||||||
let rate = effect_config
|
let rate = effect_config
|
||||||
.params
|
.params
|
||||||
.get("rate")
|
.get("rate")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(1.0) as f32;
|
.unwrap_or(1.0) as f32;
|
||||||
let depth = effect_config
|
let depth = effect_config
|
||||||
.params
|
.params
|
||||||
.get("depth")
|
.get("depth")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(0.5) as f32;
|
.unwrap_or(0.5) as f32;
|
||||||
let mix = effect_config
|
let mix = effect_config
|
||||||
.params
|
.params
|
||||||
.get("mix")
|
.get("mix")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(0.3) as f32;
|
.unwrap_or(0.3) as f32;
|
||||||
let layers = effect_config
|
let layers = effect_config
|
||||||
.params
|
.params
|
||||||
.get("layers")
|
.get("layers")
|
||||||
.and_then(|v| v.as_u64())
|
.and_then(|v| v.as_integer())
|
||||||
.unwrap_or(3) as usize;
|
.unwrap_or(3) as usize;
|
||||||
Box::new(Chorus::new(rate, depth, mix, layers))
|
Box::new(Chorus::new(rate, depth, mix, layers))
|
||||||
}
|
}
|
||||||
@ -185,17 +185,17 @@ impl TrackState {
|
|||||||
let intensity = effect_config
|
let intensity = effect_config
|
||||||
.params
|
.params
|
||||||
.get("intensity")
|
.get("intensity")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(0.5) as f32;
|
.unwrap_or(0.5) as f32;
|
||||||
let frequency = effect_config
|
let frequency = effect_config
|
||||||
.params
|
.params
|
||||||
.get("frequency")
|
.get("frequency")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(0.5) as f32;
|
.unwrap_or(0.5) as f32;
|
||||||
let mix = effect_config
|
let mix = effect_config
|
||||||
.params
|
.params
|
||||||
.get("mix")
|
.get("mix")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(0.3) as f32;
|
.unwrap_or(0.3) as f32;
|
||||||
Box::new(VinylCrackle::new(intensity, frequency, mix))
|
Box::new(VinylCrackle::new(intensity, frequency, mix))
|
||||||
}
|
}
|
||||||
@ -203,17 +203,17 @@ impl TrackState {
|
|||||||
let drive = effect_config
|
let drive = effect_config
|
||||||
.params
|
.params
|
||||||
.get("drive")
|
.get("drive")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(2.0) as f32;
|
.unwrap_or(2.0) as f32;
|
||||||
let warmth = effect_config
|
let warmth = effect_config
|
||||||
.params
|
.params
|
||||||
.get("warmth")
|
.get("warmth")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(0.7) as f32;
|
.unwrap_or(0.7) as f32;
|
||||||
let mix = effect_config
|
let mix = effect_config
|
||||||
.params
|
.params
|
||||||
.get("mix")
|
.get("mix")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(0.5) as f32;
|
.unwrap_or(0.5) as f32;
|
||||||
Box::new(TapeSaturation::new(drive, warmth, mix))
|
Box::new(TapeSaturation::new(drive, warmth, mix))
|
||||||
}
|
}
|
||||||
@ -221,17 +221,17 @@ impl TrackState {
|
|||||||
let bit_depth = effect_config
|
let bit_depth = effect_config
|
||||||
.params
|
.params
|
||||||
.get("bit_depth")
|
.get("bit_depth")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(8.0) as f32;
|
.unwrap_or(8.0) as f32;
|
||||||
let sample_rate_reduction = effect_config
|
let sample_rate_reduction = effect_config
|
||||||
.params
|
.params
|
||||||
.get("sample_rate_reduction")
|
.get("sample_rate_reduction")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(2.0) as f32;
|
.unwrap_or(2.0) as f32;
|
||||||
let mix = effect_config
|
let mix = effect_config
|
||||||
.params
|
.params
|
||||||
.get("mix")
|
.get("mix")
|
||||||
.and_then(|v| v.as_f64())
|
.and_then(|v| v.as_float())
|
||||||
.unwrap_or(0.5) as f32;
|
.unwrap_or(0.5) as f32;
|
||||||
Box::new(BitCrusher::new(bit_depth, sample_rate_reduction, mix))
|
Box::new(BitCrusher::new(bit_depth, sample_rate_reduction, mix))
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user