Skip to content

Commit d4c4e0b

Browse files
committed
Merge remote-tracking branch 'origin/main'
2 parents c0de8a9 + 9e22850 commit d4c4e0b

File tree

10 files changed

+109
-7
lines changed

10 files changed

+109
-7
lines changed

ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ LONGINT_IMPL = MPZ
1212

1313
# No I2S on SAMD51G
1414
CIRCUITPY_AUDIOBUSIO = 0
15+
CIRCUITPY_SYNTHIO = 0
1516

1617
CIRCUITPY_BITBANG_APA102 = 1
1718

shared-bindings/synthio/Synthesizer.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "py/binary.h"
3232
#include "py/objproperty.h"
3333
#include "py/runtime.h"
34+
#include "py/enum.h"
3435
#include "shared-bindings/util.h"
3536
#include "shared-bindings/synthio/Biquad.h"
3637
#include "shared-bindings/synthio/Synthesizer.h"
@@ -256,7 +257,9 @@ MP_PROPERTY_GETTER(synthio_synthesizer_sample_rate_obj,
256257
(mp_obj_t)&synthio_synthesizer_get_sample_rate_obj);
257258

258259
//| pressed: NoteSequence
259-
//| """A sequence of the currently pressed notes (read-only property)"""
260+
//| """A sequence of the currently pressed notes (read-only property).
261+
//|
262+
//| This does not include notes in the release phase of the envelope."""
260263
//|
261264
STATIC mp_obj_t synthio_synthesizer_obj_get_pressed(mp_obj_t self_in) {
262265
synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -268,6 +271,23 @@ MP_DEFINE_CONST_FUN_OBJ_1(synthio_synthesizer_get_pressed_obj, synthio_synthesiz
268271
MP_PROPERTY_GETTER(synthio_synthesizer_pressed_obj,
269272
(mp_obj_t)&synthio_synthesizer_get_pressed_obj);
270273

274+
//| def note_info(self, note: Note) -> Tuple[Optional[EnvelopeState], float]:
275+
//| """Get info about a note's current envelope state
276+
//|
277+
//| If the note is currently playing (including in the release phase), the returned value gives the current envelope state and the current envelope value.
278+
//|
279+
//| If the note is not playing on this synthesizer, returns the tuple ``(None, 0.0)``."""
280+
STATIC mp_obj_t synthio_synthesizer_obj_note_info(mp_obj_t self_in, mp_obj_t note) {
281+
synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in);
282+
check_for_deinit(self);
283+
mp_float_t vol = MICROPY_FLOAT_CONST(0.0);
284+
envelope_state_e state = common_hal_synthio_synthesizer_note_info(self, note, &vol);
285+
return MP_OBJ_NEW_TUPLE(
286+
cp_enum_find(&synthio_note_state_type, state),
287+
mp_obj_new_float(vol));
288+
}
289+
MP_DEFINE_CONST_FUN_OBJ_2(synthio_synthesizer_note_info_obj, synthio_synthesizer_obj_note_info);
290+
271291
//| blocks: List[BlockInput]
272292
//| """A list of blocks to advance whether or not they are associated with a playing note.
273293
//|
@@ -417,6 +437,7 @@ STATIC const mp_rom_map_elem_t synthio_synthesizer_locals_dict_table[] = {
417437
{ MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&synthio_synthesizer_sample_rate_obj) },
418438
{ MP_ROM_QSTR(MP_QSTR_max_polyphony), MP_ROM_INT(CIRCUITPY_SYNTHIO_MAX_CHANNELS) },
419439
{ MP_ROM_QSTR(MP_QSTR_pressed), MP_ROM_PTR(&synthio_synthesizer_pressed_obj) },
440+
{ MP_ROM_QSTR(MP_QSTR_note_info), MP_ROM_PTR(&synthio_synthesizer_note_info_obj) },
420441
{ MP_ROM_QSTR(MP_QSTR_blocks), MP_ROM_PTR(&synthio_synthesizer_blocks_obj) },
421442
};
422443
STATIC MP_DEFINE_CONST_DICT(synthio_synthesizer_locals_dict, synthio_synthesizer_locals_dict_table);

