Skip to content

Commit 9e4dea7

Browse files
authored
Merge pull request #7933 from jepler/synthio-note
synthio: add 'Note' with arbitrary frequency and more
2 parents 7cd65ff + c031bda commit 9e4dea7

File tree

29 files changed

+1101
-164
lines changed

29 files changed

+1101
-164
lines changed

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

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

1313
CIRCUITPY__EVE = 1
1414
CIRCUITPY_CANIO = 1
15+
CIRCUITPY_SYNTHIO = 0
1516

1617
CIRCUITPY_LTO_PARTITION = one

ports/raspberrypi/supervisor/internal_flash.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,16 @@ void port_internal_flash_flush(void) {
9595
if (_cache_lba == NO_CACHE) {
9696
return;
9797
}
98+
// Make sure we don't have an interrupt while we do flash operations.
9899
common_hal_mcu_disable_interrupts();
99100
flash_range_erase(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + _cache_lba, SECTOR_SIZE);
100101
flash_range_program(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + _cache_lba, _cache, SECTOR_SIZE);
101-
common_hal_mcu_enable_interrupts();
102102
_cache_lba = NO_CACHE;
103+
common_hal_mcu_enable_interrupts();
103104
}
104105

105106
mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) {
107+
port_internal_flash_flush(); // we never read out of the cache, so we have to write it if dirty
106108
memcpy(dest,
107109
(void *)(XIP_BASE + CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + block * FILESYSTEM_BLOCK_SIZE),
108110
num_blocks * FILESYSTEM_BLOCK_SIZE);
@@ -118,6 +120,7 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32
118120
uint8_t block_offset = block_address % blocks_per_sector;
119121

120122
if (_cache_lba != block_address) {
123+
port_internal_flash_flush();
121124
memcpy(_cache,
122125
(void *)(XIP_BASE + CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + sector_offset),
123126
SECTOR_SIZE);
@@ -133,11 +136,6 @@ mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t lba, uint32
133136
FILESYSTEM_BLOCK_SIZE);
134137
block++;
135138
}
136-
// Make sure we don't have an interrupt while we do flash operations.
137-
common_hal_mcu_disable_interrupts();
138-
flash_range_erase(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + sector_offset, SECTOR_SIZE);
139-
flash_range_program(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + sector_offset, _cache, SECTOR_SIZE);
140-
common_hal_mcu_enable_interrupts();
141139
}
142140

143141
return 0; // success

ports/unix/variants/coverage/mpconfigvariant.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ SRC_BITMAP := \
4242
shared-bindings/struct/__init__.c \
4343
shared-bindings/synthio/__init__.c \
4444
shared-bindings/synthio/MidiTrack.c \
45+
shared-bindings/synthio/Note.c \
4546
shared-bindings/synthio/Synthesizer.c \
4647
shared-bindings/traceback/__init__.c \
4748
shared-bindings/util.c \
@@ -64,6 +65,7 @@ SRC_BITMAP := \
6465
shared-module/struct/__init__.c \
6566
shared-module/synthio/__init__.c \
6667
shared-module/synthio/MidiTrack.c \
68+
shared-module/synthio/Note.c \
6769
shared-module/synthio/Synthesizer.c \
6870
shared-module/traceback/__init__.c \
6971
shared-module/zlib/__init__.c \

py/argcheck.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,16 @@ mp_float_t mp_arg_validate_type_float(mp_obj_t obj, qstr arg_name) {
194194
return a_float;
195195
}
196196

