
    xi	                        d Z ddlZddlZddlZddlmZmZmZmZm	Z	m
Z
 ddlmZmZmZ ddlmZ ddlZddlmZmZmZmZ ej.                  j1                  d      duZd2d	Ze G d
 d             Ze G d d             Ze G d d             Ze G d d             Zdeee	f   dee    dededee!   dededede
ee    eeee!   eeef   fdZ" ed      	 	 d3dededee   defd        Z#	 	 	 	 	 	 d4d!ed"e!d#ee    d$ee!   d%e!d&e$d'e$defd(Z%e G d) d*             Z&	 	 	 	 	 	 	 	 d5d+ed,e$dee   d"e!d#ee    d$ee!   d%e!d&e$d'e$de&fd-Z'e G d. d/             Z(	 	 	 	 	 	 	 d6deded0eeee	f      d"e!d#ee    d$ee!   d%e!d&e$d'e$de(fd1Z)y)7z
ACE-Step Inference API Module

This module provides a standardized inference interface for music generation,
designed for third-party integration. It offers both a simplified API and
backward-compatible Gradio UI support.
    N)OptionalUnionListDictAnyTuple)	dataclassfieldasdict)logger)
AudioSavergenerate_uuid_from_paramsnormalize_audioget_lora_weights_hashSPACE_ID   c                     t         r	 ddl}|j                  |       S d S # t        $ r t	        j
                  d       d cY S w xY w)z
    Get the @spaces.GPU decorator if running in HuggingFace Space environment.
    Returns identity decorator if not in Space environment.
    r   Ndurationz0spaces package not found, GPU decorator disabledc                     | S N funcs    0/mnt/workspace/ACE-Step-1.5/acestep/inference.py<lambda>z+_get_spaces_gpu_decorator.<locals>.<lambda>"   s        c                     | S r   r   r   s    r   r   z+_get_spaces_gpu_decorator.<locals>.<lambda>#   s    r   )IS_HUGGINGFACE_SPACEspacesGPUImportErrorr   warning)r   r    s     r   _get_spaces_gpu_decoratorr$      sL    
 	%::x:00   	%NNMN$$	%s   ! !AAc                      e Zd ZU dZdZeed<   dZeed<   dZe	e   ed<   dZ
