o
    7wih                     @   sJ  d dl mZ d dlmZ d dlmZ d dlmZmZm	Z	m
Z
 d dlmZ d dl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 d d	lmZ d d
lmZ d#ddZdd fdedee dee fddZde defddZ!dede fddZ"		 	 	d$dej#dee ef dedee dee dee d eej# dej#fd!d"Z$dS )%    )CounterFractionreduce)chaincountislicerepeat)log2)CallableListOptionalUnionN)version)primespadc           	      #   s    |rt t|  \ }dd }t|}tt|t || }t|| k r(d S 	 t fdd|D V  t tt	| |tt	|t|D ]\}}|| |krS nqGd S || d }t t	|| |t|||d  D ]\}}|||< qmq))Nc                 S   s   t tt| |S N)r   from_iterablemapr
   )ic r   S/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torch_pitch_shift/main.py<lambda>   s    z2_combinations_without_repetition.<locals>.<lambda>Tc                 3   s    | ]} | V  qd S r   r   ).0r   valuesr   r   	<genexpr>   s    z3_combinations_without_repetition.<locals>.<genexpr>   )
zipr   itemslenlistr	   r   tuplereversedrange)	riterabler   countsfnindicesr   jr   r   r    _combinations_without_repetition   s&   ,*
r/   c                 C   s   | dko| dko| dkS )Ng      ?   r    r   )xr   r   r   r   (   s    r   sample_rate	conditionreturnc                 C   s   t  }t| }g }tdt|d D ]}|dd t||dD  q|D ]}|D ]}t||}||r:|| q*q&t	|S )a  
    Search for pitch-shift targets that can be computed quickly for a given sample rate.

    Parameters
    ----------
    sample_rate: int
        The sample rate of an audio clip.
    condition: Callable [optional]
        A function to validate fast shift ratios.
        Default is `lambda x: x >= 0.5 and x <= 2 and x != 1` (between -1 and +1 octaves).

    Returns
    -------
    output: List[Fraction]
        A list of fast pitch-shift target ratios
    r    c                 S   s   g | ]	}t d d |qS )c                 S   s   | | S r   r   )r1   yr   r   r   r   @   s    z,get_fast_shifts.<locals>.<listcomp>.<lambda>r   )r   r1   r   r   r   
<listcomp>?   s    z#get_fast_shifts.<locals>.<listcomp>)r)   )
setr   factorsr'   r#   extendr/   r   addr$   )r2   r3   fast_shiftsr8   productsr   r.   r+   r   r   r   get_fast_shifts&   s"   



r=   	semitonesc                 C   s   t d| d  S )z
    Convert semitonal shifts into ratios.

    Parameters
    ----------
    semitones: float
        The number of semitones for a desired shift.

    Returns
    -------
    output: Fraction
        A Fraction indicating a pitch shift ratio
           @      (@r   )r>   r   r   r   semitones_to_ratioL      rA   ratioc                 C   s   t dt|  S )z
    Convert rational shifts to semitones.

    Parameters
    ----------
    ratio: Fraction
        The ratio for a desired shift.

    Returns
    -------
    output: float
        The magnitude of a pitch shift in semitones
    r@   )floatr   )rC   r   r   r   ratio_to_semitones]   rB   rE      inputshiftbins_per_octaven_fft
hop_lengthwindowc                 C   sp  |s|d }|s|d }|du rt |}|| j}| j\}}}	t|ts.dt||  }t	|t
|| | j}
| }||| |	}ttjtdk}t j|||||dd }tjtd| |jd	 |d
| j}||}t j|d |||d}|
|}~
~|jd | jd	 kr|ddd| jd	 f }nt|d| jd	 |jd  ddfd}||||	}|S )a  
    Shift the pitch of a batch of waveforms by a given amount.

    Parameters
    ----------
    input: torch.Tensor [shape=(batch_size, channels, samples)]
        Input audio clips of shape (batch_size, channels, samples)
    shift: float OR Fraction
        `float`: Amount to pitch-shift in # of bins. (1 bin == 1 semitone if `bins_per_octave` == 12)
        `Fraction`: A `fractions.Fraction` object indicating the shift ratio. Usually an element in `get_fast_shifts()`.
    sample_rate: int
        The sample rate of the input audio clips.
    bins_per_octave: int [optional]
        Number of bins per octave. Default is 12.
    n_fft: int [optional]
        Size of FFT. Default is `sample_rate // 64`.
    hop_length: int [optional]
        Size of hop length. Default is `n_fft // 32`.
    window: torch.Tensor [optional]
        A window tensor for the STFT. Default is a tensor of ones.

    Returns
    -------
    output: torch.Tensor [shape=(batch_size, channels, samples)]
        The pitch-shifted batch of audio clips
    @       Nr?   z0.11.0)return_complexrL   )N.r    r0   )
fixed_raten_freqrK   r   )rL   r   )torchonestodeviceshape
isinstancer   rD   TResampleintreshaper   parse
torchaudio__version__stftTimeStretchistftr   )rG   rH   r2   rI   rJ   rK   rL   
batch_sizechannelssamples	resampleroutputv011	stretcherr   r   r   pitch_shiftn   s>   $

$ri   )NNN)rF   r   r   N)%collectionsr   	fractionsr   	functoolsr   	itertoolsr   r   r	   r
   mathr   typingr   r   r   r   rR   r]   torchaudio.transforms
transformsrX   	packagingr   primePyr   torch.nn.functionalr   r/   rZ   r=   rD   rA   rE   Tensorri   r   r   r   r   <module>   sX    

&
