
    (HJj3                     L    d dl Z d dlmZ d dlmZmZ d dlZd dlZ	 G d d      Z
y)    N)deque)EventLockc                      e Zd ZdZ	 	 	 	 d'dZd Zd Zd Zd Zde	fd	Z
de	fd
ZdddefdZd(defdZdedej"                  ddfdZddde	dededededefdZdededej"                  dz  fdZedej"                  de	dej"                  fd       Zed)dej"                  de	dej"                  fd       Zed ej"                  d!ej"                  defd"       Zd# Zd$ Zd% Zd& Zy)*AudioPlayerg      ?Nc                    || _         || _        || _        t        || j                  n|      | _        t               | _        t               | _	        d | _
        d| _        t               | _        t               | _        t               | _        d| _        d | _        d | _        d| _        d| _        d | _        d| _        d| _        y )NFg      @        r   )sample_ratebuffer_sizeevent_callbackfloatmin_buffer_secondsstart_buffer_secondsr   audio_bufferr   buffer_lockstreamplayingr   drain_eventhistory_lockoutput_historyoutput_history_seconds!last_output_callback_monotonic_mslast_output_dac_timelast_output_duration_mslast_output_sampleslast_flush_monotonic_mslast_flush_buffered_sampleslast_flush_was_playing)selfr
   r   r   r   s        d/Users/ahmed/devFolder/claude-voice/.venv/lib/python3.12/site-packages/mlx_audio/sts/audio_player.py__init__zAudioPlayer.__init__   s     '&,$)#+ ##%%
! "G6.2 7 F#g&)#15.$(!'*$#$ '+$+,(&+#    c                 b    | j                   y 	 | j                  ||       y # t        $ r Y y w xY wN)r   	Exception)r   eventfieldss      r    _emit_eventzAudioPlayer._emit_event,   s8    &	v. 		s   " 	..c                    |j                  d       d}d}d}| j                  5  ||k  r| j                  r| j                  d   }t        ||z
  t	        |            }	|d |	 ||||	z   df<   ||	z  }|	t	        |      k(  r| j                  j                          n||	d  | j                  d<   ||k  r| j                  rt        t        t        | j                              }| j                  s(||k  r#| j                  j                          d| _
        d}d d d        |rt        j                         dz  }
t        |dd       }t        |dd       }|t        |      dz  n|
}|d |df   j                         }| j!                  ||       |
| _        |t        |      nd | _        || j&                  z  dz  | _        || _        |||| j&                  z  dz  | j&                  ||| j&                  z  dz  |
d}|t        |      |d<   |t        |      |d	<   |rt-        |      |d
<    | j.                  di | |rt1        j2                         y # 1 sw Y   ?xY w)Nr   FT     @@outputBufferDacTimecurrentTime)samplesframesduration_msr
   buffered_samplesbuffered_mscallback_monotonic_mspa_output_dac_timepa_current_timestatus)tts_output_callback)fillr   r   minlenpopleftsummapr   setr   time	monotonicgetattrr   copy_append_output_historyr   r   r
   r   r   strr(   sdCallbackStop)r   outdatar.   callback_timer5   filledshould_stopr0   bufto_copyr2   output_dac_timecurrent_timeoutput_start_msoutput_samplesr'   s                   r    callbackzAudioPlayer.callback4   s   Q6/d&7&7''*fvos3x88;HW'!11145'!c#h&%%--/+.wx=D%%a( 6/d&7&7  #3sD,=,=#>?$$&  $$&$"! $ $(NN$4v$=!%m5JDQO"=-FL #. o&/* 
 %WfWaZ0557N''H5JD2*9*Eo&4 % ,2D4D4D+Dv+MD('-D$! %(8(886A#//$4/$2B2BBVK)>F */4_/E+,',1,,?()#&v;x D=f=//## i s   BI>AIIc                 *   | j                   | j                          t        j                  | j                  d| j
                  | j                        | _         | j                   j                          d| _        | j                  j                          y )N   )