e	e   ed<   d	Zeed
<   d	Zeed<   d	Zeed<   dZeed<   dZeed<   dZe	e   ed<   d	Zeed<   d	Zeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed<   dZeed <   d!Zeed"<   dZeed#<   dZeed$<   dZ eed%<   dZ!eed&<   d'Z"eed(<   dZ#e	e$e      ed)<   dZ%eed*<   dZ&eed+<   dZ'eed,<   dZ(eed-<   dZ)eed.<   d/Z*eed0<   d1Z+eed2<   d3Z,eed4<   d5Z-eed6<   d7Z.eed8<   dZ/eed9<   dZ0eed:<   dZ1eed;<   dZ2eed<<   dZ3eed=<   dZ4e	e   ed><   d	Z5eed?<   d	Z6eed@<   dZ7e	e   edA<   dZ8eedB<   d	Z9eedC<   d	Z:eedD<   dEe;ee<f   fdFZ=y)GGenerationParamsu  Configuration for music generation parameters.
    
    Attributes:
        # Text Inputs
        caption: A short text prompt describing the desired music (main prompt). < 512 characters
        lyrics: Lyrics for the music. Use "[Instrumental]" for instrumental songs. < 4096 characters
        instrumental: If True, generate instrumental music regardless of lyrics.
        
        # Music Metadata
        bpm: BPM (beats per minute), e.g., 120. Set to None for automatic estimation. 30 ~ 300
        keyscale: Musical key (e.g., "C Major", "Am"). Leave empty for auto-detection. A-G, #/♭, major/minor
        timesignature: Time signature (2 for '2/4', 3 for '3/4', 4 for '4/4', 6 for '6/8'). Leave empty for auto-detection.
        vocal_language: Language code for vocals, e.g., "en", "zh", "ja", or "unknown". see acestep/constants.py:VALID_LANGUAGES
        duration: Target audio length in seconds. If <0 or None, model chooses automatically. 10 ~ 600
        
        # Audio Post-Processing
        enable_normalization: Whether to apply loudness normalization to the output audio.
        normalization_db: Target loudness in dB for normalization (e.g., -1.0 for -1 dBFS peak).
        latent_shift: Additive shift applied to DiT latents before VAE decode (default 0, no shift).
        latent_rescale: Multiplicative rescale applied to DiT latents before VAE decode (default 1.0, no rescale).
        
        # Generation Parameters
        inference_steps: Number of diffusion steps (e.g., 8 for turbo, 32–100 for base model).
        guidance_scale: CFG (classifier-free guidance) strength. Higher means following the prompt more strictly. Only support for non-turbo model.
        seed: Integer seed for reproducibility. -1 means use random seed each time.
        
        # Advanced DiT Parameters
        use_adg: Whether to use Adaptive Dual Guidance (only works for base model).
        cfg_interval_start: Start ratio (0.0–1.0) to apply CFG.
        cfg_interval_end: End ratio (0.0–1.0) to apply CFG.
        shift: Timestep shift factor (default 1.0). When != 1.0, applies t = shift * t / (1 + (shift - 1) * t) to timesteps.
        
        # Task-Specific Parameters
        task_type: Type of generation task. One of: "text2music", "cover", "repaint", "lego", "extract", "complete".
        reference_audio: Path to a reference audio file for style transfer or cover tasks.
        src_audio: Path to a source audio file for audio-to-audio tasks.
        audio_codes: Audio semantic codes as a string (advanced use, for code-control generation).
        repainting_start: For repaint/lego tasks: start time in seconds for region to repaint.
        repainting_end: For repaint/lego tasks: end time in seconds for region to repaint (-1 for until end).
        audio_cover_strength: Strength of reference audio/codes influence (range 0.0–1.0). set smaller (0.2) for style transfer tasks.
        instruction: Optional task instruction prompt. If empty, auto-generated by system.
        
        # 5Hz Language Model Parameters for CoT reasoning
        thinking: If True, enable 5Hz Language Model "Chain-of-Thought" reasoning for semantic/music metadata and codes.
        lm_temperature: Sampling temperature for the LLM (0.0–2.0). Higher = more creative/varied results.
        lm_cfg_scale: Classifier-free guidance scale for the LLM.
        lm_top_k: LLM top-k sampling (0 = disabled).
        lm_top_p: LLM top-p nucleus sampling (1.0 = disabled).
        lm_negative_prompt: Negative prompt to use for LLM (for control).
        use_cot_metas: Whether to let LLM generate music metadata via CoT reasoning.
        use_cot_caption: Whether to let LLM rewrite or format the input caption via CoT reasoning.
        use_cot_language: Whether to let LLM detect vocal language via CoT.
    
text2music	task_typez;Fill the audio semantic mask based on the given conditions:instructionNreference_audio	src_audio audio_codescaptionlyricsFinstrumentalunknownvocal_languagebpmkeyscaletimesignatureg      r   Tenable_normalizationnormalization_db        latent_shift      ?latent_rescale   inference_stepsseedg      @guidance_scaleuse_adgcfg_interval_startcfg_interval_endshiftodeinfer_method	timestepsrepainting_startrepainting_endaudio_cover_strengthcover_noise_strengththinking333333?lm_temperatureg       @lm_cfg_scaler   lm_top_kg?lm_top_pNO USER INPUTlm_negative_promptuse_cot_metasuse_cot_captionuse_cot_lyricsuse_cot_languageuse_constrained_decodingcot_bpmcot_keyscalecot_timesignaturecot_durationcot_vocal_languagecot_caption
cot_lyricsreturnc                     t        |       S z4Convert config to dictionary for JSON serialization.r   selfs    r   to_dictzGenerationParams.to_dict       d|r   )>__name__
__module____qualname____doc__r(   str__annotations__r)   r*   r   r+   r-   r.   r/   r0   boolr2   r3   intr4   r5   r   floatr6   r7   r9   r;   r=   r?   r@   rA   rB   rC   rD   rF   rG   r   rH   rI   rJ   rK   rL   rN   rO   rP   rQ   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r   r   rf   r   r   r   r&   r&   &   s8   4l "Is!TKT &*OXc])#Ix}# K GSFCL$ $NC#C#HcM3He "&$%"e" L%NE OSD#NNEGT ##!e!E5L# (,IxU$+!e!NE"%%%"%%% Hd NE L%HcHe--M4 OT  ND !d!%)d)!GXc]!L#s$(L(5/(''KJc3h r   r&   c                       e Zd ZU dZdZeed<   dZeed<   dZ	eed<   dZ
eee      ed	<   d
Zeed<   dZeed<   dZeed<   deeef   fdZy)GenerationConfiga:  Configuration for music generation.
    
    Attributes:
        batch_size: Number of audio samples to generate
        allow_lm_batch: Whether to allow batch processing in LM
        use_random_seed: Whether to use random seed
        seeds: Seed(s) for batch generation. Can be:
            - None: Use random seeds (when use_random_seed=True) or params.seed (when use_random_seed=False)
            - List[int]: List of seeds, will be padded with random seeds if fewer than batch_size
            - int: Single seed value (will be converted to list and padded)
        lm_batch_chunk_size: Batch chunk size for LM processing
        constrained_decoding_debug: Whether to enable constrained decoding debug
        audio_format: Output audio format, one of "mp3", "wav", "flac", "wav32", "opus", "aac". Default: "flac"
       
batch_sizeFallow_lm_batchTuse_random_seedNseedsr<   lm_batch_chunk_sizeconstrained_decoding_debugflacaudio_formatr`   c                     t        |       S rb   rc   rd   s    r   rf   zGenerationConfig.to_dict   rg   r   )rh   ri   rj   rk   rt   ro   rm   ru   rn   rv   rw   r   r   rx   ry   r{   rl   r   r   rf   r   r   r   rr   rr      sn     J ND  OT !%E8DI%  ',,L#c3h r   rr   c                       e Zd ZU dZ ee      Zeee	e
f      ed<   dZe	ed<    ee      Zee	e
f   ed<   dZeed<   d	Zee	   ed
<   dee	e
f   fdZy	)GenerationResultaj  Result of music generation.
    
    Attributes:
        # Audio Outputs
        audios: List of audio dictionaries with paths, keys, params
        status_message: Status message from generation
        extra_outputs: Extra outputs from generation
        success: Whether generation completed successfully
        error: Error message if generation failed
    )default_factoryaudiosr,   status_messageextra_outputsTsuccessNerrorr`   c                     t        |       S z4Convert result to dictionary for JSON serialization.rc   rd   s    r   rf   zGenerationResult.to_dict   rg   r   )rh   ri   rj   rk   r
   listr   r   r   rl   r   rm   r   dictr   r   rn   r   r   rf   r   r   r   r~   r~      sr    	 $)#>FDc3h >NC$)$$?M4S>?GTE8C=c3h r   r~   c                       e Zd ZU dZdZeed<   dZeed<   dZe	e
   ed<   dZe	e   ed<   dZeed<   dZeed	<   dZeed