shared-bindings/synthio/Synthesizer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,4 @@ void common_hal_synthio_synthesizer_retrigger(synthio_synthesizer_obj_t *self, m
4545
void common_hal_synthio_synthesizer_release_all(synthio_synthesizer_obj_t *self);
4646
mp_obj_t common_hal_synthio_synthesizer_get_pressed_notes(synthio_synthesizer_obj_t *self);
4747
mp_obj_t common_hal_synthio_synthesizer_get_blocks(synthio_synthesizer_obj_t *self);
48+
envelope_state_e common_hal_synthio_synthesizer_note_info(synthio_synthesizer_obj_t *self, mp_obj_t note, mp_float_t *vol_out);

shared-bindings/synthio/__init__.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,32 @@
4545

4646
#include "shared-module/synthio/LFO.h"
4747

48+
//| class EnvelopeState:
49+
//| ATTACK: EnvelopeState
50+
//| """The note is in its attack phase"""
51+
//| DECAY: EnvelopeState
52+
//| """The note is in its decay phase"""
53+
//| SUSTAIN: EnvelopeState
54+
//| """The note is in its sustain phase"""
55+
//| RELEASE: EnvelopeState
56+
//| """The note is in its release phase"""
57+
//|
58+
MAKE_ENUM_VALUE(synthio_note_state_type, note_state, ATTACK, SYNTHIO_ENVELOPE_STATE_ATTACK);
59+
MAKE_ENUM_VALUE(synthio_note_state_type, note_state, DECAY, SYNTHIO_ENVELOPE_STATE_DECAY);
60+
MAKE_ENUM_VALUE(synthio_note_state_type, note_state, SUSTAIN, SYNTHIO_ENVELOPE_STATE_SUSTAIN);
61+
MAKE_ENUM_VALUE(synthio_note_state_type, note_state, RELEASE, SYNTHIO_ENVELOPE_STATE_RELEASE);
62+
63+
MAKE_ENUM_MAP(synthio_note_state) {
64+
MAKE_ENUM_MAP_ENTRY(note_state, ATTACK),
65+
MAKE_ENUM_MAP_ENTRY(note_state, DECAY),
66+
MAKE_ENUM_MAP_ENTRY(note_state, SUSTAIN),
67+
MAKE_ENUM_MAP_ENTRY(note_state, RELEASE),
68+
};
69+
70+
STATIC MP_DEFINE_CONST_DICT(synthio_note_state_locals_dict, synthio_note_state_locals_table);
71+
MAKE_PRINTER(synthio, synthio_note_state);
72+
MAKE_ENUM_TYPE(synthio, EnvelopeState, synthio_note_state);
73+
4874
#define default_attack_time (MICROPY_FLOAT_CONST(0.1))
4975
#define default_decay_time (MICROPY_FLOAT_CONST(0.05))
5076
#define default_release_time (MICROPY_FLOAT_CONST(0.2))
@@ -316,6 +342,7 @@ STATIC const mp_rom_map_elem_t synthio_module_globals_table[] = {
316342
{ MP_ROM_QSTR(MP_QSTR_MathOperation), MP_ROM_PTR(&synthio_math_operation_type) },
317343
{ MP_ROM_QSTR(MP_QSTR_MidiTrack), MP_ROM_PTR(&synthio_miditrack_type) },
318344
{ MP_ROM_QSTR(MP_QSTR_Note), MP_ROM_PTR(&synthio_note_type) },
345+
{ MP_ROM_QSTR(MP_QSTR_EnvelopeState), MP_ROM_PTR(&synthio_note_state_type) },
319346
{ MP_ROM_QSTR(MP_QSTR_LFO), MP_ROM_PTR(&synthio_lfo_type) },
320347
{ MP_ROM_QSTR(MP_QSTR_Synthesizer), MP_ROM_PTR(&synthio_synthesizer_type) },
321348
{ MP_ROM_QSTR(MP_QSTR_from_file), MP_ROM_PTR(&synthio_from_file_obj) },

shared-bindings/synthio/__init__.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,16 @@
2929
#include "py/objnamedtuple.h"
3030
#include "py/enum.h"
3131

32+
typedef enum {
33+
SYNTHIO_ENVELOPE_STATE_ATTACK, SYNTHIO_ENVELOPE_STATE_DECAY,
34+
SYNTHIO_ENVELOPE_STATE_SUSTAIN, SYNTHIO_ENVELOPE_STATE_RELEASE
35+
} envelope_state_e;
36+
3237
typedef enum synthio_bend_mode_e {
3338
SYNTHIO_BEND_MODE_STATIC, SYNTHIO_BEND_MODE_VIBRATO, SYNTHIO_BEND_MODE_SWEEP, SYNTHIO_BEND_MODE_SWEEP_IN
3439
} synthio_bend_mode_t;
3540

41+
extern const mp_obj_type_t synthio_note_state_type;
3642
extern const cp_enum_obj_t bend_mode_VIBRATO_obj;
3743
extern const mp_obj_type_t synthio_bend_mode_type;
3844
typedef struct synthio_synth synthio_synth_t;

shared-module/synthio/Synthesizer.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,17 @@ mp_obj_t common_hal_synthio_synthesizer_get_pressed_notes(synthio_synthesizer_ob
185185
return MP_OBJ_FROM_PTR(result);
186186
}
187187

188+
envelope_state_e common_hal_synthio_synthesizer_note_info(synthio_synthesizer_obj_t *self, mp_obj_t note, mp_float_t *vol_out) {
189+
for (int chan = 0; chan < CIRCUITPY_SYNTHIO_MAX_CHANNELS; chan++) {
190+
if (self->synth.span.note_obj[chan] == note) {
191+
*vol_out = self->synth.envelope_state[chan].level / 32767.;
192+
return self->synth.envelope_state[chan].state;
193+
}
194+
}
195+
return (envelope_state_e) - 1;
196+
}
197+
198+
188199
mp_obj_t common_hal_synthio_synthesizer_get_blocks(synthio_synthesizer_obj_t *self) {
189200
return self->blocks;
190201
}

shared-module/synthio/__init__.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#define SYNTHIO_FREQUENCY_SHIFT (16)
3636

3737
#include "shared-module/audiocore/__init__.h"
38+
#include "shared-bindings/synthio/__init__.h"
3839

3940
typedef struct {
4041
uint16_t dur;
@@ -49,11 +50,6 @@ typedef struct {
4950
uint16_t attack_level, sustain_level;
5051
} synthio_envelope_definition_t;
5152

52-
typedef enum {
53-
SYNTHIO_ENVELOPE_STATE_ATTACK, SYNTHIO_ENVELOPE_STATE_DECAY,
54-
SYNTHIO_ENVELOPE_STATE_SUSTAIN, SYNTHIO_ENVELOPE_STATE_RELEASE
55-
} envelope_state_e;
56-
5753
typedef struct {
5854
int16_t level;
5955
uint16_t substep;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from synthio import Synthesizer, Note, Envelope
2+
from audiocore import get_buffer
3+
4+
s = Synthesizer()
5+
n = Note(440, envelope=Envelope())
6+
print("{} {:.2f}".format(*s.note_info(n)))
7+
s.press(n)
8+
print("press")
9+
for _ in range(9):
10+
print("{} {:.2f}".format(*s.note_info(n)))
11+
get_buffer(s)
12+
13+
s.release(n)
14+
print("release")
15+
for _ in range(11):
16+
print("{} {:.2f}".format(*s.note_info(n)))
17+
get_buffer(s)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
None 0.00
2+
press
3+
synthio.EnvelopeState.ATTACK 0.23
4+
synthio.EnvelopeState.ATTACK 0.46
5+
synthio.EnvelopeState.ATTACK 0.70
6+
synthio.EnvelopeState.ATTACK 0.93
7+
synthio.EnvelopeState.DECAY 1.00
8+
synthio.EnvelopeState.DECAY 0.91
9+
synthio.EnvelopeState.DECAY 0.81
10+
synthio.EnvelopeState.SUSTAIN 0.80
11+
synthio.EnvelopeState.SUSTAIN 0.80
12+
release
13+
synthio.EnvelopeState.RELEASE 0.80
14+
synthio.EnvelopeState.RELEASE 0.71
15+
synthio.EnvelopeState.RELEASE 0.61
16+
synthio.EnvelopeState.RELEASE 0.52
17+
synthio.EnvelopeState.RELEASE 0.43
18+
synthio.EnvelopeState.RELEASE 0.34
19+
synthio.EnvelopeState.RELEASE 0.24
20+
synthio.EnvelopeState.RELEASE 0.15
21+
synthio.EnvelopeState.RELEASE 0.06
22+
synthio.EnvelopeState.RELEASE 0.00
23+
None 0.00

tests/cmdline/cmd_showbc.py.exp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
File cmdline/cmd_showbc.py, code block '<module>' (descriptor: \.\+, bytecode @\.\+ bytes)
22
Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+):
33
########
4-
\.\+63
54
arg names:
65
(N_STATE 3)
76
(N_EXC_STACK 0)

0 commit comments

Comments
 (0)