.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/cli/plot_analyze_command.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_cli_plot_analyze_command.py: Using the Analyze Command ========================== This example demonstrates how to use the ``mixref analyze`` command to analyze audio files and compare them against platform and genre targets. The analyze command provides loudness measurements (LUFS, true peak, LRA) and compares your track against streaming platform targets or genre-specific targets. .. GENERATED FROM PYTHON SOURCE LINES 11-21 .. code-block:: Python import tempfile from pathlib import Path import numpy as np import soundfile as sf from mixref.audio import load_audio from mixref.meters import calculate_lufs, compare_to_target, get_target, Genre, Platform .. GENERATED FROM PYTHON SOURCE LINES 22-27 Create Example Audio Files --------------------------- First, let's create three different audio files to demonstrate the analyze command with different loudness levels. .. GENERATED FROM PYTHON SOURCE LINES 27-55 .. code-block:: Python sample_rate = 44100 duration = 3.0 samples = int(sample_rate * duration) # Set random seed for reproducibility np.random.seed(42) # Create temporary directory for files temp_dir = Path(tempfile.mkdtemp()) # 1. Quiet track (good for streaming) quiet_audio = np.random.randn(samples, 2) * 0.01 quiet_file = temp_dir / "streaming_master.wav" sf.write(quiet_file, quiet_audio, sample_rate) # 2. Club-ready track (louder) club_audio = np.random.randn(samples, 2) * 0.3 club_file = temp_dir / "club_master.wav" sf.write(club_file, club_audio, sample_rate) # 3. Over-loud track (potential clipping) loud_audio = np.random.randn(samples, 2) * 0.8 loud_file = temp_dir / "too_loud.wav" sf.write(loud_file, loud_audio, sample_rate) print(f"Created test files in: {temp_dir}") .. rst-class:: sphx-glr-script-out .. code-block:: none Created test files in: /tmp/tmpt19my6vl .. GENERATED FROM PYTHON SOURCE LINES 56-67 Analyze Basic: Get Loudness Metrics ------------------------------------ The simplest use case is analyzing a file without specifying targets. This shows the raw loudness measurements. Command line equivalent: .. code-block:: bash mixref analyze streaming_master.wav .. GENERATED FROM PYTHON SOURCE LINES 67-78 .. code-block:: Python audio, sr = load_audio(quiet_file) result = calculate_lufs(audio.T if audio.ndim == 2 else audio, sr) print(f"\n=== Analysis: {quiet_file.name} ===") print(f"Integrated LUFS: {result.integrated_lufs:>6.1f} LUFS") print(f"True Peak: {result.true_peak_db:>6.1f} dBTP") print(f"Loudness Range: {result.loudness_range_lu:>6.1f} LU") print(f"Short-term Max: {result.short_term_max_lufs:>6.1f} LUFS") print(f"Short-term Min: {result.short_term_min_lufs:>6.1f} LUFS") .. rst-class:: sphx-glr-script-out .. code-block:: none === Analysis: streaming_master.wav === Integrated LUFS: -33.9 LUFS True Peak: -26.8 dBTP Loudness Range: 0.0 LU Short-term Max: -30.9 LUFS Short-term Min: -36.9 LUFS .. GENERATED FROM PYTHON SOURCE LINES 79-91 Compare Against Streaming Platforms ------------------------------------ Compare your track against platform targets like Spotify, YouTube, or Apple Music. Command line equivalent: .. code-block:: bash mixref analyze streaming_master.wav --platform spotify mixref analyze streaming_master.wav --platform youtube mixref analyze streaming_master.wav -p tidal # short form .. GENERATED FROM PYTHON SOURCE LINES 91-105 .. code-block:: Python platforms = [Platform.SPOTIFY, Platform.YOUTUBE, Platform.APPLE_MUSIC] print(f"\n=== Platform Comparison: {quiet_file.name} ===") for platform in platforms: target = get_target(platform=platform) is_ok, diff, message = compare_to_target(result.integrated_lufs, target) status = "✅" if is_ok else "⚠️" print(f"\n{platform.value.upper():12} {status}") print(f" Target: {target.target_lufs} LUFS") print(f" Diff: {diff:+.1f} dB") print(f" {message}") .. rst-class:: sphx-glr-script-out .. code-block:: none === Platform Comparison: streaming_master.wav === SPOTIFY ✅ Target: -14.0 LUFS Diff: -19.9 dB 19.9 dB below Spotify target (-14.0 LUFS). Still acceptable. YOUTUBE ✅ Target: -14.0 LUFS Diff: -19.9 dB 19.9 dB below YouTube target (-14.0 LUFS). Still acceptable. APPLE_MUSIC ✅ Target: -16.0 LUFS Diff: -17.9 dB 17.9 dB below Apple Music target (-16.0 LUFS). Still acceptable. .. GENERATED FROM PYTHON SOURCE LINES 106-118 Compare Against Genre Targets ------------------------------ Compare against genre-specific targets for club/DJ playback. Command line equivalent: .. code-block:: bash mixref analyze club_master.wav --genre dnb mixref analyze club_master.wav --genre techno mixref analyze club_master.wav -g house # short form .. GENERATED FROM PYTHON SOURCE LINES 118-137 .. code-block:: Python # Analyze the club-ready track audio_club, sr = load_audio(club_file) result_club = calculate_lufs(audio_club.T if audio_club.ndim == 2 else audio_club, sr) genres = [Genre.DNB, Genre.TECHNO, Genre.HOUSE] print(f"\n=== Genre Comparison: {club_file.name} ===") print(f"Measured LUFS: {result_club.integrated_lufs:.1f}") for genre in genres: target = get_target(genre=genre) is_ok, diff, message = compare_to_target(result_club.integrated_lufs, target) status = "✅" if is_ok else "⚠️" print(f"\n{genre.value.upper():8} {status}") print(f" Target: {target.target_lufs} LUFS") print(f" Diff: {diff:+.1f} dB") .. rst-class:: sphx-glr-script-out .. code-block:: none === Genre Comparison: club_master.wav === Measured LUFS: -4.4 DNB ⚠️ Target: -8.0 LUFS Diff: +3.6 dB TECHNO ⚠️ Target: -9.0 LUFS Diff: +4.6 dB HOUSE ⚠️ Target: -10.0 LUFS Diff: +5.6 dB .. GENERATED FROM PYTHON SOURCE LINES 138-143 Detect Potential Issues ----------------------- The analyze command warns you about potential problems like clipping or excessive loudness. .. GENERATED FROM PYTHON SOURCE LINES 143-165 .. code-block:: Python # Analyze the over-loud track audio_loud, sr = load_audio(loud_file) result_loud = calculate_lufs(audio_loud.T if audio_loud.ndim == 2 else audio_loud, sr) print(f"\n=== Problem Detection: {loud_file.name} ===") print(f"Integrated LUFS: {result_loud.integrated_lufs:.1f}") print(f"True Peak: {result_loud.true_peak_db:.1f} dBTP") # Check for clipping danger if result_loud.true_peak_db > -1.0: print("\n⚠️ WARNING: True peak above -1.0 dBTP!") print(" Risk of clipping when converted to lossy formats.") print(" Recommendation: Reduce gain by at least " f"{abs(-1.0 - result_loud.true_peak_db):.1f} dB") # Check against streaming targets spotify_target = get_target(platform=Platform.SPOTIFY) is_ok, diff, message = compare_to_target(result_loud.integrated_lufs, spotify_target) print(f"\n{message}") .. rst-class:: sphx-glr-script-out .. code-block:: none === Problem Detection: too_loud.wav === Integrated LUFS: 2.4 True Peak: 0.0 dBTP ⚠️ WARNING: True peak above -1.0 dBTP! Risk of clipping when converted to lossy formats. Recommendation: Reduce gain by at least 1.0 dB ⚠️ 16.4 dB above Spotify target (-14.0 LUFS). May be turned down or distorted. .. GENERATED FROM PYTHON SOURCE LINES 166-176 JSON Output for Automation --------------------------- Get machine-readable output for scripts and automation. Command line equivalent: .. code-block:: bash mixref analyze my_track.wav --platform spotify --json | jq . .. GENERATED FROM PYTHON SOURCE LINES 176-205 .. code-block:: Python import json # Build JSON output structure (matches CLI --json output) output = { "file": str(quiet_file), "loudness": { "integrated_lufs": round(result.integrated_lufs, 2), "true_peak_db": round(result.true_peak_db, 2), "loudness_range_lu": round(result.loudness_range_lu, 2), "short_term_max_lufs": round(result.short_term_max_lufs, 2), "short_term_min_lufs": round(result.short_term_min_lufs, 2), }, } # Add platform comparison spotify_target = get_target(platform=Platform.SPOTIFY) is_ok, diff, message = compare_to_target(result.integrated_lufs, spotify_target) output["platform"] = { "name": "spotify", "target_lufs": spotify_target.target_lufs, "difference": round(diff, 2), "is_acceptable": is_ok, "message": message, } print("\n=== JSON Output ===") print(json.dumps(output, indent=2)) .. rst-class:: sphx-glr-script-out .. code-block:: none === JSON Output === { "file": "/tmp/tmpt19my6vl/streaming_master.wav", "loudness": { "integrated_lufs": -33.92, "true_peak_db": -26.82, "loudness_range_lu": 0.0, "short_term_max_lufs": -30.92, "short_term_min_lufs": -36.92 }, "platform": { "name": "spotify", "target_lufs": -14.0, "difference": -19.92, "is_acceptable": true, "message": "19.9 dB below Spotify target (-14.0 LUFS). Still acceptable." } } .. GENERATED FROM PYTHON SOURCE LINES 206-210 Workflow Example: Pre-Release Check ------------------------------------ Typical producer workflow: check if track meets targets before release. .. GENERATED FROM PYTHON SOURCE LINES 210-263 .. code-block:: Python def check_release_ready(file_path: Path) -> dict: """Check if track is ready for release. Args: file_path: Path to audio file Returns: Dictionary with pass/fail status and recommendations """ audio, sr = load_audio(file_path) result = calculate_lufs(audio.T if audio.ndim == 2 else audio, sr) checks = { "file": file_path.name, "lufs": result.integrated_lufs, "peak": result.true_peak_db, "issues": [], "ready": True, } # Check 1: No clipping if result.true_peak_db > -1.0: checks["issues"].append(f"⚠️ True peak too high ({result.true_peak_db:.1f} dBTP)") checks["ready"] = False # Check 2: Spotify target spotify = get_target(platform=Platform.SPOTIFY) is_ok, diff, msg = compare_to_target(result.integrated_lufs, spotify) if abs(diff) > 2.0: checks["issues"].append(f"⚠️ {diff:+.1f} dB from Spotify target") # Check 3: Dynamic range if result.loudness_range_lu < 3.0: checks["issues"].append("⚠️ Very low dynamic range (over-compressed)") return checks # Check all three files print("\n=== Pre-Release Checks ===") for file_path in [quiet_file, club_file, loud_file]: status = check_release_ready(file_path) print(f"\n{status['file']}") print(f" LUFS: {status['lufs']:.1f}") print(f" Peak: {status['peak']:.1f} dBTP") print(f" Ready: {'✅ YES' if status['ready'] else '❌ NO'}") if status['issues']: print(" Issues:") for issue in status['issues']: print(f" {issue}") .. rst-class:: sphx-glr-script-out .. code-block:: none === Pre-Release Checks === streaming_master.wav LUFS: -33.9 Peak: -26.8 dBTP Ready: ✅ YES Issues: ⚠️ -19.9 dB from Spotify target ⚠️ Very low dynamic range (over-compressed) club_master.wav LUFS: -4.4 Peak: 0.0 dBTP Ready: ❌ NO Issues: ⚠️ True peak too high (0.0 dBTP) ⚠️ +9.6 dB from Spotify target ⚠️ Very low dynamic range (over-compressed) too_loud.wav LUFS: 2.4 Peak: 0.0 dBTP Ready: ❌ NO Issues: ⚠️ True peak too high (0.0 dBTP) ⚠️ +16.4 dB from Spotify target ⚠️ Very low dynamic range (over-compressed) .. GENERATED FROM PYTHON SOURCE LINES 264-275 Key Takeaways ------------- 1. **Basic analysis**: ``mixref analyze file.wav`` shows loudness metrics 2. **Platform targets**: Add ``--platform spotify`` to compare against streaming 3. **Genre targets**: Add ``--genre dnb`` for club/DJ playback 4. **JSON output**: Add ``--json`` for machine-readable results 5. **Automation**: Combine with scripts for batch processing The analyze command integrates audio loading, LUFS calculation, and target comparison into a single, producer-friendly tool. .. GENERATED FROM PYTHON SOURCE LINES 275-280 .. code-block:: Python # Clean up temporary files import shutil shutil.rmtree(temp_dir) print("\n✅ Example complete!") .. rst-class:: sphx-glr-script-out .. code-block:: none ✅ Example complete! .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.083 seconds) .. _sphx_glr_download_auto_examples_cli_plot_analyze_command.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_analyze_command.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_analyze_command.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_analyze_command.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_