<   dZeed<   dZeed<   dZe	e   ed<   deeef   fdZy)UnderstandResulta  Result of music understanding from audio codes.
    
    Attributes:
        # Metadata Fields
        caption: Generated caption describing the music
        lyrics: Generated or extracted lyrics
        bpm: Beats per minute (None if not detected)
        duration: Duration in seconds (None if not detected)
        keyscale: Musical key (e.g., "C Major")
        language: Vocal language code (e.g., "en", "zh")
        timesignature: Time signature (e.g., "4/4")
        
        # Status
        status_message: Status message from understanding
        success: Whether understanding completed successfully
        error: Error message if understanding failed
    r,   r.   r/   Nr3   r   r4   languager5   r   Tr   r   r`   c                     t        |       S r   rc   rd   s    r   rf   zUnderstandResult.to_dict  rg   r   rh   ri   rj   rk   r.   rl   rm   r/   r3   r   ro   r   rp   r4   r   r5   r   r   rn   r   r   r   rf   r   r   r   r   r      s    $ GSFCC# $Hhuo$HcHcM3 NCGTE8C=c3h r   r   metadatar3   	key_scaletime_signatureaudio_durationr2   r.   r/   r`   c                    |2| j                  d      r!| j                  d      }|dvr	 t        |      }|s:| j                  d      r)| j                  d| j                  dd            }	|	dk7  r|	}|s:| j                  d      r)| j                  d| j                  dd            }
|
dk7  r|
}||d	k  r"| j                  d
d      }|dvr	 t	        |      }|s"| j                  d      r| j                  d      }|s"| j                  d      r| j                  d      }|s"| j                  d      r| j                  d      }|||||||fS # t        t        f$ r Y (w xY w# t        t        f$ r Y w xY w)z>Update metadata fields from LM output if not provided by user.r3   )N/Ar,   r4   r   r,   r   r5   r   r   r   r>   r2   r.   r/   )getro   
ValueError	TypeErrorrp   )r   r3   r   r   r   r2   r.   r/   	bpm_valuekey_scale_valuetime_signature_valueaudio_duration_values               r   _update_metadata_from_lmr     s~    {x||E*LL'	K')n j1",,z8<<R3PQe#'Ihll?;'||OX\\JZ\^=_`5(1N1!4'||J;{2!&';!< hll+;<!&67x||I.,,y)hll8,h'	>>>7TZZZ7 	* $ 	* s#   E E! EE!E32E3r   paramsconfigsave_dirc                 :   	 |j                   }d}g }dddd}	|j                  }
|j                  }|j                  }|j                  }|j
                  }|j                  }|j                  }t        |j                   xr# t        |j                         j                               }| }|j                  |j                  nd}d}|j                  t        |j                  t              r;t        |j                        dkD  r#dj!                  d |j                  D              }n/t        |j                  t"              rt        |j                        }| j%                  |||j&                        \  }}d	d
h}|j(                  xs |j*                  xs |j,                  }|j.                  xs |xr" |duxr |j0                  xr |j2                  |v}g }|j2                  |v r#t5        j6                  d|j2                   d       t5        j6                  d|j.                   d|j(                   d|j*                   d|j,                   d| d|r|j0                  nd d|        |r|j8                  r|j8                  dk(  rdnt#        |j8                        }|j:                  r|j:                  dk\  rdn|j:                  }i }|
	 t=        |
      }|dkD  rt#        |      |d<   |r7|j                         r'|j                         }|jC                         dvr||d<   |r7|j                         r'|j                         } | jC                         dvr| |d<   |	 t=        |      }!|!dkD  rt#        |!      |d<   |r|nd}"|r|j.                  rdnd}#|jD                  dkD  rt#        |jD                        n|}$tG        jH                  ||$z        }%g }&g }'tK        |%      D ]^  }(|(|$z  })tM        |)|$z   |      }*|*|)z
  }+|)t        |      k  r||)|* nd},t5        j6                  d|(dz    d|% d|# d |+ d!|, d"       |jO                  |j
                  xs d|j                  xs d|#|jP                  |jR                  |jT                  ||||"|j(                  |j*                  |j,                  |jV                  |jX                  |+|,|#      }-|-j[                  d$d      s;|-j[                  d%d&      }.|j]                  d'|.        t_        g d(|. i d|.)      c S |+dkD  rG|-j[                  d*g       }/|-j[                  d+g       }0|&ja                  |/       |'ja                  |0       nF|-j[                  d*i       }1|-j[                  d+d      }2|&j]                  |1       |'j]                  |2       |-j[                  d,i       }3|3j[                  d-i       }4|4sdD ]  }5|5|4v s|	|5xx   |4|5   z  cc<    d.j!                  |4jc                         D 67cg c]  \  }6}7|6 d/|7d0d1 c}7}6      }8|j]                  d2|(dz    d/|8        a |&r|&d   nd}|'}|#dk(  r|dkD  r|'}n|'r|'d   nd}n|j                   }|rte        ||
||||||3      \  }
}}}}9}:};|j                  s|
|_3        |j                  s||_4        |j                  s||_5        |j                  s||_6        |j                  s|9|_7        |j
                  s|:|_8        |j                  s|;|_9        |j(                  r|j[                  d4|      }|j*                  r|j[                  d5|      }|j2                  d6v rv|j
                  xs |}|j                  |j                  n|}t5        j6                  d7|j
                   d8|j                   d9       t5        j6                  d:| d;| d9        | jt                  d}i d<|d=|d|
