o
    Si0                     @   s|   d dl mZmZ d dlmZmZmZmZmZ d dl	Z
d dlZd dlmZ d dlmZmZ d dlmZ eG dd deZdS )	    )	dataclassfield)CallableListOptionalTupleUnionN)AudioTransform)FastRandomRIRGenerator
convolve1d)Secondsc                   @   s   e Zd ZU dZdZee ed< dZe	ed< dZ
e	ed< edd	 d
Zee ed< dZeeeef  ed< dZeed< dd ZdefddZdejdedejfddZdedee dee deeee f fddZdS )ReverbWithImpulseResponseaF  
    Reverberation effect by convolving with a room impulse response.
    This code is based on Kaldi's wav-reverberate utility:
    https://github.com/kaldi-asr/kaldi/blob/master/src/featbin/wav-reverberate.cc
    If no ``rir_recording`` is provided, we will generate an impulse response using a fast random
    generator (https://arxiv.org/abs/2208.04101).
    The impulse response can possibly be multi-channel, in which case multi-channel reverberated
    audio can be obtained by appropriately setting `rir_channels`. For example, `rir_channels=[0,1]`
    will convolve using the first two channels of the impulse response, generating a stereo
    reverberated audio.
    Note that we enforce the --shift-output option in Kaldi's wav-reverberate utility,
    which means that the output length will be equal to the input length.
    NrirTnormalize_outputF
early_onlyc                   C   s   dgS )Nr    r   r   r   K/home/ubuntu/.local/lib/python3.10/site-packages/lhotse/augmentation/rir.py<lambda>   s    z"ReverbWithImpulseResponse.<lambda>)default_factoryrir_channelsrir_generatorg       ?RIR_SCALING_FACTORc                    s   t  jtr#ddlm}  j }d jv r|d  |d< || _ jd us1 jd us1J d jd urFt fdd jD sFJ d jd ur\t  jtr^t	di  j _d S d S d S )	Nr   )deserialize_item	recordingz1Either `rir` or `rir_generator` must be provided.c                 3   s    | ]	}| j jk V  qd S )N)r   num_channels).0cselfr   r   	<genexpr>4   s    
z:ReverbWithImpulseResponse.__post_init__.<locals>.<genexpr>z'Invalid channel index in `rir_channels`r   )

isinstancer   dictlhotse.serializationr   copyr   allr   r
   )r   r   r   r   r   r   __post_init__$   s$   




z'ReverbWithImpulseResponse.__post_init__returnc                 C   s|   ddl m} ddlm} t| jt| j||fr| j n| j| j	| j
t| j| jd u s2t| jtr5| jn| j ddS )Nr   	Recording)Cut)r   r   r   r   r   )namekwargs)lhotser(   
lhotse.cutr)   type__name__r    r   to_dictr   r   listr   r   r!   )r   r(   r)   r   r   r   r0   ;   s   z!ReverbWithImpulseResponse.to_dictsamplessampling_ratec              	   C   s
  |j \}}|dk}|r| jdust| jdksJ dnt| jdks.t| j|ks.J d| jdu r:| jdd}n'ddlm} t| j|rK| j n| j}|	| j}| j
r]|jdd	}| }|j \}	}
|}|rl|	n|}|	dkry|j|dd
n|}tj||f|jd}t|D ]y}|rdn|}|| ||d|f< tt|| d | }||ddf | j }tt|| t| }t|}||||  ||ddf< | jrtt||ddf d | }|dkr||ddf  t|| 9  < q|S )z
        :param samples: The audio samples to reverberate.
        :param sampling_rate: The sampling rate of the audio samples.
           NzLFor mono input, either provide an RIR explicitly or set rir_channels to [0].zgFor multi-channel input, we only support mono RIR or RIR with the same number of channels as the input.)nsourcer   r'   g?)duration)axis)dtype   )shaper   lenr   r   r,   r(   r    to_cutwith_channelsr   truncate
load_audiorepeatnpzerosr8   rangesumabsr   r   torch
from_numpynumpyargmaxr   sqrt)r   r2   r3   D_inN_ininput_is_monorir_r(   r   D_rirN_rirN_outD_out	augmenteddd_inpower_before_reverbrir_daug_dshift_indexpower_after_reverbr   r   r   __call__N   sR   
	


$
"z"ReverbWithImpulseResponse.__call__offsetr6   c                 C   s   ||fS )z
        This method just returns the original offset and duration since we have
        implemented output shifting which preserves these properties.
        r   )r   r\   r6   r3   r   r   r   reverse_timestamps   s   z,ReverbWithImpulseResponse.reverse_timestamps)r/   
__module____qualname____doc__r   r   r!   __annotations__r   boolr   r   r   r   intr   r   r   r   floatr%   r0   rA   ndarrayr[   r   r   r]   r   r   r   r   r      s4   
 
Mr   )dataclassesr   r   typingr   r   r   r   r   rH   rA   rF   lhotse.augmentation.transformr	   lhotse.augmentation.utilsr
   r   lhotse.utilsr   r   r   r   r   r   <module>   s    