197-
void mp_arg_validate_obj_float_range(mp_obj_t float_in, mp_int_t min, mp_int_t max, qstr arg_name) {
197+
mp_float_t mp_arg_validate_obj_float_range(mp_obj_t float_in, mp_int_t min, mp_int_t max, qstr arg_name) {
198198
const mp_float_t f = mp_arg_validate_type_float(float_in, arg_name);
199+
return mp_arg_validate_float_range(f, min, max, arg_name);
200+
}
201+
202+
mp_float_t mp_arg_validate_float_range(mp_float_t f, mp_int_t min, mp_int_t max, qstr arg_name) {
199203
if (f < (mp_float_t)min || f > (mp_float_t)max) {
200204
mp_raise_ValueError_varg(translate("%q must be %d-%d"), arg_name, min, max);
201205
}
206+
return f;
202207
}
203208

204209
mp_float_t mp_arg_validate_obj_float_non_negative(mp_obj_t float_in, mp_float_t default_for_null, qstr arg_name) {

py/circuitpy_defns.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ SRC_SHARED_MODULE_ALL = \
651651
supervisor/__init__.c \
652652
supervisor/StatusBar.c \
653653
synthio/MidiTrack.c \
654+
synthio/Note.c \
654655
synthio/Synthesizer.c \
655656
synthio/__init__.c \
656657
terminalio/Terminal.c \

py/runtime.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ mp_int_t mp_arg_validate_int_max(mp_int_t i, mp_int_t j, qstr arg_name);
103103
mp_int_t mp_arg_validate_int_range(mp_int_t i, mp_int_t min, mp_int_t max, qstr arg_name);
104104
#if MICROPY_PY_BUILTINS_FLOAT
105105
mp_float_t mp_arg_validate_obj_float_non_negative(mp_obj_t float_in, mp_float_t default_for_null, qstr arg_name);
106-
void mp_arg_validate_obj_float_range(mp_obj_t float_in, mp_int_t min, mp_int_t max, qstr arg_name);
106+
mp_float_t mp_arg_validate_obj_float_range(mp_obj_t float_in, mp_int_t min, mp_int_t max, qstr arg_name);
107+
mp_float_t mp_arg_validate_float_range(mp_float_t float_in, mp_int_t min, mp_int_t max, qstr arg_name);
107108
mp_float_t mp_arg_validate_type_float(mp_obj_t obj, qstr arg_name);
108109
#endif
109110
mp_uint_t mp_arg_validate_length_min(mp_uint_t length, mp_uint_t min, qstr arg_name);

shared-bindings/synthio/Note.c

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2021 Artyom Skrobov
7+
* Copyright (c) 2023 Jeff Epler for Adafruit Industries
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#include <stdint.h>
29+
30+
#include "py/objproperty.h"
31+
#include "py/runtime.h"
32+
#include "shared-bindings/util.h"
33+
#include "shared-bindings/synthio/Note.h"
34+
#include "shared-module/synthio/Note.h"
35+
36+
static const mp_arg_t note_properties[] = {
37+
{ MP_QSTR_frequency, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = NULL } },
38+
{ MP_QSTR_amplitude, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(1) } },
39+
{ MP_QSTR_tremolo_rate, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = NULL } },
40+
{ MP_QSTR_tremolo_depth, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = NULL } },
41+
{ MP_QSTR_vibrato_rate, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = NULL } },
42+
{ MP_QSTR_vibrato_depth, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = NULL } },
43+
{ MP_QSTR_waveform, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } },
44+
{ MP_QSTR_envelope, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } },
45+
};
46+
//| class Note:
47+
//| def __init__(
48+
//| self,
49+
//| *,
50+
//| frequency: float,
51+
//| amplitude: float = 1.0,
52+
//| waveform: Optional[ReadableBuffer] = None,
53+
//| envelope: Optional[Envelope] = None,
54+
//| tremolo_depth: float = 0.0,
55+
//| tremolo_rate: float = 0.0,
56+
//| vibrato_depth: float = 0.0,
57+
//| vibrato_rate: float = 0.0,
58+
//| ) -> None:
59+
//| """Construct a Note object, with a frequency in Hz, and optional amplitude (volume), waveform, envelope, tremolo (volume change) and vibrato (frequency change).
60+
//|
61+
//| If waveform or envelope are `None` the synthesizer object's default waveform or envelope are used.
62+
//|
63+
//| If the same Note object is played on multiple Synthesizer objects, the result is undefined.
64+
//| """
65+
STATIC mp_obj_t synthio_note_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
66+
enum { ARG_frequency, ARG_amplitude, ARG_waveform, ARG_envelope, ARG_tremolo_rate, ARG_tremolo_depth, ARG_vibrato_rate, ARG_vibrato_depth };
67+
mp_arg_val_t args[MP_ARRAY_SIZE(note_properties)];
68+
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(note_properties), note_properties, args);
69+
70+
synthio_note_obj_t *self = m_new_obj(synthio_note_obj_t);
71+
self->base.type = &synthio_note_type;
72+
73+
mp_obj_t result = MP_OBJ_FROM_PTR(self);
74+
for (size_t i = 0; i < MP_ARRAY_SIZE(note_properties); i++) {
75+
if (args[i].u_obj != NULL) {
76+
mp_store_attr(result, note_properties[i].qst, args[i].u_obj);
77+
}
78+
}
79+
80+
return result;
81+
};
82+
83+
//| frequency: float
84+
//| """The base frequency of the note, in Hz."""
85+
STATIC mp_obj_t synthio_note_get_frequency(mp_obj_t self_in) {
86+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
87+
return mp_obj_new_float(common_hal_synthio_note_get_frequency(self));
88+
}
89+
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_frequency_obj, synthio_note_get_frequency);
90+
91+
STATIC mp_obj_t synthio_note_set_frequency(mp_obj_t self_in, mp_obj_t arg) {
92+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
93+
common_hal_synthio_note_set_frequency(self, mp_obj_get_float(arg));
94+
return mp_const_none;
95+
}
96+
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_frequency_obj, synthio_note_set_frequency);
97+
MP_PROPERTY_GETSET(synthio_note_frequency_obj,
98+
(mp_obj_t)&synthio_note_get_frequency_obj,
99+
(mp_obj_t)&synthio_note_set_frequency_obj);
100+
101+
//| amplitude: float
102+
//| """The base amplitude of the note, from 0 to 1"""
103+
STATIC mp_obj_t synthio_note_get_amplitude(mp_obj_t self_in) {
104+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
105+
return mp_obj_new_float(common_hal_synthio_note_get_amplitude(self));
106+
}
107+
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_amplitude_obj, synthio_note_get_amplitude);
108+
109+
STATIC mp_obj_t synthio_note_set_amplitude(mp_obj_t self_in, mp_obj_t arg) {
110+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
111+
common_hal_synthio_note_set_amplitude(self, mp_obj_get_float(arg));
112+
return mp_const_none;
113+
}
114+
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_amplitude_obj, synthio_note_set_amplitude);
115+
MP_PROPERTY_GETSET(synthio_note_amplitude_obj,
116+
(mp_obj_t)&synthio_note_get_amplitude_obj,
117+
(mp_obj_t)&synthio_note_set_amplitude_obj);
118+
119+
120+
//| tremolo_depth: float
121+
//| """The tremolo depth of the note, from 0 to 1
122+
//|
123+
//| A depth of 0 disables tremolo. A nonzero value enables tremolo,
124+
//| with the maximum decrease in amplitude being equal to the tremolo
125+
//| depth. A note with a tremolo depth of 1 will fade out to nothing, while
126+
//| a tremolo depth of 0.1 will give a minimum amplitude of 0.9."""
127+
STATIC mp_obj_t synthio_note_get_tremolo_depth(mp_obj_t self_in) {
128+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
129+
return mp_obj_new_float(common_hal_synthio_note_get_tremolo_depth(self));
130+
}
131+
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_tremolo_depth_obj, synthio_note_get_tremolo_depth);
132+
133+
STATIC mp_obj_t synthio_note_set_tremolo_depth(mp_obj_t self_in, mp_obj_t arg) {
134+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
135+
common_hal_synthio_note_set_tremolo_depth(self, mp_obj_get_float(arg));
136+
return mp_const_none;
137+
}
138+
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_tremolo_depth_obj, synthio_note_set_tremolo_depth);
139+
MP_PROPERTY_GETSET(synthio_note_tremolo_depth_obj,
140+
(mp_obj_t)&synthio_note_get_tremolo_depth_obj,
141+
(mp_obj_t)&synthio_note_set_tremolo_depth_obj);
142+
143+
//| tremolo_rate: float
144+
//| """The tremolo rate of the note, in Hz."""
145+
STATIC mp_obj_t synthio_note_get_tremolo_rate(mp_obj_t self_in) {
146+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
147+
return mp_obj_new_float(common_hal_synthio_note_get_tremolo_rate(self));
148+
}
149+
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_tremolo_rate_obj, synthio_note_get_tremolo_rate);
150+
151+
STATIC mp_obj_t synthio_note_set_tremolo_rate(mp_obj_t self_in, mp_obj_t arg) {
152+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
153+
common_hal_synthio_note_set_tremolo_rate(self, mp_obj_get_float(arg));
154+
return mp_const_none;
155+
}
156+
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_tremolo_rate_obj, synthio_note_set_tremolo_rate);
157+
MP_PROPERTY_GETSET(synthio_note_tremolo_rate_obj,
158+
(mp_obj_t)&synthio_note_get_tremolo_rate_obj,
159+
(mp_obj_t)&synthio_note_set_tremolo_rate_obj);
160+
161+
//| vibrato_depth: float
162+
//| """The vibrato depth of the note, from 0 to 1
163+
//|
164+
//| A depth of 0 disables vibrato. A depth of 1 corresponds to a vibrato of ±1
165+
//| octave. A depth of (1/12) = 0.833 corresponds to a vibrato of ±1 semitone,
166+
//| and a depth of .00833 corresponds to one musical cent.
167+
//| """
168+
STATIC mp_obj_t synthio_note_get_vibrato_depth(mp_obj_t self_in) {
169+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
170+
return mp_obj_new_float(common_hal_synthio_note_get_vibrato_depth(self));
171+
}
172+
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_vibrato_depth_obj, synthio_note_get_vibrato_depth);
173+
174+
STATIC mp_obj_t synthio_note_set_vibrato_depth(mp_obj_t self_in, mp_obj_t arg) {
175+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
176+
common_hal_synthio_note_set_vibrato_depth(self, mp_obj_get_float(arg));
177+
return mp_const_none;
178+
}
179+
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_vibrato_depth_obj, synthio_note_set_vibrato_depth);
180+
MP_PROPERTY_GETSET(synthio_note_vibrato_depth_obj,
181+
(mp_obj_t)&synthio_note_get_vibrato_depth_obj,
182+
(mp_obj_t)&synthio_note_set_vibrato_depth_obj);
183+
184+
//| vibrato_rate: float
185+
//| """The vibrato rate of the note, in Hz."""
186+
STATIC mp_obj_t synthio_note_get_vibrato_rate(mp_obj_t self_in) {
187+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
188+
return mp_obj_new_float(common_hal_synthio_note_get_vibrato_rate(self));
189+
}
190+
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_vibrato_rate_obj, synthio_note_get_vibrato_rate);
191+
192+
STATIC mp_obj_t synthio_note_set_vibrato_rate(mp_obj_t self_in, mp_obj_t arg) {
193+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
194+
common_hal_synthio_note_set_vibrato_rate(self, mp_obj_get_float(arg));
195+
return mp_const_none;
196+
}
197+
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_vibrato_rate_obj, synthio_note_set_vibrato_rate);
198+
MP_PROPERTY_GETSET(synthio_note_vibrato_rate_obj,
199+
(mp_obj_t)&synthio_note_get_vibrato_rate_obj,
200+
(mp_obj_t)&synthio_note_set_vibrato_rate_obj);
201+
202+
//| waveform: Optional[ReadableBuffer]
203+
//| """The waveform of this note. Setting the waveform to a buffer of a different size resets the note's phase."""
204+
STATIC mp_obj_t synthio_note_get_waveform(mp_obj_t self_in) {
205+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
206+
return common_hal_synthio_note_get_waveform_obj(self);
207+
}
208+
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_waveform_obj, synthio_note_get_waveform);
209+
210+
STATIC mp_obj_t synthio_note_set_waveform(mp_obj_t self_in, mp_obj_t arg) {
211+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
212+
common_hal_synthio_note_set_waveform(self, arg);
213+
return mp_const_none;
214+
}
215+
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_waveform_obj, synthio_note_set_waveform);
216+
MP_PROPERTY_GETSET(synthio_note_waveform_obj,
217+
(mp_obj_t)&synthio_note_get_waveform_obj,
218+
(mp_obj_t)&synthio_note_set_waveform_obj);
219+
220+
221+
//| envelope: Envelope
222+
//| """The envelope of this note"""
223+
//|
224+
STATIC mp_obj_t synthio_note_get_envelope(mp_obj_t self_in) {
225+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
226+
return common_hal_synthio_note_get_envelope_obj(self);
227+
}
228+
MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_envelope_obj, synthio_note_get_envelope);
229+
230+
STATIC mp_obj_t synthio_note_set_envelope(mp_obj_t self_in, mp_obj_t arg) {
231+
synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in);
232+
common_hal_synthio_note_set_envelope(self, arg);
233+
return mp_const_none;
234+
}
235+
MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_envelope_obj, synthio_note_set_envelope);
236+
MP_PROPERTY_GETSET(synthio_note_envelope_obj,
237+
(mp_obj_t)&synthio_note_get_envelope_obj,
238+
(mp_obj_t)&synthio_note_set_envelope_obj);
239+
240+
static void note_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
241+
(void)kind;
242+
properties_print_helper(print, self_in, note_properties, MP_ARRAY_SIZE(note_properties));
243+
}
244+
245+
STATIC const mp_rom_map_elem_t synthio_note_locals_dict_table[] = {
246+
{ MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&synthio_note_frequency_obj) },
247+
{ MP_ROM_QSTR(MP_QSTR_amplitude), MP_ROM_PTR(&synthio_note_amplitude_obj) },
248+
{ MP_ROM_QSTR(MP_QSTR_waveform), MP_ROM_PTR(&synthio_note_waveform_obj) },
249+
{ MP_ROM_QSTR(MP_QSTR_envelope), MP_ROM_PTR(&synthio_note_envelope_obj) },
250+
{ MP_ROM_QSTR(MP_QSTR_tremolo_depth), MP_ROM_PTR(&synthio_note_tremolo_depth_obj) },
251+
{ MP_ROM_QSTR(MP_QSTR_tremolo_rate), MP_ROM_PTR(&synthio_note_tremolo_rate_obj) },
252+
{ MP_ROM_QSTR(MP_QSTR_vibrato_depth), MP_ROM_PTR(&synthio_note_vibrato_depth_obj) },
253+
{ MP_ROM_QSTR(MP_QSTR_vibrato_rate), MP_ROM_PTR(&synthio_note_vibrato_rate_obj) },
254+
};
255+
STATIC MP_DEFINE_CONST_DICT(synthio_note_locals_dict, synthio_note_locals_dict_table);
256+
257+
const mp_obj_type_t synthio_note_type = {
258+
{ &mp_type_type },
259+
.name = MP_QSTR_Note,
260+
.make_new = synthio_note_make_new,
261+
.locals_dict = (mp_obj_dict_t *)&synthio_note_locals_dict,
262+
.print = note_print,
263+
};