d>|d?|d5|d@|jv                  dA|jx                  dB|j&                  dC|dD|jz                  dE|dF|j                  |j                  nddG|j2                  dHk(  rdn|j|                  dI|dJ|j~                  dK|j                  dL|j                  dM|j                  dN|j                  dO|j2                  dP|j                  dQ|j                  dR|j                  dS|j                  dT|j                  dU|j                  dV|j                  dW|j                  dX|}-|-j[                  d$d      s/t_        g |-j[                  dYd      i d|-j[                  d%      )      S |-j[                  dZg       }<|-j[                  dYd      }=|-j[                  d,i       }>|}?|j                         }@|j                  r|j                  nd[}At        |A\      }B|t        j                  |d]^       g }Ct        |<      D ]p  \  }D}E@j                         }F|Dt        |?      k  r|?D   ndFdC<   |r3Dt        |      k  r%|D   }G|Grt        G      j                         rGFd+<   | j                  Fd_<   | j                  |Fd`<   | j                  |Fda<   t        |       |Fdb<   Ej[                  dc      }H|Ej[                  ddde      }I|j                  r|j                  dk  r	 t        j                  t        j                  H            j                         }Jt5        j6                  dfD dg|Jdhdi|j                   dj       t        |H|j                        }Ht        j                  t        j                  |H            j                         }Kt5        j6                  df|D dk|Kdh       Dt        |?      k  r|?D   n|?r|?d   ndm}M|rDt        |      k  r|D   n|}Nt        |Nt              rDt        N      k  rND   nd}Nt        F      }Od}PHG|E	 Adnk(  rdonA}Qt        j                  j!                  |O dp|Q       }RBj                  H|RIAd]q      }PPxs dHOIFds}SCj]                  |S       s |>j                         }T||Tdt<   i }U|r"|	r |	jc                         D ]  \  }5}V|VUdu|5 <    |>j[                  d-i       }W|Wr Wjc                         D ]  \  }5}V|VUdv|5 <    Ur,Uj[                  dwd      }X|Uj[                  dxd      }Y|X|Yz   |Udy<   UTd-<   |rdzj!                  |      dzz   |=z   }=n|=}=t_        C|=Td]d)      S # t>        t@        f$ r Y 
dw xY w# t>        t@        f$ r Y 	w xY wc c}7}6w # t        $ r#}Lt5        j                  dlL        Y d}L~Ld}L~Lww xY w# t        $ r%}Lt5        j                  drL        d}PY d}L~Lxd}L~Lww xY w# t        $ rD}Lt5        j                  d{       t_        g d|t        L       i dt        |L      )      cY d}L~LS d}L~Lww xY w)~a  Generate music using ACE-Step model with optional LM reasoning.
    
    Args:
        dit_handler: Initialized DiT model handler (AceStepHandler instance)
        llm_handler: Initialized LLM handler (LLMHandler instance)
        params: Generation parameters (GenerationParams instance)
        config: Generation configuration (GenerationConfig instance)
        
    Returns:
        GenerationResult with generated audio files and metadata
    Nr8   )phase1_timephase2_time
total_time   r,   r   ,c              3   2   K   | ]  }t        |        y wr   )rl   ).0ss     r   	<genexpr>z!generate_music.<locals>.<genexpr>x  s     .L|!s1v|s   coverrepaintzSkipping LM for task_type='z' - using DiT directlyz.[generate_music] LLM usage decision: thinking=z, use_cot_caption=z, use_cot_language=z, use_cot_metas=z, need_lm_for_cot=z, llm_initialized=Fz	, use_lm=r:   r3   )zn/ar,   r4   r5   r   llm_ditditz	LM chunk /z (infer_type=z	) (size: z	, seeds: ))r.   r/   
infer_typetemperature	cfg_scalenegative_prompttop_ktop_ptarget_durationuser_metadatarU   rW   rT   rX   ry   rt   rw   progressr   r   zUnknown LM erroru   ❌ LM Error: u   ❌ LM generation failed: )r   r   r   r   r   r   r-   r   
time_costsz, z: z.2fr   u   ✅ LM chunk )r   r3   r   r   r   r2   r.   r/   r.   r2   )r   r   z;[generate_music] Repaint/Cover task: using params.caption='z', params.lyrics=''z2[generate_music] Final inputs: dit_input_caption='z', dit_input_lyrics='captionsr/   r   r   r=   r@   rv   r?   r*   r   rt   r+   r'   audio_code_stringrH   rI   r)   rJ   rK   r(   rA   rB   rC   rD   rF   rG   r9   r;   r   r   r   rz   )default_formatT)exist_oklora_loadeduse_lora
lora_scalelora_weights_hashtensorsample_ratei  z[Normalization] Audio z BEFORE: Peak=z.4fz	, Target=dBz AFTER: Peak=zNormalization failed: r>   wav32wav.)r   formatchannels_firstz,[generate_music] Failed to save audio file: )pathr   keyr   r   lm_metadatalm_dit_lm_total_timedit_total_time_costpipeline_total_time
zMusic generation failedError: r   )dr-   r3   r4   r5   r   r.   r2   r/   rn   rl   striprt   rw   
isinstancer   lenjoinro   prepare_seedsrv   rU   rW   rT   rL   llm_initializedr(   r   inforP   rQ   rp   r   r   lowerrx   mathceilrangemingenerate_with_stop_conditionrN   rO   rS   rX   ry   r   appendr~   extenditemsr   rY   rZ   r[   r\   r]   r^   r_   generate_musicr=   r@   r*   r+   rH   rI   r)   rJ   rK   rA   rB   rC   rD   rF   rG   r9   r;   rf   r{   r   osmakedirs	enumeratecopyr   r   r   r   r6   r7   torchmaxabsitemr   	Exceptionr   r   r   
save_audio	exception)Zdit_handlerllm_handlerr   r   r   r   audio_code_string_to_uselm_generated_metadatalm_generated_audio_codes_listlm_total_time_costsr3   r   r   r   dit_input_captiondit_input_vocal_languagedit_input_lyricsuser_provided_audio_codesneed_audio_codesactual_batch_sizeseed_for_generationactual_seed_list_skip_lm_tasksneed_lm_for_cotuse_lm	lm_statustop_k_valuetop_p_valuer   r   key_scale_cleantime_sig_cleanduration_valueuser_metadata_to_passr   max_inference_batch_size
num_chunksall_metadata_listall_audio_codes_list	chunk_idxchunk_start	chunk_end
chunk_sizechunk_seedsresult	error_msgmetadata_listaudio_codes_listr   r-   lm_extralm_chunk_time_costsr   kvtime_strr2   r.   r/   
dit_audiosr   dit_extra_outputs	seed_listbase_params_dictr{   audio_saverr   idx	dit_audioaudio_paramslm_codeaudio_tensorr   peak_before
peak_aftere
batch_seedaudio_code_str	audio_key
audio_pathfile_ext
audio_file
audio_dictr   unified_time_costsvaluedit_time_costslm_total	dit_totalsZ                                                                                             r   r   r   5  s   (
#)#5#5  $(*%
 jjOO	--"NN#)#8#8 !== %)););)_FDVDV@W@]@]@_$`!  98 281B1B1NF--TU
 ! <<#&,,-#fll2Ca2G&)hh.Lv||.L&L#FLL#. '*&,,&7# *778IK^`f`v`vw!
 !), !00cF4K4KcvOcOc//4_  \+T:Q  \VaVqVq  \v|  wG  wG  O\  w\	},KK5f6F6F5GG]^_DV__DU V&&,&<&<%==PQWQhQhPi j$$*$8$8#99KOK\ ]&EPk&A&AV[%\\eflemo 	p
 &,ooA9M$SVW]WfWfSgK&,ooC9O$U[UdUdK M %c
I 1}/29~e, Y__."+//"3"((*+=0?M*-."6"6"8!/!5!5!7!'')<5CM/2)%*>%:N%)474Gj1 6CM!
 '76??PUJ KQJdJdghJhs6+E+E'Fn$#47O#OPJ "#% ":.	'*BB.F FHYZ	&4
