feat(output): Add parameter metadata to final audio files
Browse filesSaves the complete set of `AppParameters` used for each render into the metadata of the output FLAC file.
This makes each render self-documenting and allows users to easily track the settings used for any given result. The parameters are stored as a JSON string in the file's `comment` tag.
- app.py +32 -2
- requirements.txt +1 -0
app.py
CHANGED
|
@@ -49,6 +49,7 @@ import shutil
|
|
| 49 |
import librosa
|
| 50 |
import pyloudnorm as pyln
|
| 51 |
import soundfile as sf
|
|
|
|
| 52 |
|
| 53 |
import torch
|
| 54 |
import ffmpeg
|
|
@@ -198,6 +199,19 @@ class AppParameters:
|
|
| 198 |
# === Helper Functions ===
|
| 199 |
# =================================================================================================
|
| 200 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
def preprocess_midi_for_harshness(midi_data: pretty_midi.PrettyMIDI, params: AppParameters):
|
| 202 |
"""
|
| 203 |
Analyzes and modifies a PrettyMIDI object in-place to reduce characteristics
|
|
@@ -2173,8 +2187,24 @@ def run_single_file_pipeline(input_file_path: str, timestamp: str, params: AppPa
|
|
| 2173 |
# Also, copy the final processed MIDI to a consistent output directory with a timestamped name
|
| 2174 |
final_midi_path = os.path.join(output_midi_dir, f"{timestamped_base_name}_processed.mid")
|
| 2175 |
|
| 2176 |
-
|
| 2177 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2178 |
# Use shutil to copy the final midi file to its new home
|
| 2179 |
shutil.copy(final_midi_path_from_render, final_midi_path)
|
| 2180 |
|
|
|
|
| 49 |
import librosa
|
| 50 |
import pyloudnorm as pyln
|
| 51 |
import soundfile as sf
|
| 52 |
+
from mutagen.flac import FLAC
|
| 53 |
|
| 54 |
import torch
|
| 55 |
import ffmpeg
|
|
|
|
| 199 |
# === Helper Functions ===
|
| 200 |
# =================================================================================================
|
| 201 |
|
| 202 |
+
def format_params_for_metadata(params: AppParameters) -> str:
|
| 203 |
+
"""
|
| 204 |
+
Formats the AppParameters object into a human-readable string
|
| 205 |
+
suitable for embedding as metadata in an audio file.
|
| 206 |
+
"""
|
| 207 |
+
import json
|
| 208 |
+
# Convert the dataclass to a dictionary
|
| 209 |
+
params_dict = params.__dict__
|
| 210 |
+
# Use json.dumps for clean, well-formatted, multi-line string representation
|
| 211 |
+
# indent=2 makes it look nice when read back
|
| 212 |
+
return json.dumps(params_dict, indent=2)
|
| 213 |
+
|
| 214 |
+
|
| 215 |
def preprocess_midi_for_harshness(midi_data: pretty_midi.PrettyMIDI, params: AppParameters):
|
| 216 |
"""
|
| 217 |
Analyzes and modifies a PrettyMIDI object in-place to reduce characteristics
|
|
|
|
| 2187 |
# Also, copy the final processed MIDI to a consistent output directory with a timestamped name
|
| 2188 |
final_midi_path = os.path.join(output_midi_dir, f"{timestamped_base_name}_processed.mid")
|
| 2189 |
|
| 2190 |
+
# --- Save audio with embedded parameter metadata ---
|
| 2191 |
+
try:
|
| 2192 |
+
# Generate the metadata string from the final parameters used for the render.
|
| 2193 |
+
metadata_string = format_params_for_metadata(params)
|
| 2194 |
+
|
| 2195 |
+
sf.write(final_audio_path, final_audio_data, final_srate)
|
| 2196 |
+
audio = FLAC(final_audio_path)
|
| 2197 |
+
audio["comment"] = metadata_string
|
| 2198 |
+
audio.save()
|
| 2199 |
+
|
| 2200 |
+
print(f" - Successfully saved audio with embedded parameters to {os.path.basename(final_audio_path)}")
|
| 2201 |
+
|
| 2202 |
+
except Exception as e:
|
| 2203 |
+
print(f" - Warning: Could not save audio with metadata. Error: {e}")
|
| 2204 |
+
print(" - Falling back to standard save method.")
|
| 2205 |
+
# Fallback to the original simple write method if the advanced one fails.
|
| 2206 |
+
sf.write(final_audio_path, final_audio_data, final_srate)
|
| 2207 |
+
|
| 2208 |
# Use shutil to copy the final midi file to its new home
|
| 2209 |
shutil.copy(final_midi_path_from_render, final_midi_path)
|
| 2210 |
|
requirements.txt
CHANGED
|
@@ -17,6 +17,7 @@ networkx
|
|
| 17 |
scikit-learn
|
| 18 |
psutil
|
| 19 |
pretty_midi
|
|
|
|
| 20 |
soundfile
|
| 21 |
pyloudnorm
|
| 22 |
ffmpeg-python
|
|
|
|
| 17 |
scikit-learn
|
| 18 |
psutil
|
| 19 |
pretty_midi
|
| 20 |
+
mutagen
|
| 21 |
soundfile
|
| 22 |
pyloudnorm
|
| 23 |
ffmpeg-python
|