[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6KF9DA0P51RNAGJC014XBKN":3,"skill-same:01M6KF9DA0P51RNAGJC014XBKN":66},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":33,"linkOnly":34,"markdownContent":35,"markdownBody":36,"frontMatter":37,"refName":38,"commitSha":39,"skillDirectory":40,"forksCount":14,"repositoryHtmlUrl":41,"repositoryHomepageUrl":6,"ownerHtmlUrl":42,"ownerBlogUrl":43,"ownerDescription":44,"updatedAt":45,"install":46,"resources":59},"01M6KF9DA0P51RNAGJC014XBKN","adaptive-stem-alignment",null,"Incremental audio production with duration mismatch handling, adaptive stem extension, and pre-mix alignment verification","xyliu-cs\u002FOpenSpace-GDPval","xyliu-cs","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F89236536?v=4","01M6KF8Z1V4TXS86CKSH48BY8T","xy","01M6KF8Z67443W0SHXM85JEF0B",0,"MIT","https:\u002F\u002Fgithub.com\u002Fxyliu-cs\u002FOpenSpace-GDPval\u002Fblob\u002Fmain\u002Fgdpval_bench\u002Fskills\u002Faudio-track-production-enhanced-enhanced-b8f537\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32],"alignment","adaptive stem alignment","adaptive","verification","Production","Audio","extension","with","mix","2026-11-10 10:12:30",false,"---\nname: adaptive-stem-alignment\ndescription: Incremental audio production with duration mismatch handling, adaptive stem extension, and pre-mix alignment verification\n---\n\n# Adaptive Stem Alignment Workflow\n\nThis skill provides a resilient pattern for audio production that emphasizes **incremental verification**, **fail-fast** principles, and **adaptive duration handling**. Each major step produces verified outputs before proceeding, with explicit strategies for handling stems of different durations.\n\n## Overview\n\nFollow these steps in strict order. Each step must complete successfully and pass verification before proceeding to the next:\n\n1. **Early timing calculation** - Derive section transitions from BPM and duration first\n2. **Verify reference audio** - Validate input file properties and establish target duration\n3. **Generate and verify each stem individually** - One stem at a time with immediate verification\n4. **Generate drum stem separately** - Dedicated drum extension with rhythm patterns\n5. **Align stem durations** - Handle duration mismatches with adaptive extension strategies\n6. **Apply effects with verification** - Process each stem and verify output\n7. **Export master track** - Mix all verified stems\n8. **Archive and final verification** - Package deliverables with comprehensive checks\n\n## Key Differences from Standard Workflow\n\n- **Incremental verification**: Verify each stem immediately after generation, not just at the end\n- **Fail-fast approach**: Stop and report errors at each step rather than accumulating failures\n- **Early timing**: Calculate section transitions before any audio generation\n- **Separated drums**: Drum stem generation is a distinct step with rhythm-specific processing\n- **Memory-efficient**: Process stems individually to avoid large array operations that cause sandbox failures\n- **Adaptive duration handling**: Explicit strategies for mismatched stem durations (zero-padding, looping, crossfade extension)\n- **Pre-mix alignment**: Verify all stems match target duration before mixing\n\n## Step 1: Calculate Timing Parameters (Early)\n\nCalculate all timing parameters **before** generating any audio. This ensures consistent timing across all stems:\n\n```python\ndef calculate_section_transitions(bpm, total_duration_sec, sections):\n    \"\"\"Calculate beat-aligned transition points for song sections.\"\"\"\n    beats_per_second = bpm \u002F 60.0\n    \n    section_durations = {}\n    cumulative_time = 0\n    \n    for section_name, beat_count in sections.items():\n        duration = beat_count \u002F beats_per_second\n        section_durations[section_name] = {\n            'start': cumulative_time,\n            'end': cumulative_time + duration,\n            'beats': beat_count,\n            'start_beat': cumulative_time * beats_per_second\n        }\n        cumulative_time += duration\n    \n    return section_durations\n\n# Configuration\nBPM = 120\nDURATION = 137\nSECTIONS = {'intro': 16, 'verse': 32, 'chorus': 32, 'bridge': 16, 'outro': 16}\n\ntiming = calculate_section_transitions(BPM, DURATION, SECTIONS)\nprint(\"Timing calculated:\")\nfor section, data in timing.items():\n    print(f\"  {section}: {data['start']:.2f}s - {data['end']:.2f}s ({data['beats']} beats)\")\n```\n\n## Step 2: Verify Reference Audio\n\nValidate the reference file exists and has expected properties:\n\n```python\nimport soundfile as sf\nimport os\n\ndef verify_reference_file(filepath, expected_sample_rate=None, min_duration=None):\n    \"\"\"Verify reference audio file and return info dict.\"\"\"\n    if not os.path.exists(filepath):\n        raise FileNotFoundError(f\"Reference file not found: {filepath}\")\n    \n    info = sf.info(filepath)\n    errors = []\n    \n    if expected_sample_rate and info.samplerate != expected_sample_rate:\n        errors.append(f\"Sample rate mismatch: expected {expected_sample_rate}, got {info.samplerate}\")\n    \n    if min_duration and info.duration \u003C min_duration:\n        errors.append(f\"Duration too short: expected >= {min_duration}s, got {info.duration}s\")\n    \n    if errors:\n        raise ValueError(f\"Reference file validation failed: {'; '.join(errors)}\")\n    \n    print(f\"Reference verified: {info.duration:.2f}s @ {info.samplerate}Hz, {info.channels}ch, {info.subtype}\")\n    return {\n        'sample_rate': info.samplerate,\n        'duration': info.duration,\n        'channels': info.channels,\n        'subtype': info.subtype\n    }\n\n# Verify reference\nref_info = verify_reference_file('reference.wav', expected_sample_rate=48000, min_duration=130)\nTARGET_DURATION = ref_info['duration']  # Use reference duration as target\n```\n\n## Step 3: Generate and Verify Each Stem Individually\n\nGenerate one stem at a time, verify it immediately before proceeding to the next:\n\n```python\nimport numpy as np\n\ndef generate_stem(name, duration_sec, sample_rate, subtype='FLOAT', section_timing=None):\n    \"\"\"Generate a single stem with explicit sample type.\"\"\"\n    frames = int(duration_sec * sample_rate)\n    t = np.linspace(0, duration_sec, frames)\n    \n    # Generate stem-specific content (customize per stem type)\n    if name == 'bass':\n        freq = 110  # A2\n        audio_data = np.sin(2 * np.pi * freq * t) * 0.8\n    elif name == 'guitars':\n        freq = 440  # A4\n        audio_data = np.sin(2 * np.pi * freq * t) * 0.6\n    elif name == 'synths':\n        freq = 880  # A5\n        audio_data = np.sin(2 * np.pi * freq * t) * 0.5\n    elif name == 'bridge':\n        freq = 220  # A3\n        audio_data = np.sin(2 * np.pi * freq * t) * 0.7\n    else:\n        audio_data = np.sin(2 * np.pi * 440 * t) * 0.5\n    \n    # Ensure proper data type\n    if subtype == 'FLOAT':\n        audio_data = audio_data.astype(np.float32)\n    elif subtype == 'PCM_24':\n        audio_data = np.clip(audio_data, -1, 1) * (2**23 - 1)\n        audio_data = audio_data.astype(np.int32)\n    \n    filepath = f'{name}_stem.wav'\n    sf.write(filepath, audio_data, sample_rate, subtype=subtype, format='WAV')\n    \n    return filepath, audio_data\n\ndef verify_stem(filepath, expected_sample_rate, expected_subtype, expected_duration):\n    \"\"\"Verify a single stem meets specifications.\"\"\"\n    if not os.path.exists(filepath):\n        return {'success': False, 'error': f'File not found: {filepath}'}\n    \n    info = sf.info(filepath)\n    errors = []\n    \n    if info.samplerate != expected_sample_rate:\n        errors.append(f'sample_rate: expected {expected_sample_rate}, got {info.samplerate}')\n    \n    if info.subtype != expected_subtype:\n        errors.append(f'subtype: expected {expected_subtype}, got {info.subtype}')\n    \n    if abs(info.duration - expected_duration) > 1.0:  # Allow 1s tolerance\n        errors.append(f'duration: expected ~{expected_duration}s, got {info.duration}s')\n    \n    if errors:\n        return {'success': False, 'error': '; '.join(errors)}\n    \n    return {'success': True, 'info': info}\n\n# Generate stems one at a time with verification\nSAMPLE_RATE = 48000\nSUBTYPE = 'FLOAT'\nSTEM_NAMES = ['bass', 'guitars', 'synths', 'bridge']\n\ngenerated_stems = []\nstem_durations = {}  # Track actual durations for alignment step\n\nfor stem_name in STEM_NAMES:\n    print(f\"\\n=== Generating {stem_name} stem ===\")\n    \n    # Generate\n    filepath, data = generate_stem(stem_name, DURATION, SAMPLE_RATE, subtype=SUBTYPE)\n    \n    # Verify immediately\n    result = verify_stem(filepath, SAMPLE_RATE, SUBTYPE, DURATION)\n    \n    if result['success']:\n        print(f\"✓ {stem_name} stem verified: {result['info'].duration:.2f}s @ {result['info'].samplerate}Hz\")\n        generated_stems.append(filepath)\n        stem_durations[stem_name] = result['info'].duration\n    else:\n        print(f\"✗ {stem_name} stem FAILED: {result['error']}\")\n        raise RuntimeError(f\"Stem generation failed for {stem_name}: {result['error']}\")\n\nprint(f\"\\nAll {len(generated_stems)} stems generated and verified successfully\")\n```\n\n## Step 4: Generate Drum Stem Separately\n\nDrums require different processing (rhythm patterns, percussion sounds):\n\n```python\ndef generate_drum_stem(duration_sec, sample_rate, bpm, section_timing, subtype='FLOAT'):\n    \"\"\"Generate drum stem with rhythm patterns aligned to sections.\"\"\"\n    frames = int(duration_sec * sample_rate)\n    audio_data = np.zeros(frames, dtype=np.float32)\n    beats_per_second = bpm \u002F 60.0\n    \n    # Simple kick drum pattern (every beat)\n    kick_freq = 60\n    kick_duration = 0.1\n    kick_frames = int(kick_duration * sample_rate)\n    \n    for beat_time in np.arange(0, duration_sec, 1.0 \u002F beats_per_second):\n        start_frame = int(beat_time * sample_rate)\n        end_frame = min(start_frame + kick_frames, frames)\n        \n        if start_frame \u003C frames:\n            t = np.linspace(0, kick_duration, end_frame - start_frame)\n            kick = np.exp(-5 * t) * np.sin(2 * np.pi * kick_freq * t)\n            audio_data[start_frame:end_frame] += kick * 0.9\n    \n    # Simple snare pattern (every 2nd and 4th beat)\n    snare_freq = 200\n    snare_duration = 0.05\n    snare_frames = int(snare_duration * sample_rate)\n    \n    for beat_time in np.arange(0, duration_sec, 2.0 \u002F beats_per_second):\n        start_frame = int((beat_time + 0.5 \u002F beats_per_second) * sample_rate)\n        end_frame = min(start_frame + snare_frames, frames)\n        \n        if start_frame \u003C frames:\n            t = np.linspace(0, snare_duration, end_frame - start_frame)\n            snare = np.exp(-10 * t) * np.random.uniform(-1, 1, len(t)) * 0.5\n            audio_data[start_frame:end_frame] += snare * 0.7\n    \n    audio_data = np.clip(audio_data, -1, 1)\n    \n    filepath = 'drums_stem.wav'\n    sf.write(filepath, audio_data, sample_rate, subtype=subtype, format='WAV')\n    \n    return filepath, audio_data\n\nprint(\"\\n=== Generating drum stem ===\")\ndrums_filepath, drums_data = generate_drum_stem(DURATION, SAMPLE_RATE, BPM, timing, subtype=SUBTYPE)\n\ndrums_result = verify_stem(drums_filepath, SAMPLE_RATE, SUBTYPE, DURATION)\nif drums_result['success']:\n    print(f\"✓ Drum stem verified: {drums_result['info'].duration:.2f}s @ {drums_result['info'].samplerate}Hz\")\n    generated_stems.append(drums_filepath)\n    stem_durations['drums'] = drums_result['info'].duration\nelse:\n    print(f\"✗ Drum stem FAILED: {drums_result['error']}\")\n    raise RuntimeError(f\"Drum stem generation failed: {drums_result['error']}\")\n```\n\n## Step 5: Align Stem Durations (NEW)\n\nHandle duration mismatches with adaptive extension strategies. Choose the appropriate method based on stem type:\n\n### Duration Mismatch Handling Strategies\n\n| Strategy | Best For | How It Works | Considerations |\n|----------|----------|--------------|----------------|\n| **Zero-padding** | Ambient pads, drones, FX | Append silence to match target duration | Simple, no artifacts, but may create abrupt endings |\n| **Looping** | Rhythmic elements, drums, percussion | Repeat content to fill duration | Maintains rhythm, but requires beat-aligned loop points |\n| **Crossfade extension** | Melodic elements, vocals, guitars | Fade out original, crossfade with looped\u002Ffaded content | Smoothest transition, but requires careful fade curve design |\n| **Time-stretch** | Any content (when quality matters) | Use phase vocoder to stretch without pitch shift | Computationally expensive, may introduce artifacts |\n\n```python\ndef align_stem_duration(input_filepath, output_filepath, target_duration, sample_rate, \n                        subtype='FLOAT', strategy='auto', stem_type=None):\n    \"\"\"\n    Align stem duration to target using appropriate strategy.\n    \n    Args:\n        input_filepath: Path to input stem\n        output_filepath: Path for aligned output\n        target_duration: Target duration in seconds\n        sample_rate: Sample rate\n        subtype: Audio subtype (FLOAT, PCM_24, etc.)\n        strategy: 'zero_pad', 'loop', 'crossfade', 'auto'\n        stem_type: Type of stem ('rhythmic', 'melodic', 'ambient', 'percussion')\n    \n    Returns:\n        dict with success status and alignment info\n    \"\"\"\n    if not os.path.exists(input_filepath):\n        return {'success': False, 'error': f'Input file not found: {input_filepath}'}\n    \n    # Load audio\n    data, sr = sf.read(input_filepath)\n    current_duration = len(data) \u002F sr\n    \n    # Check if alignment needed (allow 0.5s tolerance)\n    if abs(current_duration - target_duration) \u003C 0.5:\n        print(f\"  Duration already aligned: {current_duration:.2f}s ≈ {target_duration:.2f}s\")\n        # Just copy file\n        sf.write(output_filepath, data, sample_rate, subtype=subtype, format='WAV')\n        return {'success': True, 'strategy': 'none', 'original_duration': current_duration}\n    \n    # Auto-detect strategy if not specified\n    if strategy == 'auto':\n        if stem_type in ['rhythmic', 'percussion', 'drums']:\n            strategy = 'loop'\n        elif stem_type in ['ambient', 'pad', 'drone', 'fx']:\n            strategy = 'zero_pad'\n        else:  # melodic, vocals, guitars, etc.\n            strategy = 'crossfade'\n    \n    print(f\"  Aligning duration: {current_duration:.2f}s → {target_duration:.2f}s using '{strategy}'\")\n    \n    # Calculate frames needed\n    target_frames = int(target_duration * sample_rate)\n    current_frames = len(data)\n    \n    if strategy == 'zero_pad':\n        # Simple zero-padding\n        if current_frames \u003C target_frames:\n            aligned_data = np.zeros(target_frames, dtype=data.dtype)\n            aligned_data[:current_frames] = data\n        else:\n            # Truncate with fade-out\n            fade_frames = int(0.5 * sample_rate)  # 500ms fade\n            aligned_data = data[:target_frames].copy()\n            if target_frames \u003C current_frames:\n                fade_start = max(0, target_frames - fade_frames)\n                fade_curve = np.linspace(1, 0, target_frames - fade_start)\n                aligned_data[fade_start:] *= fade_curve\n    \n    elif strategy == 'loop':\n        # Loop to fill duration\n        aligned_data = np.zeros(target_frames, dtype=data.dtype)\n        loop_count = (target_frames \u002F\u002F current_frames) + 1\n        \n        for i in range(loop_count):\n            start = i * current_frames\n            end = min(start + current_frames, target_frames)\n            copy_len = end - start\n            \n            if copy_len > 0:\n                aligned_data[start:end] = data[:copy_len]\n        \n        # Apply crossfade at loop points to avoid clicks\n        crossfade_frames = int(0.05 * sample_rate)  # 50ms crossfade\n        if current_frames > crossfade_frames * 2:\n            for i in range(1, loop_count):\n                loop_start = i * current_frames\n                if loop_start \u003C target_frames:\n                    # Crossfade region\n                    cf_end = min(loop_start + crossfade_frames, target_frames)\n                    cf_start = max(loop_start - crossfade_frames, 0)\n                    if cf_end > cf_start:\n                        fade_in = np.linspace(0, 1, cf_end - cf_start)\n                        fade_out = np.linspace(1, 0, cf_end - cf_start)\n                        aligned_data[cf_start:cf_end] = (\n                            aligned_data[cf_start:cf_end] * fade_out +\n                            np.roll(aligned_data[cf_start:cf_end], -current_frames) * fade_in\n                        )\n    \n    elif strategy == 'crossfade':\n        # Crossfade-based extension with smooth transition\n        if current_frames \u003C target_frames:\n            # Extend with crossfaded loop\n            extension_frames = target_frames - current_frames\n            fade_frames = min(int(2.0 * sample_rate), extension_frames \u002F\u002F 2)  # Max 2s fade\n            \n            # Create extension from looped content with fade\n            extension_data = np.zeros(extension_frames, dtype=data.dtype)\n            \n            if extension_frames \u003C= current_frames:\n                # Just take from beginning with fade-in\n                extension_data[:extension_frames] = data[:extension_frames]\n                if fade_frames > 0:\n                    fade_in = np.linspace(0, 1, min(fade_frames, extension_frames))\n                    extension_data[:len(fade_in)] *= fade_in\n            else:\n                # Loop multiple times with crossfades\n                loop_data = np.tile(data, (extension_frames \u002F\u002F current_frames) + 2)[:extension_frames]\n                \n                # Apply fade-in to extension\n                if fade_frames > 0:\n                    fade_in = np.linspace(0, 1, fade_frames)\n                    loop_data[:fade_frames] *= fade_in\n                \n                extension_data = loop_data\n            \n            # Concatenate with crossfade\n            aligned_data = np.zeros(target_frames, dtype=data.dtype)\n            aligned_data[:current_frames] = data\n            \n            # Crossfade region at junction\n            if fade_frames > 0:\n                junction_start = current_frames - fade_frames\n                junction_end = min(current_frames + fade_frames, target_frames)\n                \n                if junction_end > junction_start:\n                    crossfade_len = junction_end - junction_start\n                    fade_out = np.linspace(1, 0, crossfade_len)\n                    fade_in = np.linspace(0, 1, crossfade_len)\n                    \n                    aligned_data[junction_start:junction_end] = (\n                        aligned_data[junction_start:junction_end] * fade_out +\n                        extension_data[:crossfade_len] * fade_in\n                    )\n                else:\n                    aligned_data[current_frames:current_frames + extension_frames] = extension_data\n            else:\n                aligned_data[current_frames:] = extension_data\n        else:\n            # Truncate with fade-out\n            fade_frames = int(2.0 * sample_rate)\n            aligned_data = data[:target_frames].copy()\n            fade_start = max(0, target_frames - fade_frames)\n            fade_curve = np.linspace(1, 0, target_frames - fade_start)\n            aligned_data[fade_start:] *= fade_curve\n    \n    else:\n        return {'success': False, 'error': f'Unknown strategy: {strategy}'}\n    \n    # Clip to prevent overload\n    aligned_data = np.clip(aligned_data, -1, 1)\n    \n    # Export\n    sf.write(output_filepath, aligned_data, sample_rate, subtype=subtype, format='WAV')\n    \n    # Verify\n    result = verify_stem(output_filepath, sample_rate, subtype, target_duration)\n    if result['success']:\n        return {\n            'success': True,\n            'strategy': strategy,\n            'original_duration': current_duration,\n            'aligned_duration': result['info'].duration\n        }\n    else:\n        return result\n\n# Apply duration alignment to all stems\nprint(\"\\n=== Aligning stem durations ===\")\naligned_stems = []\n\nfor stem_name in STEM_NAMES:\n    input_file = f'{stem_name}_stem.wav'\n    output_file = f'{stem_name}_aligned.wav'\n    \n    # Determine stem type for strategy selection\n    stem_type_map = {\n        'bass': 'rhythmic',\n        'guitars': 'melodic',\n        'synths': 'ambient',\n        'bridge': 'melodic'\n    }\n    stem_type = stem_type_map.get(stem_name, 'melodic')\n    \n    print(f\"Aligning {stem_name} (type: {stem_type})...\")\n    result = align_stem_duration(\n        input_file, output_file, TARGET_DURATION, SAMPLE_RATE,\n        subtype=SUBTYPE, strategy='auto', stem_type=stem_type\n    )\n    \n    if result['success']:\n        if result['strategy'] != 'none':\n            print(f\"✓ {stem_name} aligned: {result['original_duration']:.2f}s → {result['aligned_duration']:.2f}s ({result['strategy']})\")\n        else:\n            print(f\"✓ {stem_name} already aligned\")\n        aligned_stems.append(output_file)\n    else:\n        print(f\"✗ {stem_name} alignment FAILED: {result['error']}\")\n        raise RuntimeError(f\"Stem alignment failed for {stem_name}: {result['error']}\")\n\n# Align drums separately\ndrums_aligned = 'drums_aligned.wav'\nprint(f\"Aligning drums (type: percussion)...\")\ndrums_result = align_stem_duration(\n    'drums_stem.wav', drums_aligned, TARGET_DURATION, SAMPLE_RATE,\n    subtype=SUBTYPE, strategy='auto', stem_type='percussion'\n)\nif drums_result['success']:\n    if drums_result['strategy'] != 'none':\n        print(f\"✓ Drums aligned: {drums_result['original_duration']:.2f}s → {drums_result['aligned_duration']:.2f}s ({drums_result['strategy']})\")\n    else:\n        print(f\"✓ Drums already aligned\")\n    aligned_stems.append(drums_aligned)\nelse:\n    raise RuntimeError(f\"Drums alignment failed: {drums_result['error']}\")\n\n# Final duration verification - all stems must match\nprint(\"\\n=== Verifying duration alignment ===\")\nfinal_durations = {}\nfor stem_file in aligned_stems:\n    info = sf.info(stem_file)\n    stem_name = os.path.basename(stem_file).replace('_aligned.wav', '')\n    final_durations[stem_name] = info.duration\n    duration_diff = abs(info.duration - TARGET_DURATION)\n    \n    if duration_diff > 0.5:\n        print(f\"✗ WARNING: {stem_name} duration mismatch: {info.duration:.2f}s vs target {TARGET_DURATION:.2f}s\")\n    else:\n        print(f\"✓ {stem_name}: {info.duration:.2f}s (Δ{duration_diff:.2f}s)\")\n\nmax_duration_diff = max(abs(d - TARGET_DURATION) for d in final_durations.values())\nif max_duration_diff > 0.5:\n    raise RuntimeError(f\"Duration alignment incomplete: max deviation {max_duration_diff:.2f}s exceeds tolerance\")\nprint(f\"\\nAll stems aligned within tolerance (max deviation: {max_duration_diff:.2f}s)\")\n```\n\n## Step 6: Apply Effects with Verification\n\nProcess each stem and verify the output:\n\n```python\nfrom scipy import signal\n\ndef apply_lowpass_filter(audio_data, sample_rate, cutoff_freq=8000):\n    \"\"\"Apply lowpass filter using scipy.signal.\"\"\"\n    nyquist = sample_rate \u002F 2\n    normalized_cutoff = cutoff_freq \u002F nyquist\n    b, a = signal.butter(4, normalized_cutoff, btype='low')\n    return signal.filtfilt(b, a, audio_data)\n\ndef apply_effects_and_verify(input_filepath, output_filepath, sample_rate, subtype):\n    \"\"\"Apply effects to stem and verify output.\"\"\"\n    data, sr = sf.read(input_filepath)\n    \n    # Apply effects\n    processed = apply_lowpass_filter(data, sr, cutoff_freq=8000)\n    processed = np.clip(processed, -1, 1)\n    \n    # Export\n    sf.write(output_filepath, processed, sample_rate, subtype=subtype, format='WAV')\n    \n    # Verify\n    result = verify_stem(output_filepath, sample_rate, subtype, TARGET_DURATION)\n    return result, processed\n\nprint(\"\\n=== Applying effects to all stems ===\")\nprocessed_stems = []\n\nfor stem_name in STEM_NAMES:\n    input_file = f'{stem_name}_aligned.wav'\n    output_file = f'{stem_name}_processed.wav'\n    \n    print(f\"Processing {stem_name}...\")\n    result, _ = apply_effects_and_verify(input_file, output_file, SAMPLE_RATE, SUBTYPE)\n    \n    if result['success']:\n        print(f\"✓ {stem_name} processed and verified\")\n        processed_stems.append(output_file)\n    else:\n        print(f\"✗ {stem_name} processing FAILED: {result['error']}\")\n        raise RuntimeError(f\"Effects processing failed for {stem_name}\")\n\n# Process drums separately\ndrums_output = 'drums_processed.wav'\ndrums_result, _ = apply_effects_and_verify('drums_aligned.wav', drums_output, SAMPLE_RATE, SUBTYPE)\nif drums_result['success']:\n    print(f\"✓ Drums processed and verified\")\n    processed_stems.append(drums_output)\nelse:\n    raise RuntimeError(f\"Drums processing failed: {drums_result['error']}\")\n```\n\n## Step 7: Export Master Track\n\nMix all verified stems into master track:\n\n```python\ndef create_master_track(stem_files, output_filepath, sample_rate, subtype):\n    \"\"\"Create master track from verified stems with gain staging.\"\"\"\n    # Load first stem to get dimensions\n    first_data, sr = sf.read(stem_files[0])\n    master_audio = np.zeros(len(first_data), dtype=np.float32)\n    \n    # Verify all stems have matching length\n    for stem_file in stem_files:\n        data, _ = sf.read(stem_file)\n        if len(data) != len(first_data):\n            raise ValueError(f\"Stem length mismatch: {stem_file} has {len(data)} frames, expected {len(first_data)}\")\n    \n    # Mix all stems with gain staging\n    gain_per_stem = 0.4  # Prevent clipping with 5 stems\n   \n    for i, stem_file in enumerate(stem_files):\n        data, sr = sf.read(stem_file)\n        master_audio += data * gain_per_stem\n        print(f\"  Mixed {os.path.basename(stem_file)} (gain: {gain_per_stem})\")\n    \n    # Apply master bus limiting\n    master_audio = np.clip(master_audio, -1, 1)\n    \n    # Soft clip for warmth\n    master_audio = np.tanh(master_audio * 1.2) \u002F 1.2\n    \n    # Export\n    sf.write(output_filepath, master_audio, sample_rate, subtype=subtype, format='WAV')\n    \n    # Verify\n    info = sf.info(output_filepath)\n    print(f\"Master exported: {info.duration:.2f}s @ {info.samplerate}Hz, {info.channels}ch\")\n    \n    return output_filepath, master_audio\n\nprint(\"\\n=== Creating master track ===\")\nmaster_filepath, master_data = create_master_track(processed_stems, 'master.wav', SAMPLE_RATE, SUBTYPE)\n```\n\n## Step 8: Archive and Final Verification\n\nPackage deliverables with comprehensive checks:\n\n```python\nimport json\nfrom datetime import datetime\n\ndef create_archive_manifest(stem_files, master_file, output_dir='deliverables'):\n    \"\"\"Create archive manifest with comprehensive verification.\"\"\"\n    os.makedirs(output_dir, exist_ok=True)\n    \n    manifest = {\n        'created': datetime.now().isoformat(),\n        'target_duration': TARGET_DURATION,\n        'sample_rate': SAMPLE_RATE,\n        'subtype': SUBTYPE,\n        'stems': [],\n        'master': None,\n        'verification': {\n            'all_stems_aligned': True,\n            'all_stems_verified': True,\n            'master_verified': True\n        }\n    }\n    \n    # Verify each stem\n    for stem_file in stem_files:\n        if not os.path.exists(stem_file):\n            manifest['verification']['all_stems_verified'] = False\n            continue\n        \n        info = sf.info(stem_file)\n        stem_name = os.path.basename(stem_file)\n        duration_diff = abs(info.duration - TARGET_DURATION)\n        \n        stem_info = {\n            'file': stem_name,\n            'duration': info.duration,\n            'sample_rate': info.samplerate,\n            'channels': info.channels,\n            'duration_aligned': duration_diff \u003C 0.5\n        }\n        manifest['stems'].append(stem_info)\n        \n        if duration_diff >= 0.5:\n            manifest['verification']['all_stems_aligned'] = False\n            print(f\"WARNING: {stem_name} duration misaligned by {duration_diff:.2f}s\")\n    \n    # Verify master\n    if os.path.exists(master_file):\n        info = sf.info(master_file)\n        manifest['master'] = {\n            'file': os.path.basename(master_file),\n            'duration': info.duration,\n            'sample_rate': info.samplerate,\n            'channels': info.channels,\n            'subtype': info.subtype\n        }\n        \n        # Check master duration matches target\n        if abs(info.duration - TARGET_DURATION) > 1.0:\n            manifest['verification']['master_verified'] = False\n            print(f\"WARNING: Master duration {info.duration:.2f}s differs from target {TARGET_DURATION:.2f}s\")\n    else:\n        manifest['verification']['master_verified'] = False\n    \n    # Save manifest\n    manifest_path = os.path.join(output_dir, 'manifest.json')\n    with open(manifest_path, 'w') as f:\n        json.dump(manifest, f, indent=2)\n    \n    # Copy files to deliverables\n    import shutil\n    for stem_file in stem_files:\n        shutil.copy(stem_file, output_dir)\n    shutil.copy(master_file, output_dir)\n    \n    return manifest_path, manifest\n\nprint(\"\\n=== Creating archive ===\")\nmanifest_path, manifest = create_archive_manifest(processed_stems, master_filepath)\nprint(f\"Archive manifest created: {manifest_path}\")\n\n# Final summary\nprint(\"\\n\" + \"=\"*60)\nprint(\"PRODUCTION COMPLETE\")\nprint(\"=\"*60)\nprint(f\"Target duration: {TARGET_DURATION:.2f}s\")\nprint(f\"Sample rate: {SAMPLE_RATE}Hz\")\nprint(f\"Stems processed: {len(processed_stems)}\")\nprint(f\"All stems aligned: {manifest['verification']['all_stems_aligned']}\")\nprint(f\"Master verified: {manifest['verification']['master_verified']}\")\nprint(f\"Deliverables: .\u002Fdeliverables\u002F\")\nprint(\"=\"*60)\n```\n\n## Troubleshooting Duration Mismatches\n\n### Common Causes\n1. **Different sample rates**: Ensure all stems use the same sample rate\n2. **Incorrect frame calculations**: Verify `frames = int(duration * sample_rate)` calculations\n3. **Off-by-one errors**: Check array indexing and loop boundaries\n4. **Resampling artifacts**: When converting between sample rates, use high-quality resampling\n\n### Strategy Selection Guide\n\n**Use zero-padding when:**\n- Stem is ambient\u002Fpad\u002Fdrone content\n- Short duration mismatch (\u003C 10% of total)\n- Quick turnaround needed\n\n**Use looping when:**\n- Stem is rhythmic (drums, percussion, rhythmic bass)\n- Content has clear loop points\n- Loop length divides evenly into target duration\n\n**Use crossfade extension when:**\n- Stem is melodic (vocals, guitars, synths)\n- Quality is priority over speed\n- Significant duration extension needed\n\n**Use time-stretch when:**\n- Content cannot be looped or padded\n- Pitch must be preserved\n- High-quality processing is available (e.g., librubberband, elasticsearch)\n\n### Verification Checklist\n- [ ] All stems have matching sample rate\n- [ ] All stems within 0.5s of target duration\n- [ ] No clipping in any stem (-1 to 1 range)\n- [ ] Master track duration matches target\n- [ ] Archive manifest generated with verification status\n","# Adaptive Stem Alignment Workflow\n\nThis skill provides a resilient pattern for audio production that emphasizes **incremental verification**, **fail-fast** principles, and **adaptive duration handling**. Each major step produces verified outputs before proceeding, with explicit strategies for handling stems of different durations.\n\n## Overview\n\nFollow these steps in strict order. Each step must complete successfully and pass verification before proceeding to the next:\n\n1. **Early timing calculation** - Derive section transitions from BPM and duration first\n2. **Verify reference audio** - Validate input file properties and establish target duration\n3. **Generate and verify each stem individually** - One stem at a time with immediate verification\n4. **Generate drum stem separately** - Dedicated drum extension with rhythm patterns\n5. **Align stem durations** - Handle duration mismatches with adaptive extension strategies\n6. **Apply effects with verification** - Process each stem and verify output\n7. **Export master track** - Mix all verified stems\n8. **Archive and final verification** - Package deliverables with comprehensive checks\n\n## Key Differences from Standard Workflow\n\n- **Incremental verification**: Verify each stem immediately after generation, not just at the end\n- **Fail-fast approach**: Stop and report errors at each step rather than accumulating failures\n- **Early timing**: Calculate section transitions before any audio generation\n- **Separated drums**: Drum stem generation is a distinct step with rhythm-specific processing\n- **Memory-efficient**: Process stems individually to avoid large array operations that cause sandbox failures\n- **Adaptive duration handling**: Explicit strategies for mismatched stem durations (zero-padding, looping, crossfade extension)\n- **Pre-mix alignment**: Verify all stems match target duration before mixing\n\n## Step 1: Calculate Timing Parameters (Early)\n\nCalculate all timing parameters **before** generating any audio. This ensures consistent timing across all stems:\n\n```python\ndef calculate_section_transitions(bpm, total_duration_sec, sections):\n    \"\"\"Calculate beat-aligned transition points for song sections.\"\"\"\n    beats_per_second = bpm \u002F 60.0\n    \n    section_durations = {}\n    cumulative_time = 0\n    \n    for section_name, beat_count in sections.items():\n        duration = beat_count \u002F beats_per_second\n        section_durations[section_name] = {\n            'start': cumulative_time,\n            'end': cumulative_time + duration,\n            'beats': beat_count,\n            'start_beat': cumulative_time * beats_per_second\n        }\n        cumulative_time += duration\n    \n    return section_durations\n\n# Configuration\nBPM = 120\nDURATION = 137\nSECTIONS = {'intro': 16, 'verse': 32, 'chorus': 32, 'bridge': 16, 'outro': 16}\n\ntiming = calculate_section_transitions(BPM, DURATION, SECTIONS)\nprint(\"Timing calculated:\")\nfor section, data in timing.items():\n    print(f\"  {section}: {data['start']:.2f}s - {data['end']:.2f}s ({data['beats']} beats)\")\n```\n\n## Step 2: Verify Reference Audio\n\nValidate the reference file exists and has expected properties:\n\n```python\nimport soundfile as sf\nimport os\n\ndef verify_reference_file(filepath, expected_sample_rate=None, min_duration=None):\n    \"\"\"Verify reference audio file and return info dict.\"\"\"\n    if not os.path.exists(filepath):\n        raise FileNotFoundError(f\"Reference file not found: {filepath}\")\n    \n    info = sf.info(filepath)\n    errors = []\n    \n    if expected_sample_rate and info.samplerate != expected_sample_rate:\n        errors.append(f\"Sample rate mismatch: expected {expected_sample_rate}, got {info.samplerate}\")\n    \n    if min_duration and info.duration \u003C min_duration:\n        errors.append(f\"Duration too short: expected >= {min_duration}s, got {info.duration}s\")\n    \n    if errors:\n        raise ValueError(f\"Reference file validation failed: {'; '.join(errors)}\")\n    \n    print(f\"Reference verified: {info.duration:.2f}s @ {info.samplerate}Hz, {info.channels}ch, {info.subtype}\")\n    return {\n        'sample_rate': info.samplerate,\n        'duration': info.duration,\n        'channels': info.channels,\n        'subtype': info.subtype\n    }\n\n# Verify reference\nref_info = verify_reference_file('reference.wav', expected_sample_rate=48000, min_duration=130)\nTARGET_DURATION = ref_info['duration']  # Use reference duration as target\n```\n\n## Step 3: Generate and Verify Each Stem Individually\n\nGenerate one stem at a time, verify it immediately before proceeding to the next:\n\n```python\nimport numpy as np\n\ndef generate_stem(name, duration_sec, sample_rate, subtype='FLOAT', section_timing=None):\n    \"\"\"Generate a single stem with explicit sample type.\"\"\"\n    frames = int(duration_sec * sample_rate)\n    t = np.linspace(0, duration_sec, frames)\n    \n    # Generate stem-specific content (customize per stem type)\n    if name == 'bass':\n        freq = 110  # A2\n        audio_data = np.sin(2 * np.pi * freq * t) * 0.8\n    elif name == 'guitars':\n        freq = 440  # A4\n        audio_data = np.sin(2 * np.pi * freq * t) * 0.6\n    elif name == 'synths':\n        freq = 880  # A5\n        audio_data = np.sin(2 * np.pi * freq * t) * 0.5\n    elif name == 'bridge':\n        freq = 220  # A3\n        audio_data = np.sin(2 * np.pi * freq * t) * 0.7\n    else:\n        audio_data = np.sin(2 * np.pi * 440 * t) * 0.5\n    \n    # Ensure proper data type\n    if subtype == 'FLOAT':\n        audio_data = audio_data.astype(np.float32)\n    elif subtype == 'PCM_24':\n        audio_data = np.clip(audio_data, -1, 1) * (2**23 - 1)\n        audio_data = audio_data.astype(np.int32)\n    \n    filepath = f'{name}_stem.wav'\n    sf.write(filepath, audio_data, sample_rate, subtype=subtype, format='WAV')\n    \n    return filepath, audio_data\n\ndef verify_stem(filepath, expected_sample_rate, expected_subtype, expected_duration):\n    \"\"\"Verify a single stem meets specifications.\"\"\"\n    if not os.path.exists(filepath):\n        return {'success': False, 'error': f'File not found: {filepath}'}\n    \n    info = sf.info(filepath)\n    errors = []\n    \n    if info.samplerate != expected_sample_rate:\n        errors.append(f'sample_rate: expected {expected_sample_rate}, got {info.samplerate}')\n    \n    if info.subtype != expected_subtype:\n        errors.append(f'subtype: expected {expected_subtype}, got {info.subtype}')\n    \n    if abs(info.duration - expected_duration) > 1.0:  # Allow 1s tolerance\n        errors.append(f'duration: expected ~{expected_duration}s, got {info.duration}s')\n    \n    if errors:\n        return {'success': False, 'error': '; '.join(errors)}\n    \n    return {'success': True, 'info': info}\n\n# Generate stems one at a time with verification\nSAMPLE_RATE = 48000\nSUBTYPE = 'FLOAT'\nSTEM_NAMES = ['bass', 'guitars', 'synths', 'bridge']\n\ngenerated_stems = []\nstem_durations = {}  # Track actual durations for alignment step\n\nfor stem_name in STEM_NAMES:\n    print(f\"\\n=== Generating {stem_name} stem ===\")\n    \n    # Generate\n    filepath, data = generate_stem(stem_name, DURATION, SAMPLE_RATE, subtype=SUBTYPE)\n    \n    # Verify immediately\n    result = verify_stem(filepath, SAMPLE_RATE, SUBTYPE, DURATION)\n    \n    if result['success']:\n        print(f\"✓ {stem_name} stem verified: {result['info'].duration:.2f}s @ {result['info'].samplerate}Hz\")\n        generated_stems.append(filepath)\n        stem_durations[stem_name] = result['info'].duration\n    else:\n        print(f\"✗ {stem_name} stem FAILED: {result['error']}\")\n        raise RuntimeError(f\"Stem generation failed for {stem_name}: {result['error']}\")\n\nprint(f\"\\nAll {len(generated_stems)} stems generated and verified successfully\")\n```\n\n## Step 4: Generate Drum Stem Separately\n\nDrums require different processing (rhythm patterns, percussion sounds):\n\n```python\ndef generate_drum_stem(duration_sec, sample_rate, bpm, section_timing, subtype='FLOAT'):\n    \"\"\"Generate drum stem with rhythm patterns aligned to sections.\"\"\"\n    frames = int(duration_sec * sample_rate)\n    audio_data = np.zeros(frames, dtype=np.float32)\n    beats_per_second = bpm \u002F 60.0\n    \n    # Simple kick drum pattern (every beat)\n    kick_freq = 60\n    kick_duration = 0.1\n    kick_frames = int(kick_duration * sample_rate)\n    \n    for beat_time in np.arange(0, duration_sec, 1.0 \u002F beats_per_second):\n        start_frame = int(beat_time * sample_rate)\n        end_frame = min(start_frame + kick_frames, frames)\n        \n        if start_frame \u003C frames:\n            t = np.linspace(0, kick_duration, end_frame - start_frame)\n            kick = np.exp(-5 * t) * np.sin(2 * np.pi * kick_freq * t)\n            audio_data[start_frame:end_frame] += kick * 0.9\n    \n    # Simple snare pattern (every 2nd and 4th beat)\n    snare_freq = 200\n    snare_duration = 0.05\n    snare_frames = int(snare_duration * sample_rate)\n    \n    for beat_time in np.arange(0, duration_sec, 2.0 \u002F beats_per_second):\n        start_frame = int((beat_time + 0.5 \u002F beats_per_second) * sample_rate)\n        end_frame = min(start_frame + snare_frames, frames)\n        \n        if start_frame \u003C frames:\n            t = np.linspace(0, snare_duration, end_frame - start_frame)\n            snare = np.exp(-10 * t) * np.random.uniform(-1, 1, len(t)) * 0.5\n            audio_data[start_frame:end_frame] += snare * 0.7\n    \n    audio_data = np.clip(audio_data, -1, 1)\n    \n    filepath = 'drums_stem.wav'\n    sf.write(filepath, audio_data, sample_rate, subtype=subtype, format='WAV')\n    \n    return filepath, audio_data\n\nprint(\"\\n=== Generating drum stem ===\")\ndrums_filepath, drums_data = generate_drum_stem(DURATION, SAMPLE_RATE, BPM, timing, subtype=SUBTYPE)\n\ndrums_result = verify_stem(drums_filepath, SAMPLE_RATE, SUBTYPE, DURATION)\nif drums_result['success']:\n    print(f\"✓ Drum stem verified: {drums_result['info'].duration:.2f}s @ {drums_result['info'].samplerate}Hz\")\n    generated_stems.append(drums_filepath)\n    stem_durations['drums'] = drums_result['info'].duration\nelse:\n    print(f\"✗ Drum stem FAILED: {drums_result['error']}\")\n    raise RuntimeError(f\"Drum stem generation failed: {drums_result['error']}\")\n```\n\n## Step 5: Align Stem Durations (NEW)\n\nHandle duration mismatches with adaptive extension strategies. Choose the appropriate method based on stem type:\n\n### Duration Mismatch Handling Strategies\n\n| Strategy | Best For | How It Works | Considerations |\n|----------|----------|--------------|----------------|\n| **Zero-padding** | Ambient pads, drones, FX | Append silence to match target duration | Simple, no artifacts, but may create abrupt endings |\n| **Looping** | Rhythmic elements, drums, percussion | Repeat content to fill duration | Maintains rhythm, but requires beat-aligned loop points |\n| **Crossfade extension** | Melodic elements, vocals, guitars | Fade out original, crossfade with looped\u002Ffaded content | Smoothest transition, but requires careful fade curve design |\n| **Time-stretch** | Any content (when quality matters) | Use phase vocoder to stretch without pitch shift | Computationally expensive, may introduce artifacts |\n\n```python\ndef align_stem_duration(input_filepath, output_filepath, target_duration, sample_rate, \n                        subtype='FLOAT', strategy='auto', stem_type=None):\n    \"\"\"\n    Align stem duration to target using appropriate strategy.\n    \n    Args:\n        input_filepath: Path to input stem\n        output_filepath: Path for aligned output\n        target_duration: Target duration in seconds\n        sample_rate: Sample rate\n        subtype: Audio subtype (FLOAT, PCM_24, etc.)\n        strategy: 'zero_pad', 'loop', 'crossfade', 'auto'\n        stem_type: Type of stem ('rhythmic', 'melodic', 'ambient', 'percussion')\n    \n    Returns:\n        dict with success status and alignment info\n    \"\"\"\n    if not os.path.exists(input_filepath):\n        return {'success': False, 'error': f'Input file not found: {input_filepath}'}\n    \n    # Load audio\n    data, sr = sf.read(input_filepath)\n    current_duration = len(data) \u002F sr\n    \n    # Check if alignment needed (allow 0.5s tolerance)\n    if abs(current_duration - target_duration) \u003C 0.5:\n        print(f\"  Duration already aligned: {current_duration:.2f}s ≈ {target_duration:.2f}s\")\n        # Just copy file\n        sf.write(output_filepath, data, sample_rate, subtype=subtype, format='WAV')\n        return {'success': True, 'strategy': 'none', 'original_duration': current_duration}\n    \n    # Auto-detect strategy if not specified\n    if strategy == 'auto':\n        if stem_type in ['rhythmic', 'percussion', 'drums']:\n            strategy = 'loop'\n        elif stem_type in ['ambient', 'pad', 'drone', 'fx']:\n            strategy = 'zero_pad'\n        else:  # melodic, vocals, guitars, etc.\n            strategy = 'crossfade'\n    \n    print(f\"  Aligning duration: {current_duration:.2f}s → {target_duration:.2f}s using '{strategy}'\")\n    \n    # Calculate frames needed\n    target_frames = int(target_duration * sample_rate)\n    current_frames = len(data)\n    \n    if strategy == 'zero_pad':\n        # Simple zero-padding\n        if current_frames \u003C target_frames:\n            aligned_data = np.zeros(target_frames, dtype=data.dtype)\n            aligned_data[:current_frames] = data\n        else:\n            # Truncate with fade-out\n            fade_frames = int(0.5 * sample_rate)  # 500ms fade\n            aligned_data = data[:target_frames].copy()\n            if target_frames \u003C current_frames:\n                fade_start = max(0, target_frames - fade_frames)\n                fade_curve = np.linspace(1, 0, target_frames - fade_start)\n                aligned_data[fade_start:] *= fade_curve\n    \n    elif strategy == 'loop':\n        # Loop to fill duration\n        aligned_data = np.zeros(target_frames, dtype=data.dtype)\n        loop_count = (target_frames \u002F\u002F current_frames) + 1\n        \n        for i in range(loop_count):\n            start = i * current_frames\n            end = min(start + current_frames, target_frames)\n            copy_len = end - start\n            \n            if copy_len > 0:\n                aligned_data[start:end] = data[:copy_len]\n        \n        # Apply crossfade at loop points to avoid clicks\n        crossfade_frames = int(0.05 * sample_rate)  # 50ms crossfade\n        if current_frames > crossfade_frames * 2:\n            for i in range(1, loop_count):\n                loop_start = i * current_frames\n                if loop_start \u003C target_frames:\n                    # Crossfade region\n                    cf_end = min(loop_start + crossfade_frames, target_frames)\n                    cf_start = max(loop_start - crossfade_frames, 0)\n                    if cf_end > cf_start:\n                        fade_in = np.linspace(0, 1, cf_end - cf_start)\n                        fade_out = np.linspace(1, 0, cf_end - cf_start)\n                        aligned_data[cf_start:cf_end] = (\n                            aligned_data[cf_start:cf_end] * fade_out +\n                            np.roll(aligned_data[cf_start:cf_end], -current_frames) * fade_in\n                        )\n    \n    elif strategy == 'crossfade':\n        # Crossfade-based extension with smooth transition\n        if current_frames \u003C target_frames:\n            # Extend with crossfaded loop\n            extension_frames = target_frames - current_frames\n            fade_frames = min(int(2.0 * sample_rate), extension_frames \u002F\u002F 2)  # Max 2s fade\n            \n            # Create extension from looped content with fade\n            extension_data = np.zeros(extension_frames, dtype=data.dtype)\n            \n            if extension_frames \u003C= current_frames:\n                # Just take from beginning with fade-in\n                extension_data[:extension_frames] = data[:extension_frames]\n                if fade_frames > 0:\n                    fade_in = np.linspace(0, 1, min(fade_frames, extension_frames))\n                    extension_data[:len(fade_in)] *= fade_in\n            else:\n                # Loop multiple times with crossfades\n                loop_data = np.tile(data, (extension_frames \u002F\u002F current_frames) + 2)[:extension_frames]\n                \n                # Apply fade-in to extension\n                if fade_frames > 0:\n                    fade_in = np.linspace(0, 1, fade_frames)\n                    loop_data[:fade_frames] *= fade_in\n                \n                extension_data = loop_data\n            \n            # Concatenate with crossfade\n            aligned_data = np.zeros(target_frames, dtype=data.dtype)\n            aligned_data[:current_frames] = data\n            \n            # Crossfade region at junction\n            if fade_frames > 0:\n                junction_start = current_frames - fade_frames\n                junction_end = min(current_frames + fade_frames, target_frames)\n                \n                if junction_end > junction_start:\n                    crossfade_len = junction_end - junction_start\n                    fade_out = np.linspace(1, 0, crossfade_len)\n                    fade_in = np.linspace(0, 1, crossfade_len)\n                    \n                    aligned_data[junction_start:junction_end] = (\n                        aligned_data[junction_start:junction_end] * fade_out +\n                        extension_data[:crossfade_len] * fade_in\n                    )\n                else:\n                    aligned_data[current_frames:current_frames + extension_frames] = extension_data\n            else:\n                aligned_data[current_frames:] = extension_data\n        else:\n            # Truncate with fade-out\n            fade_frames = int(2.0 * sample_rate)\n            aligned_data = data[:target_frames].copy()\n            fade_start = max(0, target_frames - fade_frames)\n            fade_curve = np.linspace(1, 0, target_frames - fade_start)\n            aligned_data[fade_start:] *= fade_curve\n    \n    else:\n        return {'success': False, 'error': f'Unknown strategy: {strategy}'}\n    \n    # Clip to prevent overload\n    aligned_data = np.clip(aligned_data, -1, 1)\n    \n    # Export\n    sf.write(output_filepath, aligned_data, sample_rate, subtype=subtype, format='WAV')\n    \n    # Verify\n    result = verify_stem(output_filepath, sample_rate, subtype, target_duration)\n    if result['success']:\n        return {\n            'success': True,\n            'strategy': strategy,\n            'original_duration': current_duration,\n            'aligned_duration': result['info'].duration\n        }\n    else:\n        return result\n\n# Apply duration alignment to all stems\nprint(\"\\n=== Aligning stem durations ===\")\naligned_stems = []\n\nfor stem_name in STEM_NAMES:\n    input_file = f'{stem_name}_stem.wav'\n    output_file = f'{stem_name}_aligned.wav'\n    \n    # Determine stem type for strategy selection\n    stem_type_map = {\n        'bass': 'rhythmic',\n        'guitars': 'melodic',\n        'synths': 'ambient',\n        'bridge': 'melodic'\n    }\n    stem_type = stem_type_map.get(stem_name, 'melodic')\n    \n    print(f\"Aligning {stem_name} (type: {stem_type})...\")\n    result = align_stem_duration(\n        input_file, output_file, TARGET_DURATION, SAMPLE_RATE,\n        subtype=SUBTYPE, strategy='auto', stem_type=stem_type\n    )\n    \n    if result['success']:\n        if result['strategy'] != 'none':\n            print(f\"✓ {stem_name} aligned: {result['original_duration']:.2f}s → {result['aligned_duration']:.2f}s ({result['strategy']})\")\n        else:\n            print(f\"✓ {stem_name} already aligned\")\n        aligned_stems.append(output_file)\n    else:\n        print(f\"✗ {stem_name} alignment FAILED: {result['error']}\")\n        raise RuntimeError(f\"Stem alignment failed for {stem_name}: {result['error']}\")\n\n# Align drums separately\ndrums_aligned = 'drums_aligned.wav'\nprint(f\"Aligning drums (type: percussion)...\")\ndrums_result = align_stem_duration(\n    'drums_stem.wav', drums_aligned, TARGET_DURATION, SAMPLE_RATE,\n    subtype=SUBTYPE, strategy='auto', stem_type='percussion'\n)\nif drums_result['success']:\n    if drums_result['strategy'] != 'none':\n        print(f\"✓ Drums aligned: {drums_result['original_duration']:.2f}s → {drums_result['aligned_duration']:.2f}s ({drums_result['strategy']})\")\n    else:\n        print(f\"✓ Drums already aligned\")\n    aligned_stems.append(drums_aligned)\nelse:\n    raise RuntimeError(f\"Drums alignment failed: {drums_result['error']}\")\n\n# Final duration verification - all stems must match\nprint(\"\\n=== Verifying duration alignment ===\")\nfinal_durations = {}\nfor stem_file in aligned_stems:\n    info = sf.info(stem_file)\n    stem_name = os.path.basename(stem_file).replace('_aligned.wav', '')\n    final_durations[stem_name] = info.duration\n    duration_diff = abs(info.duration - TARGET_DURATION)\n    \n    if duration_diff > 0.5:\n        print(f\"✗ WARNING: {stem_name} duration mismatch: {info.duration:.2f}s vs target {TARGET_DURATION:.2f}s\")\n    else:\n        print(f\"✓ {stem_name}: {info.duration:.2f}s (Δ{duration_diff:.2f}s)\")\n\nmax_duration_diff = max(abs(d - TARGET_DURATION) for d in final_durations.values())\nif max_duration_diff > 0.5:\n    raise RuntimeError(f\"Duration alignment incomplete: max deviation {max_duration_diff:.2f}s exceeds tolerance\")\nprint(f\"\\nAll stems aligned within tolerance (max deviation: {max_duration_diff:.2f}s)\")\n```\n\n## Step 6: Apply Effects with Verification\n\nProcess each stem and verify the output:\n\n```python\nfrom scipy import signal\n\ndef apply_lowpass_filter(audio_data, sample_rate, cutoff_freq=8000):\n    \"\"\"Apply lowpass filter using scipy.signal.\"\"\"\n    nyquist = sample_rate \u002F 2\n    normalized_cutoff = cutoff_freq \u002F nyquist\n    b, a = signal.butter(4, normalized_cutoff, btype='low')\n    return signal.filtfilt(b, a, audio_data)\n\ndef apply_effects_and_verify(input_filepath, output_filepath, sample_rate, subtype):\n    \"\"\"Apply effects to stem and verify output.\"\"\"\n    data, sr = sf.read(input_filepath)\n    \n    # Apply effects\n    processed = apply_lowpass_filter(data, sr, cutoff_freq=8000)\n    processed = np.clip(processed, -1, 1)\n    \n    # Export\n    sf.write(output_filepath, processed, sample_rate, subtype=subtype, format='WAV')\n    \n    # Verify\n    result = verify_stem(output_filepath, sample_rate, subtype, TARGET_DURATION)\n    return result, processed\n\nprint(\"\\n=== Applying effects to all stems ===\")\nprocessed_stems = []\n\nfor stem_name in STEM_NAMES:\n    input_file = f'{stem_name}_aligned.wav'\n    output_file = f'{stem_name}_processed.wav'\n    \n    print(f\"Processing {stem_name}...\")\n    result, _ = apply_effects_and_verify(input_file, output_file, SAMPLE_RATE, SUBTYPE)\n    \n    if result['success']:\n        print(f\"✓ {stem_name} processed and verified\")\n        processed_stems.append(output_file)\n    else:\n        print(f\"✗ {stem_name} processing FAILED: {result['error']}\")\n        raise RuntimeError(f\"Effects processing failed for {stem_name}\")\n\n# Process drums separately\ndrums_output = 'drums_processed.wav'\ndrums_result, _ = apply_effects_and_verify('drums_aligned.wav', drums_output, SAMPLE_RATE, SUBTYPE)\nif drums_result['success']:\n    print(f\"✓ Drums processed and verified\")\n    processed_stems.append(drums_output)\nelse:\n    raise RuntimeError(f\"Drums processing failed: {drums_result['error']}\")\n```\n\n## Step 7: Export Master Track\n\nMix all verified stems into master track:\n\n```python\ndef create_master_track(stem_files, output_filepath, sample_rate, subtype):\n    \"\"\"Create master track from verified stems with gain staging.\"\"\"\n    # Load first stem to get dimensions\n    first_data, sr = sf.read(stem_files[0])\n    master_audio = np.zeros(len(first_data), dtype=np.float32)\n    \n    # Verify all stems have matching length\n    for stem_file in stem_files:\n        data, _ = sf.read(stem_file)\n        if len(data) != len(first_data):\n            raise ValueError(f\"Stem length mismatch: {stem_file} has {len(data)} frames, expected {len(first_data)}\")\n    \n    # Mix all stems with gain staging\n    gain_per_stem = 0.4  # Prevent clipping with 5 stems\n   \n    for i, stem_file in enumerate(stem_files):\n        data, sr = sf.read(stem_file)\n        master_audio += data * gain_per_stem\n        print(f\"  Mixed {os.path.basename(stem_file)} (gain: {gain_per_stem})\")\n    \n    # Apply master bus limiting\n    master_audio = np.clip(master_audio, -1, 1)\n    \n    # Soft clip for warmth\n    master_audio = np.tanh(master_audio * 1.2) \u002F 1.2\n    \n    # Export\n    sf.write(output_filepath, master_audio, sample_rate, subtype=subtype, format='WAV')\n    \n    # Verify\n    info = sf.info(output_filepath)\n    print(f\"Master exported: {info.duration:.2f}s @ {info.samplerate}Hz, {info.channels}ch\")\n    \n    return output_filepath, master_audio\n\nprint(\"\\n=== Creating master track ===\")\nmaster_filepath, master_data = create_master_track(processed_stems, 'master.wav', SAMPLE_RATE, SUBTYPE)\n```\n\n## Step 8: Archive and Final Verification\n\nPackage deliverables with comprehensive checks:\n\n```python\nimport json\nfrom datetime import datetime\n\ndef create_archive_manifest(stem_files, master_file, output_dir='deliverables'):\n    \"\"\"Create archive manifest with comprehensive verification.\"\"\"\n    os.makedirs(output_dir, exist_ok=True)\n    \n    manifest = {\n        'created': datetime.now().isoformat(),\n        'target_duration': TARGET_DURATION,\n        'sample_rate': SAMPLE_RATE,\n        'subtype': SUBTYPE,\n        'stems': [],\n        'master': None,\n        'verification': {\n            'all_stems_aligned': True,\n            'all_stems_verified': True,\n            'master_verified': True\n        }\n    }\n    \n    # Verify each stem\n    for stem_file in stem_files:\n        if not os.path.exists(stem_file):\n            manifest['verification']['all_stems_verified'] = False\n            continue\n        \n        info = sf.info(stem_file)\n        stem_name = os.path.basename(stem_file)\n        duration_diff = abs(info.duration - TARGET_DURATION)\n        \n        stem_info = {\n            'file': stem_name,\n            'duration': info.duration,\n            'sample_rate': info.samplerate,\n            'channels': info.channels,\n            'duration_aligned': duration_diff \u003C 0.5\n        }\n        manifest['stems'].append(stem_info)\n        \n        if duration_diff >= 0.5:\n            manifest['verification']['all_stems_aligned'] = False\n            print(f\"WARNING: {stem_name} duration misaligned by {duration_diff:.2f}s\")\n    \n    # Verify master\n    if os.path.exists(master_file):\n        info = sf.info(master_file)\n        manifest['master'] = {\n            'file': os.path.basename(master_file),\n            'duration': info.duration,\n            'sample_rate': info.samplerate,\n            'channels': info.channels,\n            'subtype': info.subtype\n        }\n        \n        # Check master duration matches target\n        if abs(info.duration - TARGET_DURATION) > 1.0:\n            manifest['verification']['master_verified'] = False\n            print(f\"WARNING: Master duration {info.duration:.2f}s differs from target {TARGET_DURATION:.2f}s\")\n    else:\n        manifest['verification']['master_verified'] = False\n    \n    # Save manifest\n    manifest_path = os.path.join(output_dir, 'manifest.json')\n    with open(manifest_path, 'w') as f:\n        json.dump(manifest, f, indent=2)\n    \n    # Copy files to deliverables\n    import shutil\n    for stem_file in stem_files:\n        shutil.copy(stem_file, output_dir)\n    shutil.copy(master_file, output_dir)\n    \n    return manifest_path, manifest\n\nprint(\"\\n=== Creating archive ===\")\nmanifest_path, manifest = create_archive_manifest(processed_stems, master_filepath)\nprint(f\"Archive manifest created: {manifest_path}\")\n\n# Final summary\nprint(\"\\n\" + \"=\"*60)\nprint(\"PRODUCTION COMPLETE\")\nprint(\"=\"*60)\nprint(f\"Target duration: {TARGET_DURATION:.2f}s\")\nprint(f\"Sample rate: {SAMPLE_RATE}Hz\")\nprint(f\"Stems processed: {len(processed_stems)}\")\nprint(f\"All stems aligned: {manifest['verification']['all_stems_aligned']}\")\nprint(f\"Master verified: {manifest['verification']['master_verified']}\")\nprint(f\"Deliverables: .\u002Fdeliverables\u002F\")\nprint(\"=\"*60)\n```\n\n## Troubleshooting Duration Mismatches\n\n### Common Causes\n1. **Different sample rates**: Ensure all stems use the same sample rate\n2. **Incorrect frame calculations**: Verify `frames = int(duration * sample_rate)` calculations\n3. **Off-by-one errors**: Check array indexing and loop boundaries\n4. **Resampling artifacts**: When converting between sample rates, use high-quality resampling\n\n### Strategy Selection Guide\n\n**Use zero-padding when:**\n- Stem is ambient\u002Fpad\u002Fdrone content\n- Short duration mismatch (\u003C 10% of total)\n- Quick turnaround needed\n\n**Use looping when:**\n- Stem is rhythmic (drums, percussion, rhythmic bass)\n- Content has clear loop points\n- Loop length divides evenly into target duration\n\n**Use crossfade extension when:**\n- Stem is melodic (vocals, guitars, synths)\n- Quality is priority over speed\n- Significant duration extension needed\n\n**Use time-stretch when:**\n- Content cannot be looped or padded\n- Pitch must be preserved\n- High-quality processing is available (e.g., librubberband, elasticsearch)\n\n### Verification Checklist\n- [ ] All stems have matching sample rate\n- [ ] All stems within 0.5s of target duration\n- [ ] No clipping in any stem (-1 to 1 range)\n- [ ] Master track duration matches target\n- [ ] Archive manifest generated with verification status\n",{"name":5,"description":7},"main","af1b40a42167d09c30b3a63000aa14ace4c1e229","gdpval_bench\u002Fskills\u002Faudio-track-production-enhanced-enhanced-b8f537","https:\u002F\u002Fgithub.com\u002Fxyliu-cs\u002FOpenSpace-GDPval","https:\u002F\u002Fgithub.com\u002Fxyliu-cs","https:\u002F\u002Fxyliu-cs.github.io","PhD Student in CS, CUHK-Shenzhen.","2026-04-06 20:32:15",{"source":8,"skillName":5,"commands":47,"prompt":57,"zipAvailable":58},[48,51,54],{"tool":49,"command":50},"npx","npx skills add xyliu-cs\u002FOpenSpace-GDPval --skill adaptive-stem-alignment",{"tool":52,"command":53},"bunx","bunx skills add xyliu-cs\u002FOpenSpace-GDPval --skill adaptive-stem-alignment",{"tool":55,"command":56},"pnpm","pnpm dlx skills add xyliu-cs\u002FOpenSpace-GDPval --skill adaptive-stem-alignment","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fxyliu-cs\u002FOpenSpace-GDPval\u002Fblob\u002Fmain\u002Fgdpval_bench\u002Fskills\u002Faudio-track-production-enhanced-enhanced-b8f537\u002FSKILL.md",true,[60],{"path":61,"resourceType":62,"resourceTypeDesc":63,"sizeBytes":64,"sourceHtmlUrl":65},".skill_id","OTHER","其他",61,"https:\u002F\u002Fgithub.com\u002Fxyliu-cs\u002FOpenSpace-GDPval\u002Fblob\u002Fmain\u002Fgdpval_bench\u002Fskills\u002Faudio-track-production-enhanced-enhanced-b8f537\u002F.skill_id",[67,80,88,103,129,149],{"skillNo":68,"name":69,"nameZh":6,"description":70,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":71,"categories":72,"keywords":73,"publishedAt":33},"01M6KG8MF1S664SWBDENYRSCK8","zip-export-deliverable","Ensures codebase deliverables are properly exported as ZIP archives through a dedicated finalization step","https:\u002F\u002Fgithub.com\u002Fxyliu-cs\u002FOpenSpace-GDPval\u002Fblob\u002Fmain\u002Fgdpval_bench\u002Fskills\u002Fzip-export-deliverable\u002FSKILL.md",[],[74,75,76,77,78,79],"zip export deliverable","zip","export","deliverables","codebase","as",{"skillNo":81,"name":82,"nameZh":6,"description":83,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":84,"categories":85,"keywords":86,"publishedAt":33},"01M6KG8GAZWHHEK7VNJDW0ME21","zip-deliverable-finalization","Ensure codebase deliverables are properly packaged as ZIP exports in a dedicated final step","https:\u002F\u002Fgithub.com\u002Fxyliu-cs\u002FOpenSpace-GDPval\u002Fblob\u002Fmain\u002Fgdpval_bench\u002Fskills\u002Fzip-deliverable-finalization\u002FSKILL.md",[],[87,75,77,78,79],"zip deliverable finalization",{"skillNo":89,"name":90,"nameZh":6,"description":91,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":94,"publishedAt":33},"01M6KG8CMQQ1PYMNTSRZ9VS1MD","zero-iteration-failure-analysis","Identify and handle agent failures with 0 iterations as pre-execution system issues","https:\u002F\u002Fgithub.com\u002Fxyliu-cs\u002FOpenSpace-GDPval\u002Fblob\u002Fmain\u002Fgdpval_bench\u002Fskills\u002Fzero-iteration-failure-analysis\u002FSKILL.md",[],[95,96,97,98,99,31,100,101,79,102],"failure analysis","ZeRO","analysis","iteration","zero iteration failure analysis","issues","execution","system",{"skillNo":104,"name":105,"nameZh":6,"description":106,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":107,"categories":108,"keywords":114,"publishedAt":33},"01M6KG86W3PA07FT9W58YHHERM","write-file-fallback-report","Generate professional documents using write_file when primary data sources fail, leveraging embedded domain knowledge instead of external retrieval","https:\u002F\u002Fgithub.com\u002Fxyliu-cs\u002FOpenSpace-GDPval\u002Fblob\u002Fmain\u002Fgdpval_bench\u002Fskills\u002Fwrite-file-fallback-report\u002FSKILL.md",[109],{"categoryNo":110,"categoryName":111,"taxonomyType":112,"taxonomyTypeDesc":113},"01JBSEEDCAT000000000000034","行政与办公人员","PROFESSION","适用职业",[115,116,117,118,119,120,121,122,123,124,125,126,127,128],"fallback","write","file","report","write file fallback report","domain","professional","sources","retrieval","generate","embedded","documents","data","knowledge",{"skillNo":130,"name":131,"nameZh":6,"description":132,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":133,"categories":134,"keywords":138,"publishedAt":33},"01M6KG82GAEY3GG77CMGCK1C2T","fallback-doc-with-delegation","Generate professional documents after tool failures using shell_agent for complex formats or write_file for simple text\u002Fmarkdown","https:\u002F\u002Fgithub.com\u002Fxyliu-cs\u002FOpenSpace-GDPval\u002Fblob\u002Fmain\u002Fgdpval_bench\u002Fskills\u002Fwrite-file-fallback-report-enhanced\u002FSKILL.md",[135],{"categoryNo":136,"categoryName":137,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[139,31,115,140,141,142,126,124,117,143,144,145,116,146,121,147,148],"fallback doc with delegation","doc","delegation","shell","markdown","tool","text","simple","formats","for",{"skillNo":150,"name":151,"nameZh":6,"description":152,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":153,"categories":154,"keywords":156,"publishedAt":33},"01M6KG7WT7GX5NYCGEFHW22NV7","context-anchored-fallback-report","Generate documents with write_file when retrieval tools fail, with explicit guardrails against task context drift","https:\u002F\u002Fgithub.com\u002Fxyliu-cs\u002FOpenSpace-GDPval\u002Fblob\u002Fmain\u002Fgdpval_bench\u002Fskills\u002Fwrite-file-fallback-report-enhanced-4bc5c2\u002FSKILL.md",[155],{"categoryNo":110,"categoryName":111,"taxonomyType":112,"taxonomyTypeDesc":113},[115,118,157,158,124,117,159,160,116,161,162,123,31,163,126],"context","context anchored fallback report","Guardrails","Tools","task","drift","context drift"]