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
|