@@ -226,6 +226,7 @@ def get_progress_ms(self):
226226 def get_duration_ms (self ):
227227 return self ._duration_ms
228228
229+
229230 # ----------------------------------------------------------------------
230231 # WAV header parser - returns bit-depth and format info
231232 # ----------------------------------------------------------------------
@@ -370,6 +371,28 @@ def _convert_32_to_16(buf):
370371 out [i * 2 ] = s16 & 0xFF
371372 out [i * 2 + 1 ] = (s16 >> 8 ) & 0xFF
372373 j += 4
374+
375+ @staticmethod
376+ def _get_freq_duty (sample_rate ):
377+ # Would be good to do this default when no communicator (external speaker) is connected, as it's better for quality:
378+ #return (sample_rate * 256, 32768)
379+ if sample_rate == 8000 :
380+ return (640000 ,1365 )
381+ elif sample_rate == 11025 :
382+ return (1060800 ,1024 )
383+ elif sample_rate == 16000 :
384+ return (512000 ,512 )
385+ elif sample_rate == 22050 :
386+ return (705600 ,1024 )
387+ elif sample_rate == 32000 :
388+ print ("Warning: sample rate 32kHz hasn't been testing, guessing!" )
389+ return (1024000 ,1024 )
390+ elif sample_rate == 44100 :
391+ return (1411200 ,2048 )
392+ else :
393+ print (f"Uncommon sample rate { sample_rate } hasn't been tried, returning default sample_rate * 256 amd 50% duty cycle" )
394+ return (sample_rate * 256 , 32768 )
395+
373396 return out
374397
375398 # ----------------------------------------------------------------------
@@ -457,14 +480,12 @@ def play(self):
457480 if 'mck' in self .i2s_pins :
458481 mck_pin = machine .Pin (self .i2s_pins ['mck' ], machine .Pin .OUT )
459482 from machine import Pin , PWM
460- # Add MCLK generation on GPIO2
461483 try :
462484 self ._mck_pwm = PWM (mck_pin )
463- # Set frequency to sample_rate * 256 (common ratio for CJC4334H auto-detect)
464- # Use duty_u16 for finer control (0–65535 range, 32768 = 50%)
465- self ._mck_pwm .freq (playback_rate * 256 )
466- self ._mck_pwm .duty_u16 (32768 ) # 50% duty cycle
467- print (f"MCLK PWM started on GPIO2 at { playback_rate * 256 } Hz" )
485+ freq , duty = WAVStream ._get_freq_duty (playback_rate )
486+ self ._mck_pwm .freq (freq )
487+ self ._mck_pwm .duty_u16 (duty ) # 50% duty cycle
488+ print (f"MCLK PWM started at { freq } Hz with duty cycle { duty } /65535" )
468489 except Exception as e :
469490 print (f"MCLK PWM init failed: { e } " )
470491 # fallback or error handling
@@ -560,7 +581,7 @@ def play(self):
560581 print (f"_i2s.shift got exception, falling back to software scaling: { e } " )
561582 _scale_audio_optimized (raw , len (raw ), scale_fixed )
562583 else :
563- print ("_i2s has no shift attribute, falling back to software scaling" )
584+ # print("_i2s has no shift attribute, falling back to software scaling")
564585 _scale_audio_optimized (raw , len (raw ), scale_fixed )
565586
566587 # 4. Output to I2S (blocking write is OK - we're in a separate thread)
0 commit comments