sampleratechannelsrP   	blocksizeT)r   stop_streamrD   OutputStreamr
   rP   r   startr   r   clearr   s    r    start_streamzAudioPlayer.start_streamq   so    ;;"oo'']]&&	
 	 r"   c                     	 | j                   r4| j                   j                          | j                   j                          d | _         d| _        y # d | _         d| _        w xY w)NF)r   stopcloser   rZ   s    r    rV   zAudioPlayer.stop_stream~   sN    	!{{  "!!#DK DL DK DLs   A A A!returnc                 H    t        t        t        | j                              S r$   )r;   r<   r9   r   rZ   s    r    r0   zAudioPlayer.buffered_samples   s    3sD--.//r"   c           	      l    t        dt        t        | j                  | j                  z                    S )NrR   )maxintroundr
   r   rZ   s    r    start_buffer_samplesz AudioPlayer.start_buffer_samples   s*    1c% 0 043L3L LMNOOr"   Fforcec          
      *   | j                         }|rdn| j                         }d}| j                  s||k\  r| j                          d}d| j                  || j                  ||| j                  z  dz  | j                         | j
                  dz  |d	S )NrR   FTr*   )	player_enabledplayer_playingplayer_startedr
   r0   r1   re   start_buffer_msforced)r0   re   r   r[   r
   r   )r   rg   r0   neededstarteds        r    start_if_bufferedzAudioPlayer.start_if_buffered   s    002!:!:!<|| 0F :G""ll%++ 0+d.>.>>G$($=$=$?#886A

 
	
r"   c                 T   |t        j                         dz  n
t        |      }| j                         }i ddd| j                  d| j
                  d|d|| j
                  z  dz  d| j                  d	d d
| j                  d| j                  d| j                  d| j                  dd d| j                  d| j                  d| j                         d| j                  dz  }| j                  || j                  z
  |d	<   | j                  || j                  z
  |d<   |S )Nr*   ri   Trj   r
   r0   r1   r   last_output_age_msr   r   r   r   last_flush_age_msr   r   re   rl   )r>   r?   r   r0   r   r
   r   r   r   r   r   r   r   re   r   )r   now_msr0   states       r    playback_statezAudioPlayer.playback_state   s   .4n!F*%-002
d
dll
 4++
  0	

 +d.>.>>G
 01W1W
 !$
 &t'C'C
 "4#;#;
 #D$=$=
 &t'C'C
  
 *4+K+K
 %d&A&A
 #D$=$=$?
  t886A!
$ 11=??? &' ''3)/$2N2N)NE%&r"   start_msr-   c                    |j                   dk(  ry t        j                  |t        j                        j	                  d      }| j
                  5  | j                  j                  t        |      |f       || j                  dz  z
  }| j                  r^| j                  d   \  }}||j                   | j                  z  dz  z   }||k\  rn'| j                  j                          | j                  r^d d d        y # 1 sw Y   y xY w)Nr   dtyper*   )sizenpasarrayfloat32reshaper   r   appendr   r   r
   r:   )r   rw   r-   	cutoff_mschunk_startchunk	chunk_ends          r    rB   z"AudioPlayer._append_output_history   s    <<1**WBJJ7??C&&h'AB 4#>#>#GGI%%%)%8%8%;"U'%**t7G7G*G&*PP		)##++- %% s   B"C==Dg      @@)step_msinput_sample_rateinput_end_msmin_delay_msmax_delay_msr   c                Z   t        j                  |t         j                        j                  d      }|j                  dk  rdd d dS |j                  |z  dz  }dd d d}t        |      }	|	|k  r||	z
  }
|
|z
  }| j                  ||
      }||j                  dk\  r| j                  ||j                        }| j                  ||      }| j                  | j                  |      | j                  |            }t        ||      }||k\  rdnd}||d	   kD  r||	|d}|	|z  }	|	|k  r|S )
Nry   r{      r	   )correlationdelay_msmethodr*   rawenveloper   )r}   r~   r   r   r|   r   _history_segment	_resample_normalized_correlation	_enveloperb   )r   r-   r   r   r   r   r   r/   bestdelay
output_endoutput_startoutputr   envr   r   s                    r    echo_correlationzAudioPlayer.echo_correlation   sF    **WBJJ7??C<<!#&DDIIll%66?"El#|#%-J%3L**<DF!fkkQ&6=227FC22NN7+T^^F-C "#sm"%**m!44'2$)"(D
 WE% |#& r"   end_msc           
         g }| j                   5  t        | j                        }d d d        D ]  \  }}||j                  | j                  z  dz  z   }||k  s||k\  r0t        dt        t        ||z
  dz  | j                  z                    }t        |j                  t        t        ||z
  dz  | j                  z                    }	|	|kD  s|j                  |||	         |sy t        j                  |      S # 1 sw Y   xY w)Nr*   r   )r   listr   r|   r
   rb   rc   rd   r8   r   r}   concatenate)