ITWZ[kWlIl.{9Ervi	!}Aj\zl [&&0\;-qJ K %AA"NN0b!==.B) & 5 5$11$*$=$=%%$2"7$*$:$:%+%<%<"("6"6-3-L-L/5/P/P)%%% B , zz)U3 &

74F GI$$~i[%AB+!)CI;'O&( %'  >$*JJz2$>M'-zz-'D$%,,];(//0@A%zz*b9H"(**]B"?K%,,X6(//< "::or:&.ll<&D#&K"55/48KC8PP4  L  $yyGZG`G`Gb)cGbtq!QCr!C*:Gb)cdH$$}Yq[MH:%NOI /L =N$5a$8SW!,@) Y&$q(/C,J^/CA/Fdf, ,2+=+=( %bz2'#1#1#;-+c-_YPWY_ zz%(FN*3F'++/=F,*8F',,0>F-~~)0F&}}(.F% %%$9$=$=iIZ$[!&&+@+D+DEUWo+p( 33 & C2C060Iv}}O_KKUV\VdVdUeewx~  yF  yF  xG  GH  I  JKKLM^L__t  vF  uG  GH  I  J ,++ !
&!
#!
 !
  	!

 *!
 4!
 #22!
 "00!
 #22!
 %!
 #22!
 *!
 -3,=,=,Iv((q!
  %..,>dFDTDT!!
" 7#!
$ $44%!
& "00'!
( **)!
* "(!<!<+!
, "(!<!<-!
. &&/!
0 NN1!
2  &883!
4 $445!
6 ,,7!
8  ,,9!
: &&;!
<  ,,=!
> "00?!
@ A!
H zz)U+#%zz*:B? jj)  ZZ"-
$4b9"JJ; %	 ">>+ /5.A.Av**v = KK40 '
3NC+002L 693y>5I9S>tL  -s;X7Y1Y7<s7|11329L/ +6*A*AL''2';';L$)4)?)?L&0Ek0RL,- %==2L#--u=K **v/F/F#/M@#(99UYY|-D#E#J#J#L[[[#9#n[Y\L]]fgmg~g~f  @B  "C  D$3L&BYBY$Z\"'))EIIl,C"D"I"I"KZ[[#9#mJWZK[!\] ,/Y+?3U^Yq\dfJ .#<Y8Z2Z ;3?ay .$/8;c.>Q8Q!4WY1,?I J'H,@$(4(?u\H!#h9+Qxj8Q!RJ!,!7!78BDO?KGK	 "8 "MJ #(b& *&J MM*%[ 4` *..0'<m$   )1779
U27"S;/ : +..|R@,224
U38"T#<0 5 )--osCH*../DcJI8@98L45 '9l#!YYy1D8>IN+N)'
 	
