avans06 commited on
Commit
1db4ef0
·
1 Parent(s): 69f25b5

feat(output): Add parameter metadata to final audio files

Browse files

Saves 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.

Files changed (2) hide show
  1. app.py +32 -2
  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
- sf.write(final_audio_path, final_audio_data, final_srate)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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