r   rw   r   pieceshistoryr   r   r   start_index	end_indexs
             r    r   zAudioPlayer._history_segment   s   4../G ")K#ejj43C3C&Cf&LLIH$v(=3uh4>AQAQQRSK 

E6K/69D<L<LLMNI ;&eK	:; #* ~~f%%# s   C??Dr|   c                    | j                   |k(  r!| j                  t        j                  d      S | j                   dk  r%t        j                  |t        j                        S t        j
                  dd| j                         }t        j
                  dd|      }t        j                  |||       j                  t        j                        S )NF)rA   rR   ry   r	   g      ?)r|   astyper}   r   zeroslinspaceinterp)r-   r|   sourcetargets       r    r   zAudioPlayer._resample  s    <<4>>"**5>99<<188D

33S#w||4S#t,yy188DDr"   windowc                 l   t        j                  t        j                  | t         j                        j	                  d            } | j
                  |k  r| S t        j                  |t         j                        |z  }t        j                  | |d      j                  t         j                        S )Nry   r{   same)mode)	r}   absr~   r   r   r|   onesconvolver   )r-   r   kernels      r    r   zAudioPlayer._envelope  sv    &&G2::>FFrJK<<& Nrzz2V;{{7F8??

KKr"   abc                    t        j                  | t         j                        j                  d      } t        j                  |t         j                        j                  d      }| j                  |j                  k7  s| j                  dk(  ry| t        t        j                  |             z
  } |t        t        j                  |            z
  }t        t         j                  j                  |       t         j                  j                  |      z        }|dk  ryt        t        t        j                  | |      |z              S )Nry   r{   r   r	   g:0yE>)r}   r~   r   r   r|   r   meanlinalgnormr   dot)r   r   denoms      r    r   z#AudioPlayer._normalized_correlation  s    JJq

+33B7JJq

+33B766QVVqvv{bggaj!!bggaj!!biinnQ'"))..*;;<D=51-.//r"   c                    t        j                  |t         j                        }t        |      sy |j                  dk(  r|j                  d      }n|j                  dk(  r|j                  d   dk(  r
|d d df   }n|j                  d   dk(  r|d   }nw|j                  d   dk  r2|j                  d   |j                  d   k  r|j                  d      }n3|j                  d      }n |j                  dkD  r|j                  d      }| j                  5  | j                  j                  |       d d d        | j                  d	       y # 1 sw Y   xY w)
Nry   r   rR      r   )axisr{   Frf   )r}   r~   r   r9   ndimr   shaper   r   r   r   rp   )r   r-   s     r    queue_audiozAudioPlayer.queue_audio$  s    **WBJJ77|<<1ooa(G\\Q}}Q1$!!Q$-q!Q&!!*q!Q&7==+;gmmA>N+N!,,A,.!,,A,.\\Aoob)G$$W-  	U+ s   EEc                 6    | j                   j                         S r$   )r   waitrZ   s    r    wait_for_drainzAudioPlayer.wait_for_drain;  s    $$&&r"   c                     | j                   r=| j                          t        j                  d       | j	                          d| _         y y )Nd   F)r   r   rD   sleeprV   rZ   s    r    r]   zAudioPlayer.stop>  s8    <<!HHSM DL r"   c                    | j                   }| j                         }t        j                         dz  | _        || _        || _        | j                  5  | j                  j                          ddd       |r| j                          d| _         | j                  j                          |||| j                  z  dz  | j                         d   dS # 1 sw Y   dxY w)z1Discard everything and stop playback immediately.r*   NFrr   )was_playingr0   r1   rr   )r   r0   r>   r?   r   r   r   r   r   rY   rV   r   r=   r
   rv   )r   r   r0   s      r    flushzAudioPlayer.flushF  s    ll002'+~~'7&'@$+;(&1###% & 0+d.>.>>G"&"5"5"78L"M	
 	
 s   CC)i]  i   NNr$   )   )__name__
__module____qualname__r   r!   r(   rP   r[   rV   rc   r0   re   dictrp   rv   r   r}   ndarrayrB   r   r   staticmethodr   r   r   r   r   r]   r    r"   r    r   r   	   s    !,@;$z!!0# 0Pc P */ 
4 
&T :.u .rzz .d ., # 	#
 # # # # 
#J& & &"**tBS &* E2:: ES ERZZ E E L2:: Ls LBJJ L L 
02:: 
0"** 
0 
0 
0,.'!
r"   r   )r>   collectionsr   	threadingr   r   numpyr}   sounddevicerD   r   r   r"   r    <module>r      s       !  P
 P
r"   