g
 #I. $ #I. h *dF " @\\$:1#">??@8 ! $LL#OPQs!ST!#J$l  
23$SVH-a&
 	

s   Kw t; )A4w u <Fw B8w 	w 0w u'Mw %E1w Cu-A)w 	AvC-w ;u
w uw u$ w #u$$	w -	v6vw vw 	w
%w?w w

w 	x9xxxr-   r   r   r   repetition_penaltyrX   ry   c                    | j                   st        ddd      S |r|j                         sd}	 | j                  |||||||      \  }}	|st        |	xs dd|	xs d      S |j	                  d	d
      }
|j	                  dd
      }|j	                  dd
      }|j	                  d|j	                  dd
            }|j	                  dd
      }d}|j	                  d      }||dk7  r|d
k7  r	 t        |      }d}|j	                  d      }||dk7  r|d
k7  r	 t        |      }|dk(  rd
}|dk(  rd
}|dk(  rd
}t        |
|||||||	dd
      S # t        t        f$ r Y fw xY w# t        t        f$ r Y Pw xY w# t        $ rB}t        j                  d       t        dt        |       dt        |            cY d}~S d}~ww xY w)a  Understand music from audio codes using the 5Hz Language Model.
    
    This function analyzes audio semantic codes and generates metadata about the music,
    including caption, lyrics, BPM, duration, key scale, language, and time signature.
    
    If audio_codes is empty or "NO USER INPUT", the LM will generate a sample example
    instead of analyzing existing codes.
    
    Note: cfg_scale and negative_prompt are not supported in understand mode.
    
    Args:
        llm_handler: Initialized LLM handler (LLMHandler instance)
        audio_codes: String of audio code tokens (e.g., "<|audio_code_123|><|audio_code_456|>...")
                     Use empty string or "NO USER INPUT" to generate a sample example.
        temperature: Sampling temperature for generation (0.0-2.0). Higher = more creative.
        top_k: Top-K sampling (None or 0 = disabled)
        top_p: Top-P (nucleus) sampling (None or 1.0 = disabled)
        repetition_penalty: Repetition penalty (1.0 = no penalty)
        use_constrained_decoding: Whether to use FSM-based constrained decoding for metadata
        constrained_decoding_debug: Whether to enable debug logging for constrained decoding
        
    Returns:
        UnderstandResult with parsed metadata fields and status
        
    Example:
        >>> result = understand_music(llm_handler, audio_codes="<|audio_code_123|>...")
        >>> if result.success:
        ...     print(f"Caption: {result.caption}")
        ...     print(f"BPM: {result.bpm}")
        ...     print(f"Lyrics: {result.lyrics}")
    35Hz LM not initialized. Please initialize it first.FLLM not initializedr   r   r   rR   )r-   r   r   r   r4  rX   ry   z Failed to understand audio codesEmpty metadata returnedr.   r,   r/   r4   r   r2   r5   Nr3   r   r   T
r.   r/   r3   r   r4   r   r5   r   r   r   zMusic understanding failedr   )r   r   r   understand_audio_from_codesr   ro   r   r   rp   r   r   r   rl   )r   r-   r   r   r   r4  rX   ry   r   statusr.   r/   r4   r   r5   r3   r   r   r  r'  s                       r   understand_musicr=    s-   T &&P'
 	
 k//1%H
&BB##1%='A C 
& #%K)K9 9  ,,y"-h+<<
B/<<
HLL9I2,NO _b9 LL'	 Y%%7IO)n
 !j1%.E*AnXZFZ 0
 uHuHE!M'!
 	
) 	*  	* 0  
56$SVH-a&
 	

sl   2E7 #B	E7 -E 8E7 E" #)E7 EE7 EE7 "E41E7 3E44E7 7	G 7F=7G=Gc                       e Zd ZU dZdZeed<   dZeed<   dZe	e
   ed<   dZe	e   ed<   dZeed<   dZeed	<   dZeed
