Skip to content

Commit 23d783b

Browse files
committed
Audio: Make sure everything is reset at start, to minimise duration of glitches.
1 parent 8fee594 commit 23d783b

File tree

2 files changed

+31
-30
lines changed

2 files changed

+31
-30
lines changed

inc/microbit/modaudio.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include "py/obj.h"
77
#include "py/runtime.h"
88

9-
mp_obj_t audio_init(void);
109
void audio_play_source(mp_obj_t src, mp_obj_t pin1, mp_obj_t pin2, bool wait);
1110

1211
#define LOG_AUDIO_CHUNK_SIZE 5

source/microbit/modaudio.cpp

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,11 @@ static void audio_ppi_init(uint8_t channel0, uint8_t channel1) {
113113
static inline void timer_stop(void) {
114114
TheTimer->TASKS_STOP = 1;
115115
*(uint32_t *)0x40009C0C = 0; //for Timer 1
116-
116+
TheTimer->TASKS_CLEAR = 1;
117+
TheTimer->CC[0] = 0xfffc;
118+
TheTimer->CC[1] = 0xfffc;
119+
TheTimer->CC[2] = 0xfffc;
120+
TheTimer->CC[3] = 0xfffc;
117121
}
118122

119123
static inline void timer_start(void) {
@@ -148,6 +152,7 @@ static void audio_stop(void) {
148152
disable_gpiote(1);
149153
nrf_gpio_pin_write(pin1, 0);
150154
}
155+
//NRF_CLOCK->TASKS_HFCLKSTOP = 1;
151156
}
152157

153158
static int32_t audio_ticker(void);
@@ -246,12 +251,11 @@ static void audio_data_fetcher_allow_gc(void) {
246251

247252
#define TICK_PER_SAMPLE (128/MICROSECONDS_PER_TICK)
248253

249-
#define FIRST_PHASE_START 32
250-
#define SECOND_PHASE_START ((CYCLES_PER_TICK*TICK_PER_SAMPLE/4)+32)
254+
#define FIRST_PHASE_START 4
255+
#define SECOND_PHASE_START ((CYCLES_PER_TICK*TICK_PER_SAMPLE/4)+FIRST_PHASE_START)
251256

252257
static inline void set_gpiote_output_pulses(int32_t val1, int32_t val2) {
253258
NRF_TIMER_Type *timer = TheTimer;
254-
timer->TASKS_CLEAR = 1;
255259
if (double_pin) {
256260
//Start with output zero; pins 00
257261
if (val1 < 0) {
@@ -284,6 +288,7 @@ static inline void set_gpiote_output_pulses(int32_t val1, int32_t val2) {
284288
timer->CC[2] = SECOND_PHASE_START;
285289
timer->CC[3] = SECOND_PHASE_START+val2;
286290
}
291+
timer->TASKS_CLEAR = 1;
287292
}
288293

289294
static int32_t audio_ticker(void) {
@@ -362,10 +367,32 @@ static void audio_auto_set_pins(void) {
362367
audio_set_pins((mp_obj_t)&microbit_p0_obj, mp_const_none);
363368
}
364369

370+
static void audio_init(void) {
371+
static bool initialised = false;
372+
if (!initialised) {
373+
audio_source_iter = NULL;
374+
initialised = true;
375+
//Allocate buffer
376+
audio_buffer_ptr = m_new(uint8_t, AUDIO_BUFFER_SIZE);
377+
}
378+
//NRF_CLOCK->TASKS_HFCLKSTART = 1;
379+
NVIC_DisableIRQ(TheTimer_IRQn);
380+
TheTimer->POWER = 1;
381+
NRF_TIMER_Type *timer = TheTimer;
382+
timer_stop();
383+
timer->MODE = TIMER_MODE_MODE_Timer;
384+
timer->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
385+
timer->PRESCALER = 0; //Full speed
386+
timer->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk | TIMER_INTENCLR_COMPARE1_Msk |
387+
TIMER_INTENCLR_COMPARE2_Msk | TIMER_INTENCLR_COMPARE3_Msk;
388+
timer->SHORTS = 0;
389+
}
390+
365391
void audio_play_source(mp_obj_t src, mp_obj_t pin1, mp_obj_t pin2, bool wait) {
366392
if (running) {
367393
audio_stop();
368394
}
395+
audio_init();
369396
if (pin1 == mp_const_none) {
370397
if (pin2 == mp_const_none) {
371398
audio_auto_set_pins();
@@ -395,30 +422,6 @@ void audio_play_source(mp_obj_t src, mp_obj_t pin1, mp_obj_t pin2, bool wait) {
395422
}
396423
}
397424

398-
399-
mp_obj_t audio_init(void) {
400-
static bool initialised = false;
401-
if (!initialised) {
402-
audio_source_iter = NULL;
403-
initialised = true;
404-
//Allocate buffer
405-
audio_buffer_ptr = m_new(uint8_t, AUDIO_BUFFER_SIZE);
406-
NVIC_DisableIRQ(TheTimer_IRQn);
407-
TheTimer->POWER = 1;
408-
NRF_TIMER_Type *timer = TheTimer;
409-
timer_stop();
410-
timer->TASKS_CLEAR = 1;
411-
timer->MODE = TIMER_MODE_MODE_Timer;
412-
timer->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
413-
timer->PRESCALER = 0; //Full speed
414-
timer->INTENCLR = TIMER_INTENCLR_COMPARE0_Msk | TIMER_INTENCLR_COMPARE1_Msk |
415-
TIMER_INTENCLR_COMPARE2_Msk | TIMER_INTENCLR_COMPARE3_Msk;
416-
timer->SHORTS = 0;
417-
}
418-
return mp_const_none;
419-
}
420-
MP_DEFINE_CONST_FUN_OBJ_0(audio___init___obj, audio_init);
421-
422425
STATIC mp_obj_t stop() {
423426
audio_stop();
424427
return mp_const_none;
@@ -625,7 +628,6 @@ microbit_audio_frame_obj_t *new_microbit_audio_frame(void) {
625628

626629
STATIC const mp_map_elem_t audio_globals_table[] = {
627630
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_audio) },
628-
{ MP_OBJ_NEW_QSTR(MP_QSTR___init__), (mp_obj_t)&audio___init___obj },
629631
{ MP_OBJ_NEW_QSTR(MP_QSTR_stop), (mp_obj_t)&microbit_audio_stop_obj },
630632
{ MP_OBJ_NEW_QSTR(MP_QSTR_play), (mp_obj_t)&microbit_audio_play_obj },
631633
{ MP_OBJ_NEW_QSTR(MP_QSTR_is_playing), (mp_obj_t)&microbit_audio_is_playing_obj },

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy