
     i                        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Zddej                  de
fd	Zedd
ede
fd       Z G d dej                        Zej                  dded
ede
fd       Zy)    )singledispatchN)BaseWaveformTransform)Modelaugmentationmodulewhenc                 j   t        | ||      t        |d      s(t        j                         |_        t               |_        ||j                  v rt        ||       |j                  |<   |dk(  rfd}|j                  |      }n|dk(  rfd}|j                  |      }|j                  |<   y)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   __augmentationinputc                      | S N )augmented_moduler   wrapped_augmentations     y/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/pyannote/audio/augmentation/registry.py
input_hookz)register_augmentation.<locals>.input_hooko   s    '//    outputc                      |      S r   r   )r   r   r   r   s      r   output_hookz*register_augmentation.<locals>.output_hookv   s    '//r   N)
wrap_augmentationhasattrnn
ModuleDictr   dict__augmentation_handleunregister_augmentationregister_forward_pre_hookregister_forward_hook)r   r   r   r   handler   r   s         @r   register_augmentationr"       s    B -\6M6+, "'+v$ v$$$T2"6F$w	0 11*=			0 --k:)/F  &r   c                     t        | d      r|| j                  vrt        d| d      | j                  |= | j                  j	                  |      }|j                          y)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!   s      r   r   r   ~   s`      F,-4v?T?T3T4TF/JKKd# ))--d3F
MMOr   modelc                     | S r   r   r   r'   r   s      r   r   r      s    r   c                   h     e Zd Z	 ddededef fdZdej                  dej                  fdZ	 xZ
S )	,TorchAudiomentationsWaveformTransformWrapperr   r'   r   c                     t         |           || _        t        |t              s#t        d|j                  j                   d      |dk7  rt        d| d      |j                  j                  | _        y )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   r2   s       r   r/   z5TorchAudiomentationsWaveformTransformWrapper.__init__   s     	(%'$$)OO$<$<#=ZI  7?&&*V1. 
 "KK33r   	waveformsreturnc                 P    | j                  || j                        j                  S )N)samplesr5   )r   r6   r;   )r7   r8   s     r   forwardz4TorchAudiomentationsWaveformTransformWrapper.forward   s*      4+<+< ! 

'	r   r   )r3   
__module____qualname__r   r   strr/   torchTensorr<   __classcell__)r2   s   @r   r+   r+      s>    MT414:?4GJ4( %,, r   r+   c                     t        | ||      S )Nr
   )r+   r)   s      r   _rE      s    7eRVWWr   r=   )	functoolsr   rA   torch.nnr   /torch_audiomentations.core.transforms_interfacer   pyannote.audio.core.modelr   Moduler@   r"   r   r   r+   registerrE   r   r   r   <module>rL      s   . %   Q + [0))[0II[0 [0|BII S 4 5   299 6 X) X% Xs X Xr   