<   dZeed<   dZeed<   dZeed<   dZe	e   ed<   deeef   fdZy)CreateSampleResulta  Result of creating a music sample from a natural language query.
    
    This is used by the "Simple Mode" / "Inspiration Mode" feature where users
    provide a natural language description and the LLM generates a complete
    sample with caption, lyrics, and metadata.
    
    Attributes:
        # Metadata Fields
        caption: Generated detailed music description/caption
        lyrics: Generated lyrics (or "[Instrumental]" for instrumental music)
        bpm: Beats per minute (None if not generated)
        duration: Duration in seconds (None if not generated)
        keyscale: Musical key (e.g., "C Major")
        language: Vocal language code (e.g., "en", "zh")
        timesignature: Time signature (e.g., "4")
        instrumental: Whether this is an instrumental piece
        
        # Status
        status_message: Status message from sample creation
        success: Whether sample creation completed successfully
        error: Error message if sample creation failed
    r,   r.   r/   Nr3   r   r4   r   r5   Fr0   r   Tr   r   r`   c                     t        |       S r   rc   rd   s    r   rf   zCreateSampleResult.to_dict  rg   r   )rh   ri   rj   rk   r.   rl   rm   r/   r3   r   ro   r   rp   r4   r   r5   r0   rn   r   r   r   r   r   rf   r   r   r   r?  r?    s    . GSFCC# $Hhuo$HcHcM3L$ NCGTE8C=c3h r   r?  queryr0   c
                    | j                   st        ddd      S 	 | j                  |||||||||		      \  }
}|
st        |xs dd|xs d      S |
j                  dd	      }|
j                  d
d	      }|
j                  dd	      }|
j                  d|
j                  dd	            }|
j                  dd	      }|
j                  d|      }d}|
j                  d      }||dk7  r|d	k7  r	 t	        |      }d}|
j                  d      }||dk7  r|d	k7  r	 t        |      }|dk(  rd	}|dk(  rd	}|dk(  rd	}t        |||||||||dd      S # t
        t        f$ r Y gw xY w# t
        t        f$ r Y Qw xY w# t        $ rB}t        j                  d       t        dt        |       dt        |            cY d}~S d}~ww xY w)a   Create a music sample from a natural language query using the 5Hz Language Model.
    
    This is the "Simple Mode" / "Inspiration Mode" feature that takes a user's natural
    language description of music and generates a complete sample including:
    - Detailed caption/description
    - Lyrics (unless instrumental)
    - Metadata (BPM, duration, key, language, time signature)
    
    Note: cfg_scale and negative_prompt are not supported in create_sample mode.
    
    Args:
        llm_handler: Initialized LLM handler (LLMHandler instance)
        query: User's natural language music description (e.g., "a soft Bengali love song")
        instrumental: Whether to generate instrumental music (no vocals)
        vocal_language: Allowed vocal language for constrained decoding (e.g., "en", "zh").
                       If provided, the model will be constrained to generate lyrics in this language.
                       If None or "unknown", no language constraint is applied.
        temperature: Sampling temperature for generation (0.0-2.0). Higher = more creative.
        top_k: Top-K sampling (None or 0 = disabled)
        top_p: Top-P (nucleus) sampling (None or 1.0 = disabled)
        repetition_penalty: Repetition penalty (1.0 = no penalty)
        use_constrained_decoding: Whether to use FSM-based constrained decoding
        constrained_decoding_debug: Whether to enable debug logging
        
    Returns:
        CreateSampleResult with generated sample fields and status
        
    Example:
        >>> result = create_sample(llm_handler, "a soft Bengali love song for a quiet evening", vocal_language="bn")
        >>> if result.success:
        ...     print(f"Caption: {result.caption}")
        ...     print(f"Lyrics: {result.lyrics}")
        ...     print(f"BPM: {result.bpm}")
    r6  Fr7  r8  )	rA  r0   r2   r   r   r   r4  rX   ry   zFailed to create sampler9  r.   r,   r/   r4   r   r2   r5   r0   Nr3   r   r   T)r.   r/   r3   r   r4   r   r5   r0   r   r   r   zSample creation failedr   )r   r?  create_sample_from_queryr   ro   r   r   rp   r   r   r   rl   )r   rA  r0   r2   r   r   r   r4  rX   ry   r   r<  r.   r/   r4   r   r5   is_instrumentalr3   r   r   r  r'  s                          r   create_samplerE    s1   ^ &&!P'
 	
L
&??%)#1%='A @ 

& %%B)B9 9  ,,y"-h+<<
B/<<
HLL9I2,NO _b9",,~|D LL'	 Y%%7IO)n
 !j1%.E*AnXZFZ 0
 uHuHE!M!'(!
 	
) 	*  	* 2  
12!$SVH-a&
 	

sl   4E8 BE8 -E 8E8 E# #*E8 E E8 E  E8 #E52E8 4E55E8 8	G7F>8G>Gc                       e Zd ZU dZdZeed<   dZeed<   dZe	e
   ed<   dZe	e   ed<   dZeed<   dZeed	<   dZeed
<   dZeed<   dZeed<   dZe	e   ed<   deeef   fdZy)FormatSampleResultai  Result of formatting user-provided caption and lyrics.
    
    This is used by the "Format" feature where users provide caption and lyrics,
    and the LLM formats them into structured music metadata and an enhanced description.
    
    Attributes:
        # Metadata Fields
        caption: Enhanced/formatted music description/caption
        lyrics: Formatted lyrics (may be same as input or reformatted)
        bpm: Beats per minute (None if not detected)
        duration: Duration in seconds (None if not detected)
        keyscale: Musical key (e.g., "C Major")
        language: Vocal language code (e.g., "en", "zh")
        timesignature: Time signature (e.g., "4")
        
        # Status
        status_message: Status message from formatting
        success: Whether formatting completed successfully
        error: Error message if formatting failed
    r,   r.   r/   Nr3   r   r4   r   r5   r   Tr   r   r`   c                     t        |       S r   rc   rd   s    r   rf   zFormatSampleResult.to_dict`  rg   r   r   r   r   r   rG  rG  <  s    * GSFCC# $Hhuo$HcHcM3 NCGTE8C=c3h r   rG  r   c
                 f   | j                   st        ddd      S 	 | j                  |||||||||		      \  }
}|
st        |xs dd|xs d      S |
j                  dd	      }|
j                  d
|      }|
j                  dd	      }|
j                  d|
j                  dd	            }|
j                  dd	      }d}|
j                  d      }||dk7  r|d	k7  r	 t	        |      }d}|
j                  d      }||dk7  r|d	k7  r	 t        |      }|dk(  rd	}|dk(  rd	}|dk(  rd	}t        ||||||||dd
      S # t
        t        f$ r Y fw xY w# t
        t        f$ r Y Pw xY w# t        $ rB}t        j                  d       t        dt        |       dt        |            cY d}~S d}~ww xY w)a  Format user-provided caption and lyrics using the 5Hz Language Model.
    
    This function takes user input (caption and lyrics) and generates structured
    music metadata including an enhanced caption, BPM, duration, key, language,
    and time signature.
    
    If user_metadata is provided, those values will be used to constrain the
    decoding, ensuring the output matches user-specified values.
    
    Note: cfg_scale and negative_prompt are not supported in format mode.
    
    Args:
        llm_handler: Initialized LLM handler (LLMHandler instance)
        caption: User's caption/description (e.g., "Latin pop, reggaeton")
        lyrics: User's lyrics with structure tags
        user_metadata: Optional dict with user-provided metadata to constrain decoding.
                      Supported keys: bpm, duration, keyscale, timesignature, language
        temperature: Sampling temperature for generation (0.0-2.0). Higher = more creative.
        top_k: Top-K sampling (None or 0 = disabled)
        top_p: Top-P (nucleus) sampling (None or 1.0 = disabled)
        repetition_penalty: Repetition penalty (1.0 = no penalty)
        use_constrained_decoding: Whether to use FSM-based constrained decoding for metadata
        constrained_decoding_debug: Whether to enable debug logging for constrained decoding
        
    Returns:
        FormatSampleResult with formatted metadata fields and status
        
    Example:
        >>> result = format_sample(llm_handler, "Latin pop, reggaeton", "[Verse 1]\nHola mundo...")
        >>> if result.success:
        ...     print(f"Caption: {result.caption}")
        ...     print(f"BPM: {result.bpm}")
        ...     print(f"Lyrics: {result.lyrics}")
    r6  Fr7  r8  )	r.   r/   r   r   r   r   r4  rX   ry   zFailed to format inputr9  r.   r,   r/   r4   r   r2   r5   Nr3   r   r   Tr:  zFormat sample failedr   )r   rG  format_sample_from_inputr   ro   r   r   rp   r   r   r   rl   )r   r.   r/   r   r   r   r   r4  rX   ry   r   r<  result_captionresult_lyricsr4   r   r5   r3   r   r   r  r'  s                         r   format_samplerM  e  s   ^ &&!P'
 	
J
&??'#1%='A @ 

& %%A)A9 9  "i4 Xv6<<
B/<<
HLL9I2,NO _b9 LL'	 Y%%7IO)n
 !j1%.E*AnXZFZ 0
 uHuHE!M!" '!
 	
) 	*  	* 0  
/0!$SVH-a&
 	

sl   4E% B	E% D; &E% E )E% ;E
E% EE% E"E% !E""E% %	F0.7F+%F0+F0)r   )NN)rM   NNr:   TF)FNrM   NNr:   TF)NrM   NNr:   TF)*rk   r   r   tempfiletypingr   r   r   r   r   r   dataclassesr	   r
   r   logurur   r   acestep.audio_utilsr   r   r   r   environr   r   r$   r&   rr   r~   r   rl   ro   rp   r   r   rn   r=  r?  rE  rG  rM  r   r   r   <module>rT     s    	  : : 0 0   n m zz~~j1=  ~ ~ ~B   8   4 " " "J,[38n,[	#,[ ,[ 	,[
 UO,[ ,[ ,[ ,[ 8C=#sHUOS#sBC,[^ C( #R
 R
 	R

 smR
 R
 )R
p ! #%)',}
}
 }
 C=	}

 E?}
 }
 #}
 !%}
 }
@ ( ( (\ $(! #%)',B
B
 B
 SM	B

 B
 C=B
 E?B
 B
 #B
 !%B
 B
J % % %X /3! #%)',@
@
 @
 DcN+	@

 @
 C=@
 E?@
 @
 #@
 !%@
 @
r   