| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -8,13 +8,12 @@ from typing import Dict, Optional, Tuple | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from cereal import car, messaging | 
					 | 
					 | 
					 | 
					from cereal import car, messaging | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.common.basedir import BASEDIR | 
					 | 
					 | 
					 | 
					from openpilot.common.basedir import BASEDIR | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.common.filter_simple import FirstOrderFilter | 
					 | 
					 | 
					 | 
					from openpilot.common.filter_simple import FirstOrderFilter | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.system import micd | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.system.hardware import TICI | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.common.realtime import Ratekeeper | 
					 | 
					 | 
					 | 
					from openpilot.common.realtime import Ratekeeper | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					from openpilot.common.retry import retry | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					from openpilot.common.swaglog import cloudlog | 
					 | 
					 | 
					 | 
					from openpilot.common.swaglog import cloudlog | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					from openpilot.system import micd | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					SAMPLE_RATE = 48000 | 
					 | 
					 | 
					 | 
					SAMPLE_RATE = 48000 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					SAMPLE_BUFFER = 4096 # (approx 100ms) | 
					 | 
					 | 
					 | 
					SAMPLE_BUFFER = 4096 # (approx 100ms) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					MAX_VOLUME = 1.0 | 
					 | 
					 | 
					 | 
					MAX_VOLUME = 1.0 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -127,16 +126,21 @@ class Soundd: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    volume = ((weighted_db - AMBIENT_DB) / DB_SCALE) * (MAX_VOLUME - MIN_VOLUME) + MIN_VOLUME | 
					 | 
					 | 
					 | 
					    volume = ((weighted_db - AMBIENT_DB) / DB_SCALE) * (MAX_VOLUME - MIN_VOLUME) + MIN_VOLUME | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    return math.pow(10, (np.clip(volume, MIN_VOLUME, MAX_VOLUME) - 1)) | 
					 | 
					 | 
					 | 
					    return math.pow(10, (np.clip(volume, MIN_VOLUME, MAX_VOLUME) - 1)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  @retry(attempts=7, delay=3) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					  def get_stream(self, sd): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    # reload sounddevice to reinitialize portaudio | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    sd._terminate() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    sd._initialize() | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    return sd.OutputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback, blocksize=SAMPLE_BUFFER) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					  def soundd_thread(self): | 
					 | 
					 | 
					 | 
					  def soundd_thread(self): | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    # sounddevice must be imported after forking processes | 
					 | 
					 | 
					 | 
					    # sounddevice must be imported after forking processes | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    import sounddevice as sd | 
					 | 
					 | 
					 | 
					    import sounddevice as sd | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if TICI: | 
					 | 
					 | 
					 | 
					    sm = messaging.SubMaster(['controlsState', 'microphone']) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      micd.wait_for_devices(sd) # wait for alsa to be initialized on device | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    with sd.OutputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback, blocksize=SAMPLE_BUFFER) as stream: | 
					 | 
					 | 
					 | 
					    with self.get_stream(sd) as stream: | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      rk = Ratekeeper(20) | 
					 | 
					 | 
					 | 
					      rk = Ratekeeper(20) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      sm = messaging.SubMaster(['controlsState', 'microphone']) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      cloudlog.info(f"soundd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}, {stream.blocksize=}") | 
					 | 
					 | 
					 | 
					      cloudlog.info(f"soundd stream started: {stream.samplerate=} {stream.channels=} {stream.dtype=} {stream.device=}, {stream.blocksize=}") | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					      while True: | 
					 | 
					 | 
					 | 
					      while True: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |