o
    pi                     @   s   d dl mZ d dlZd dlmZ d dlmZ d dlmZ 	ddej	dej	de
fd	d
Zddej	de
fddZeddede
fddZG dd dej	Zejddedede
fddZdS )    )singledispatchN)BaseWaveformTransform)Modelinputaugmentationmodulewhenc                    s   t | ||d t|dst |_t |_||jv r t||d  |j|< |dkr5 fdd}||}n|dkrD fdd}|	|}||j|< d	S )
uJ  Register augmentation

    Parameters
    ----------
    augmentation : nn.Module
        Augmentation module.
    module : nn.Module
        Module whose input or output should be augmented.
    when : {'input', 'output'}
        Whether to apply augmentation on the input or the output.
        Defaults to 'input'.

    Usage
    -----

    class Net(nn.Module):
        def __init__(self):
            super().__init__()
            self.spectogram = Spectrogram()
            self.other_layers = nn.Identity()

        def forward(self, waveforms):
            spectrogram = self.spectrogram(waveforms)
            return self.other_layers = other_layers

    net = Net()

    class AddNoise(nn.Module):
        def forward(self, waveforms):
            if not self.training:
                return waveforms

            augmented_waveforms = ...
            return augmented_waveforms

    # AddNoise will be automatically applied to `net` input
    register_augmentation(AddNoise(), net, when='input')

    class SpecAugment(nn.Module):
        def forward(self, spectrograms):
            if not self.training:
                return spectrograms

            augmented_spectrograms = ...
            return augmented_spectrograms

    # SpecAugment will be automatically applied to `net.spectrogram` output
    register_augmentation(SpecAugment(), net.spectrogram, when='output')

    # deactivate augmentations
    net.eval()  # or net.train(mode=False)

    # reactivate augmentations
    net.train()

    # unregister "AddNoise" augmentation
    unregister_augmentation(net, when='input')

    r   __augmentationr   c                    s    | S N )augmented_moduler   wrapped_augmentationr   X/home/ubuntu/.local/lib/python3.10/site-packages/pyannote/audio/augmentation/registry.py
input_hooko      z)register_augmentation.<locals>.input_hookoutputc                    s    |S r   r   )r   r   r   r   r   r   output_hookv   r   z*register_augmentation.<locals>.output_hookN)
wrap_augmentationhasattrnn
ModuleDictr
   dict__augmentation_handleunregister_augmentationregister_forward_pre_hookregister_forward_hook)r   r   r   r   handler   r   r   r   register_augmentation    s   A




r   c                 C   sD   t | dr
|| jvrtd| d| j|= | j|}|  dS )ad  Unregister augmentation

    Parameters
    ----------
    module : nn.Module
        Module whose augmentation should be removed.
    when : {'input', 'output'}
        Whether to remove augmentation of the input or the output.
        Defaults to 'input'.

    Raises
    ------
    ValueError if module has no corresponding registered augmentation.
    r
   zModule has no registered u    augmentation.N)r   r
   
ValueErrorr   popremove)r   r   r   r   r   r   r   ~   s
   r   modelc                 C   s   | S r   r   r   r#   r   r   r   r   r      s   r   c                       sD   e Zd Z	ddededef fddZdejdejfd	d
Z	  Z
S ),TorchAudiomentationsWaveformTransformWrapperr   r   r#   r   c                    sT   t    || _t|tstd|jj d|dkr#td| d|j	j
| _d S )Nzttorch-audiomentations waveform transforms can only be applied to `pyannote.audio.Model` instances: you tried with a z
 instance.r   zetorch-audiomentations waveform transforms can only be applied to the model input: you tried with the .)super__init__r   
isinstancer   	TypeError	__class____name__r    audiosample_ratesample_rate_)selfr   r#   r   r+   r   r   r(      s   

z5TorchAudiomentationsWaveformTransformWrapper.__init__	waveformsreturnc                 C   s   | j || jdjS )N)samplesr.   )r   r/   r4   )r0   r2   r   r   r   forward   s
   z4TorchAudiomentationsWaveformTransformWrapper.forwardr   )r,   
__module____qualname__r   r   strr(   torchTensorr5   __classcell__r   r   r1   r   r%      s    r%   c                 C   s   t | ||dS )Nr	   )r%   r$   r   r   r   _   s   r=   r6   )	functoolsr   r:   torch.nnr   /torch_audiomentations.core.transforms_interfacer   pyannote.audio.core.modelr   Moduler9   r   r   r   r%   registerr=   r   r   r   r   <module>   s&   
^	