@@ -40,6 +40,10 @@ extern "C" {
40
40
#define DEFAULT_DURATION 4 // Crotchet
41
41
#define ARTICULATION_MS 10 // articulation between notes in milliseconds
42
42
43
+ #define MUSIC_OUTPUT_DEFAULT_PIN (µbit_p0_obj)
44
+ #define MUSIC_OUTPUT_AMPLITUDE_OFF (0 )
45
+ #define MUSIC_OUTPUT_AMPLITUDE_ON (128 )
46
+
43
47
typedef struct _music_data_t {
44
48
uint16_t bpm;
45
49
uint16_t ticks;
@@ -66,7 +70,15 @@ enum {
66
70
67
71
#define music_data MP_STATE_PORT (music_data)
68
72
69
- STATIC uint32_t start_note(const char *note_str, size_t note_len, const microbit_pin_obj_t *pin);
73
+ STATIC uint32_t start_note(const char *note_str, size_t note_len);
74
+
75
+ static inline void music_output_amplitude (uint32_t amplitude) {
76
+ pwm_set_duty_cycle (music_data->async_pin ->name , amplitude);
77
+ }
78
+
79
+ static inline int music_output_period_us (uint32_t period) {
80
+ return pwm_set_period_us (period);
81
+ }
70
82
71
83
void microbit_music_tick (void ) {
72
84
if (music_data == NULL ) {
@@ -86,7 +98,7 @@ void microbit_music_tick(void) {
86
98
87
99
if (music_data->async_state == ASYNC_MUSIC_STATE_ARTICULATE) {
88
100
// turn off output and rest
89
- pwm_set_duty_cycle (music_data-> async_pin -> name , 0 );
101
+ music_output_amplitude (MUSIC_OUTPUT_AMPLITUDE_OFF );
90
102
music_data->async_wait_ticks = ticker_ticks_ms + ARTICULATION_MS;
91
103
music_data->async_state = ASYNC_MUSIC_STATE_NEXT_NOTE;
92
104
} else if (music_data->async_state == ASYNC_MUSIC_STATE_NEXT_NOTE) {
@@ -109,14 +121,14 @@ void microbit_music_tick(void) {
109
121
}
110
122
if (note == mp_const_none) {
111
123
// a rest (is this even used anymore?)
112
- pwm_set_duty_cycle (music_data-> async_pin -> name , 0 );
124
+ music_output_amplitude (MUSIC_OUTPUT_AMPLITUDE_OFF );
113
125
music_data->async_wait_ticks = 60000 / music_data->bpm ;
114
126
music_data->async_state = ASYNC_MUSIC_STATE_NEXT_NOTE;
115
127
} else {
116
128
// a note
117
129
mp_uint_t note_len;
118
130
const char *note_str = mp_obj_str_get_data (note, ¬e_len);
119
- uint32_t delay_on = start_note (note_str, note_len, music_data-> async_pin );
131
+ uint32_t delay_on = start_note (note_str, note_len);
120
132
music_data->async_wait_ticks = ticker_ticks_ms + delay_on;
121
133
music_data->async_notes_index += 1 ;
122
134
music_data->async_state = ASYNC_MUSIC_STATE_ARTICULATE;
@@ -130,14 +142,14 @@ STATIC void wait_async_music_idle(void) {
130
142
// allow CTRL-C to stop the music
131
143
if (MP_STATE_VM (mp_pending_exception) != MP_OBJ_NULL) {
132
144
music_data->async_state = ASYNC_MUSIC_STATE_IDLE;
133
- pwm_set_duty_cycle (music_data-> async_pin -> name , 0 );
145
+ music_output_amplitude (MUSIC_OUTPUT_AMPLITUDE_OFF );
134
146
break ;
135
147
}
136
148
}
137
149
}
138
150
139
- STATIC uint32_t start_note (const char *note_str, size_t note_len, const microbit_pin_obj_t *pin ) {
140
- pwm_set_duty_cycle (pin-> name , 128 );
151
+ STATIC uint32_t start_note (const char *note_str, size_t note_len) {
152
+ music_output_amplitude (MUSIC_OUTPUT_AMPLITUDE_ON );
141
153
142
154
// [NOTE](#|b)(octave)(:length)
143
155
// technically, c4 is middle c, so we'll go with that...
@@ -233,9 +245,9 @@ STATIC uint32_t start_note(const char *note_str, size_t note_len, const microbit
233
245
period = periods_us[note_index] << -octave;
234
246
}
235
247
}
236
- pwm_set_period_us (period);
248
+ music_output_period_us (period);
237
249
} else {
238
- pwm_set_duty_cycle (pin-> name , 0 );
250
+ music_output_amplitude (MUSIC_OUTPUT_AMPLITUDE_OFF );
239
251
}
240
252
241
253
// Cut off a short time from end of note so we hear articulation.
@@ -269,13 +281,14 @@ MP_DEFINE_CONST_FUN_OBJ_0(microbit_music_get_tempo_obj, microbit_music_get_tempo
269
281
STATIC mp_obj_t microbit_music_stop (mp_uint_t n_args, const mp_obj_t *args) {
270
282
const microbit_pin_obj_t *pin;
271
283
if (n_args == 0 ) {
272
- pin = µbit_p0_obj ;
284
+ pin = MUSIC_OUTPUT_DEFAULT_PIN ;
273
285
} else {
274
286
pin = microbit_obj_get_pin (args[0 ]);
275
287
}
276
288
// Raise exception if the pin we are trying to stop is not in a compatible mode.
277
289
microbit_obj_pin_acquire (pin, microbit_pin_mode_music);
278
- pwm_set_duty_cycle (pin->name , 0 );
290
+ music_data->async_pin = pin;
291
+ music_output_amplitude (MUSIC_OUTPUT_AMPLITUDE_OFF);
279
292
microbit_obj_pin_free (pin);
280
293
music_data->async_pin = NULL ;
281
294
music_data->async_state = ASYNC_MUSIC_STATE_IDLE;
@@ -287,7 +300,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(microbit_music_stop_obj, 0, 1, microbit_musi
287
300
STATIC mp_obj_t microbit_music_play (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
288
301
static const mp_arg_t allowed_args[] = {
289
302
{ MP_QSTR_music, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
290
- { MP_QSTR_pin, MP_ARG_OBJ, {.u_obj = (mp_obj_t )µbit_p0_obj } },
303
+ { MP_QSTR_pin, MP_ARG_OBJ, {.u_obj = (mp_obj_t )MUSIC_OUTPUT_DEFAULT_PIN } },
291
304
{ MP_QSTR_wait, MP_ARG_BOOL, {.u_bool = true } },
292
305
{ MP_QSTR_loop, MP_ARG_BOOL, {.u_bool = false } },
293
306
};
@@ -348,7 +361,7 @@ STATIC mp_obj_t microbit_music_pitch(mp_uint_t n_args, const mp_obj_t *pos_args,
348
361
static const mp_arg_t allowed_args[] = {
349
362
{ MP_QSTR_frequency, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0 } },
350
363
{ MP_QSTR_duration, MP_ARG_INT, {.u_int = -1 } },
351
- { MP_QSTR_pin, MP_ARG_OBJ, {.u_obj = (mp_obj_t )µbit_p0_obj } },
364
+ { MP_QSTR_pin, MP_ARG_OBJ, {.u_obj = (mp_obj_t )MUSIC_OUTPUT_DEFAULT_PIN } },
352
365
{ MP_QSTR_wait, MP_ARG_BOOL, {.u_bool = true } },
353
366
};
354
367
@@ -366,10 +379,12 @@ STATIC mp_obj_t microbit_music_pitch(mp_uint_t n_args, const mp_obj_t *pos_args,
366
379
music_data->async_pin = NULL ;
367
380
microbit_obj_pin_acquire (pin, microbit_pin_mode_music);
368
381
bool wait = args[3 ].u_bool ;
369
- pwm_set_duty_cycle (pin->name , 128 );
382
+ music_data->async_pin = pin;
383
+ music_output_amplitude (MUSIC_OUTPUT_AMPLITUDE_ON);
384
+ music_data->async_pin = NULL ;
370
385
if (frequency == 0 ) {
371
386
pwm_release (pin->name );
372
- } else if (pwm_set_period_us (1000000 /frequency)) {
387
+ } else if (music_output_period_us (1000000 /frequency)) {
373
388
pwm_release (pin->name );
374
389
mp_raise_ValueError (" invalid pitch" );
375
390
}
0 commit comments