o
    SQ8j                     @   s   d dl Z d dlmZ d dlZd dlZd dlZd dlZd dlZd dlm	Z	 d dl
mZ d dlmZmZ 		dded	ejd
ededef
ddZdd ZdejdejfddZdededed
efddZdS )    N)tqdm)LogisticRegression)make_pipeline)FunctionTransformerStandardScaler      ?   reference_clip	oww_model
model_name	thresholdNc                 K   s  t t}t|D ]X}t| tkrtjj	| \}}	n| }	|dkr,|	t
jddd }	d}
td|	jd |
 |
D ]'}|j|	|||
  fi |}|| |kr`|j|j| }|| | q9q	t|| dkrz|| t
d|j| df t
|| S )a8  
    Processes input audio files (16-bit, 16-khz single-channel WAV files) and gets the openWakeWord
    audio features that produce a prediction from the specified model greater than the threshold value.


    Args:
        reference_clip (str): The target audio file to get features from
        oww_model (openwakeword.Model): The openWakeWord model object used to get predictions
        model_name (str): The name of the model to get predictions from (should correspond to
                          a python dictionary key in the oww_model.models attribute)
        threshold (float): The minimum score from the model required to capture the associated features
        N (int): How many times to run feature extraction for a given clip, adding some slight variation
                 in the starting position each time to ensure that the features are not identical

    Returns:
        ndarray: A numpy array of shape N x M x L, where N is the number of examples, M is the number
                 of frames in the window, and L is the audio feature/embedding dimension.
       r   i   N`   )collectionsdefaultdictlistrangetypestrscipyiowavfilereadnprandomrandintshapepredictpreprocessorget_featuresmodel_inputsappendlenemptyvstack)r	   r
   r   r   r   kwargspositive_data_srdat	step_sizeipredictionsfeatures r/   i/home/nk/hobo-godmode/plappi-mvp/.venv/lib/python3.10/site-packages/openwakeword/custom_verifier_model.pyget_reference_clip_features   s,   
r1   c                 C   s   dd | D S )Nc                 S   s   g | ]}|  qS r/   )flatten.0r,   r/   r/   r0   
<listcomp>Z   s    z$flatten_features.<locals>.<listcomp>r/   )xr/   r/   r0   flatten_featuresY   s   r7   r.   labelsc                 C   s0   t dddd}tttt |}|| | |S )a  
    Train a logistic regression binary classifier model on the provided features and labels

    Args:
        features (ndarray): A N x M numpy array, where N is the number of examples and M
                             is the number of features
        labels (ndarray): A 1D numpy array where each value corresponds to the label of the Nth
                           example in the `features` argument

    Returns:
        The trained scikit-learn logistic regression model
    r   i  gMbP?)random_statemax_iterC)r   r   r   r7   r   fit)r.   r8   clfpipeliner/   r/   r0   train_verifier_model]   s   r?   positive_reference_clipsnegative_reference_clipsoutput_pathc                    s  t j r!tjdd gi|t j d t jjd  ntjdi |t	 fddt
| ddD }|jd dkrEtdt	 fd	dt
|d
dD }td tt	||ftdg|jd  dg|jd   }td t|t|d dS )a  
    Trains a voice-specific custom verifier model on examples of wake word/phrase speech and other speech
    from a single user.

    Args:
        positive_reference_clips (str): The path to a directory containing single-channel 16khz, 16-bit WAV files
                                        of the target wake word/phrase.
        negative_reference_clips (str): The path to a directory containing single-channel 16khz, 16-bit WAV files
                                        of miscellaneous speech not containing the target wake word/phrase.
        output_path (str): The location to save the trained verifier model (as a scikit-learn .joblib file)
        model_name (str): The name or path of the trained openWakeWord model that the verifier model will be
                          based on. If only a name, it must be one of the pre-trained models included in the
                          openWakeWord release.
        kwargs: Any other keyword arguments to pass to the openWakeWord model initialization

    Returns:
        None
    wakeword_modelsr   c                    s   g | ]
}t | d dqS )   )r   r1   r3   r   owwr/   r0   r5      s    z)train_custom_verifier.<locals>.<listcomp>z#Processing positive reference clips)desczThe positive features were created! Make sure that the positive reference clips contain the appropriate audio for the desired modelc              	      s   g | ]}t | d ddqS )g        r   )r   r   rF   r3   rG   r/   r0   r5      s    z#Processing negative reference clipsz%Training and saving verifier model...r   zDone!wbNr/   )ospathexistsopenwakewordModelsplitextsplitsepr   r%   r   r   
ValueErrorprintr?   arraypickledumpopen)r@   rA   rB   r   r&   positive_featuresnegative_featureslr_modelr/   rG   r0   train_custom_verifierr   s6    

$r\   )r   r   )rK   r   r   rN   numpyr   r   rV   sklearn.linear_modelr   sklearn.pipeliner   sklearn.preprocessingr   r   r   rO   floatintr1   r7   ndarrayr?   r\   r/   r/   r/   r0   <module>   sD   
;