shared-bindings/synthio/Note.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#pragma once
2+
3+
#include "py/obj.h"
4+
5+
typedef struct synthio_note_obj synthio_note_obj_t;
6+
extern const mp_obj_type_t synthio_note_type;
7+
8+
mp_float_t common_hal_synthio_note_get_frequency(synthio_note_obj_t *self);
9+
void common_hal_synthio_note_set_frequency(synthio_note_obj_t *self, mp_float_t value);
10+
11+
mp_float_t common_hal_synthio_note_get_amplitude(synthio_note_obj_t *self);
12+
void common_hal_synthio_note_set_amplitude(synthio_note_obj_t *self, mp_float_t value);
13+
14+
mp_float_t common_hal_synthio_note_get_tremolo_rate(synthio_note_obj_t *self);
15+
void common_hal_synthio_note_set_tremolo_rate(synthio_note_obj_t *self, mp_float_t value);
16+
17+
mp_float_t common_hal_synthio_note_get_tremolo_depth(synthio_note_obj_t *self);
18+
void common_hal_synthio_note_set_tremolo_depth(synthio_note_obj_t *self, mp_float_t value);
19+
20+
mp_float_t common_hal_synthio_note_get_vibrato_rate(synthio_note_obj_t *self);
21+
void common_hal_synthio_note_set_vibrato_rate(synthio_note_obj_t *self, mp_float_t value);
22+
23+
mp_float_t common_hal_synthio_note_get_vibrato_depth(synthio_note_obj_t *self);
24+
void common_hal_synthio_note_set_vibrato_depth(synthio_note_obj_t *self, mp_float_t value);
25+
26+
mp_obj_t common_hal_synthio_note_get_waveform_obj(synthio_note_obj_t *self);
27+
void common_hal_synthio_note_set_waveform(synthio_note_obj_t *self, mp_obj_t value);
28+
29+
mp_obj_t common_hal_synthio_note_get_envelope_obj(synthio_note_obj_t *self);
30+
void common_hal_synthio_note_set_envelope(synthio_note_obj_t *self, mp_obj_t value);

0 commit comments

Comments
 (0)