o
    xi                     @   s   d dl 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 ddl	mZmZmZ ddl	mZmZ g dZd	Zed
 ZefddZddejfddZdd Zdd ZdejfddZe ejfddZdS )    N)PoolQueueProcess	cpu_count)partial   )cypesqcypesq_retvalscypesq_error_message)	PesqErrorInvalidSampleRateErrorOutOfMemoryError)BufferTooShortErrorNoUtterancesError)pesq
pesq_batchr   r   r   r   r   z
        Run model on reference(ref) and degraded(deg)
        Sample rate (fs) - No default. Must select either 8000 or 16000.
        Note there is narrow band (nb) mode only when sampling rate is 8000Hz.
       z
        The shapes of ref and deg should be identical if both are 2D numpy arrays.
        Once the `ref` is 1D  and the `deg` is 2D, the broadcast operation is applied. 
        c                 C   sh   | dkr| dkrt | td|dkr |dkr t | td|dkr0| dkr2t | tdd S d S )Nwbnbz"mode should be either 'nb' or 'wb'i@  >  z6fs (sampling frequency) should be either 8000 or 16000zno wide band mode if fs = 8000)print
ValueError)modefsusage r   >/home/ubuntu/.local/lib/python3.10/site-packages/pesq/_pesq.py_check_fs_mode   s   r   r   r   c                 C   s   t t t| d t t|d }|dkrd}nd}|tjkr6t|| | tj|| tj|S t|| | tj|| tj|S )e  
    Args:
        ref: numpy 1D array, reference audio signal
        deg: numpy 1D array, degraded audio signal
        fs:  integer, sampling rate
        mode: 'wb' (wide-band) or 'nb' (narrow-band)
        on_error: PesqError.RAISE_EXCEPTION (default) or PesqError.RETURN_VALUES
    Returns:
        pesq_score: float, P.862.2 Prediction (MOS-LQO)
    g      ?r   r   r   )	maxnpabsr   RETURN_VALUESr	   astypefloat32r   )refdegr   r   on_errormax_val	mode_coder   r   r   _pesq_inner*   s"   *
r)   c              
   C   s`   	 |  \}}|d u rd S z| | }W n ty' } z|}W Y d }~nd }~ww |||f qN)get	Exceptionput)funcargs_q	results_qindexargresulter   r   r   _processor_coordinatorI   s   r5   c           	         s   t dd t   fddt|D }|D ]	}d|_|  qt|D ]\}} ||f q%t|D ]} d q5fddtt|D }dd |D  d	d t|D S )
Nr   )maxsizec                    s   g | ]}t t fd qS ))targetargs)r   r5   .0_r/   r.   r0   r   r   
<listcomp>X   s    z&_processor_mapping.<locals>.<listcomp>T)NNc                    s   g | ]}   qS r   )r+   r9   )r0   r   r   r=   a       c                 S   s   g | ]}|  qS r   )join)r:   pr   r   r   r=   b   r>   c                 S   s   g | ]}|d  qS )r   r   )r:   vr   r   r   r=   c   r>   )r   rangedaemonstart	enumerater-   lensorted)	r.   r8   n_processor
processorsr@   ir2   r;   resultsr   r<   r   _processor_mappingU   s   

rL   c                 C   s   t || t t||| ||S )r   )r   USAGEr)   )r   r$   r%   r   r&   r   r   r   r   f   s   r   c           	   
      s  t t tjdkrt jdkr$j jkr$t tjgS t jdkrjd  jd kr|dkradd t jd D }t jd D ]}t |ddf ||< qL|S t|!}|	t
td fd	dt jd D W  d   S 1 sw   Y  dS td
tjdkr jjkr|dkrdd t jd D }t jd D ]}t|ddf  |ddf ||< q|S tt fddt jd D |S tdtd)as  
    Running `pesq` using multiple processors
    Args:
        on_error:
        ref: numpy 1D (n_sample,) or 2D array (n_file, n_sample), reference audio signal
        deg: numpy 1D (n_sample,) or 2D array (n_file, n_sample), degraded audio signal
        fs:  integer, sampling rate
        mode: 'wb' (wide-band) or 'nb' (narrow-band)
        n_processor: cpu_count() (default) or number of processors (chosen by the user) or 0 (without multiprocessing)
        on_error: PesqError.RAISE_EXCEPTION (default) or PesqError.RETURN_VALUES
    Returns:
        pesq_score: list of pesq scores, P.862.2 Prediction (MOS-LQO)
    r      r   c                 S      g | ]}t jqS r   r   nanr:   rJ   r   r   r   r=          zpesq_batch.<locals>.<listcomp>N)r   r   r&   c                    s   g | ]
} |d d f qS r*   r   rS   )r%   r   r   r=      s    zThe shapes of `deg` is invalid!c                 S   rP   r   rQ   rS   r   r   r   r=      rT   c                    s2   g | ]}|d d f  |d d f fqS r*   r   rS   r%   r   r   r&   r$   r   r   r=      s   2 zThe shape of `deg` is invalid!z-The shape of `ref` should be either 1D or 2D!)r   USAGE_BATCHrF   shaper)   r   r!   rB   r   mapr   r   rL   )	r   r$   r%   r   rH   r&   
pesq_scorerJ   r@   r   rU   r   r   u   s:   ""
$."r   )numpyr   multiprocessingr   r   r   r   	functoolsr   r   r	   r
   pesq_error_messager   r   r   r   r   __all__rM   rV   r   RAISE_EXCEPTIONr)   r5   rL   r   r   r   r   r   r   <module>   s   