@@ -30,11 +30,32 @@ static const pbdrv_gpio_t pin_audio = PBDRV_GPIO_EV3_PIN(3, 7, 4, 0, 0);
3030// and we do not want the usable bit depth to vary as the sample rate changes.
3131static const unsigned N_BITS_PER_SAMPLE = 12 ;
3232
33+ static uint64_t sample_timing_accum_numerator ;
34+ static uint32_t sample_idx ;
35+
36+ static const uint16_t * playing_data ;
37+ static uint32_t playing_data_len ;
38+ static uint32_t playing_sample_rate ;
39+
3340static void sound_isr () {
3441 EHRPWMETIntClear (SOC_EHRPWM_0_REGS );
3542 IntSystemStatusClear (SYS_INT_EHRPWM0 );
3643
37- // TODO: Load samples
44+ // Convert the hardware sample index to a desired data sample index
45+ // (using a naive ratio, rearranged to be computable using integers)
46+ // TODO: Use a real DSP resampling algorithm
47+ sample_timing_accum_numerator += (uint64_t )playing_sample_rate * (1ull << N_BITS_PER_SAMPLE );
48+ if (sample_timing_accum_numerator >= SOC_EHRPWM_0_MODULE_FREQ ) {
49+ sample_timing_accum_numerator -= SOC_EHRPWM_0_MODULE_FREQ ;
50+ sample_idx ++ ;
51+ }
52+ if (sample_idx == playing_data_len ) {
53+ sample_idx = 0 ;
54+ }
55+
56+ uint16_t sample = playing_data [sample_idx ];
57+ // TODO: Dither the quantization error
58+ HWREGH (SOC_EHRPWM_0_REGS + EHRPWM_CMPB ) = sample >> (16 - N_BITS_PER_SAMPLE );
3859}
3960
4061void pbdrv_sound_stop () {
@@ -52,7 +73,28 @@ void pbdrv_sound_stop() {
5273}
5374
5475void pbdrv_sound_start (const uint16_t * data , uint32_t length , uint32_t sample_rate ) {
76+ // Stop any currently-playing sounds
77+ pbdrv_sound_stop ();
5578
79+ if (length == 0 ) {
80+ return ;
81+ }
82+
83+ __asm__ volatile ("" ::: "memory" );
84+ playing_data = data ;
85+ playing_data_len = length ;
86+ playing_sample_rate = sample_rate ;
87+ sample_idx = 0 ;
88+ sample_timing_accum_numerator = 0 ;
89+ __asm__ volatile ("" ::: "memory" );
90+
91+ // Set the first sample
92+ HWREGH (SOC_EHRPWM_0_REGS + EHRPWM_CMPB ) = data [0 ] >> (16 - N_BITS_PER_SAMPLE );
93+
94+ // Enable all the sound generation
95+ pbdrv_gpio_out_high (& pin_sound_en );
96+ EHRPWMETIntEnable (SOC_EHRPWM_0_REGS );
97+ HWREGH (SOC_EHRPWM_0_REGS + EHRPWM_TBCTL ) = (HWREGH (SOC_EHRPWM_0_REGS + EHRPWM_TBCTL ) & ~EHRPWM_TBCTL_CTRMODE ) | EHRPWM_TBCTL_CTRMODE_UP ;
5698}
5799
58100void pbdrv_sound_init () {
0 commit comments