Started splitting out synth into separate channel objects

This commit is contained in:
ZodiusInfuser 2022-08-25 17:27:53 +01:00 committed by Phil Howard
parent 882f76dcbc
commit 53dfb9866d
6 changed files with 287 additions and 159 deletions

View File

@ -444,6 +444,11 @@ namespace pimoroni {
}
}
AudioChannel& GalacticUnicorn::synth_channel(uint channel) {
assert(channel < PicoSynth::CHANNEL_COUNT);
return synth.channels[channel];
}
void GalacticUnicorn::set_pixel(int x, int y, uint8_t r, uint8_t g, uint8_t b) {
if(x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT) return;

View File

@ -75,10 +75,8 @@ namespace pimoroni {
int16_t tone_buffers[NUM_TONE_BUFFERS][TONE_BUFFER_SIZE] = {0};
uint current_buffer = 0;
public:
PicoSynth synth;
private:
enum PlayMode {
PLAYING_BUFFER,
//PLAYING_TONE,
@ -116,6 +114,7 @@ namespace pimoroni {
void play_sample(uint8_t *data, uint32_t length);
void play_synth();
void stop_playing();
AudioChannel& synth_channel(uint channel);
private:
void next_bitstream_sequence();

View File

@ -2,7 +2,7 @@ import gc
import time
import math
from machine import Timer
from galactic import GalacticUnicorn
from galactic import GalacticUnicorn, Channel
from picographics import PicoGraphics, DISPLAY_GALACTIC_UNICORN as DISPLAY
gc.collect()
@ -700,15 +700,22 @@ freq_b = 0
beat = 0
channel0 = gu.synth_channel(0)
channel1 = gu.synth_channel(1)
channel2 = gu.synth_channel(2)
channel3 = gu.synth_channel(3)
channel4 = gu.synth_channel(7)
channels = [channel0, channel1, channel2, channel3, channel4]
def next_beat():
global beat
for i in range(5):
if notes[i][beat] > 0:
gu.channel_freq(i, notes[i][beat])
gu.channel_trigger_attack(i)
channels[i].freq(notes[i][beat])
channels[i].trigger_attack()
elif notes[i][beat] == -1:
gu.channel_trigger_release(i)
channels[i].trigger_release()
beat = (beat + 1) % SONG_LENGTH
@ -729,36 +736,36 @@ while True:
if gu.is_pressed(GalacticUnicorn.SWITCH_A):
if not was_a_pressed:
gu.channel_configure(0, gu.WF_TRIANGLE + gu.WF_SQUARE,
16,
channel0.configure(Channel.TRIANGLE + Channel.SQUARE,
16,
168,
0,
168,
0)
gu.channel_configure(1, gu.WF_SINE + gu.WF_SQUARE,
38,
300,
0,
0,
12000)
gu.channel_configure(2, gu.WF_NOISE,
5,
10,
16000,
100,
0)
gu.channel_configure(3, gu.WF_NOISE,
5,
5,
8000,
40,
0)
gu.channel_configure(4, gu.WF_SQUARE,
10,
100,
0,
500,
0)
channel1.configure(Channel.SINE + Channel.SQUARE,
38,
300,
0,
0,
12000)
channel2.configure(Channel.NOISE,
5,
10,
16000,
100,
0)
channel3.configure(Channel.NOISE,
5,
5,
8000,
40,
0)
channel4.configure(Channel.SQUARE,
10,
100,
0,
500,
0)
if not synthing:
beat = 0
next_beat()
@ -774,21 +781,8 @@ while True:
if not was_b_pressed:
timer.deinit()
freq_a = 400
channel0.play_tone(freq_a, 0.06)
gu.channel_freq(0, freq_a)
gu.channel_configure(0, gu.WF_SINE,
1,
1,
0xffff,
1,
4000)
gu.channel_configure(1, gu.WF_SINE,
1,
1,
0xffff,
1,
4000)
gu.channel_trigger_attack(0)
gu.play_synth()
synthing = False
@ -803,21 +797,8 @@ while True:
timer.deinit()
freq_b = 600
gu.channel_freq(1, freq_b)
gu.channel_configure(0, gu.WF_SINE,
1,
1,
0xffff,
1,
4000)
gu.channel_configure(1, gu.WF_SINE,
1,
1,
0xffff,
1,
4000)
channel1.play_tone(freq_b, 0.06, fade_in=0.5)
gu.channel_trigger_attack(1)
gu.play_synth()
synthing = False
@ -842,56 +823,56 @@ while True:
# gu.adjust_brightness(+0.01)
if bool_playing:
freq_b += 10
gu.channel_freq(1, freq_b)
channel1.freq(freq_b)
if gu.is_pressed(GalacticUnicorn.SWITCH_BRIGHTNESS_DOWN):
# gu.adjust_brightness(-0.01)
if bool_playing:
freq_b -= 10
gu.channel_freq(1, freq_b)
channel1.freq(freq_b)
if gu.is_pressed(GalacticUnicorn.SWITCH_VOLUME_UP):
if bool_playing:
freq_a += 10
gu.channel_freq(0, freq_a)
channel0.freq(freq_a)
if gu.is_pressed(GalacticUnicorn.SWITCH_VOLUME_DOWN):
if bool_playing:
freq_a -= 10
gu.channel_freq(0, freq_a)
channel0.freq(freq_a)
if gu.is_pressed(GalacticUnicorn.SWITCH_SLEEP):
if not was_z_pressed:
gu.channel_configure(0, gu.WF_TRIANGLE + gu.WF_SQUARE,
16,
168,
0xafff,
168,
10000)
gu.channel_configure(1, gu.WF_SINE + gu.WF_SQUARE,
38,
300,
0,
0,
12000)
gu.channel_configure(2, gu.WF_NOISE,
5,
10,
16000,
100,
18000)
gu.channel_configure(3, gu.WF_NOISE,
5,
5,
8000,
40,
8000)
gu.channel_configure(4, gu.WF_SQUARE,
10,
100,
0,
500,
12000)
channel0.configure(Channel.TRIANGLE + Channel.SQUARE,
16,
168,
0xafff,
168,
10000)
channel1.configure(Channel.SINE + Channel.SQUARE,
38,
300,
0,
0,
12000)
channel2.configure(Channel.NOISE,
5,
10,
16000,
100,
18000)
channel3.configure(Channel.NOISE,
5,
5,
8000,
40,
8000)
channel4.configure(Channel.SQUARE,
10,
100,
0,
500,
12000)
if not synthing:
beat = 0
next_beat()

View File

@ -2,6 +2,13 @@
/***** Methods *****/
MP_DEFINE_CONST_FUN_OBJ_1(Channel___del___obj, Channel___del__);
MP_DEFINE_CONST_FUN_OBJ_KW(Channel_configure_obj, 6, Channel_configure);
MP_DEFINE_CONST_FUN_OBJ_2(Channel_freq_obj, Channel_freq);
MP_DEFINE_CONST_FUN_OBJ_1(Channel_trigger_attack_obj, Channel_trigger_attack);
MP_DEFINE_CONST_FUN_OBJ_1(Channel_trigger_release_obj, Channel_trigger_release);
MP_DEFINE_CONST_FUN_OBJ_KW(Channel_play_tone_obj, 2, Channel_play_tone);
MP_DEFINE_CONST_FUN_OBJ_1(GalacticUnicorn___del___obj, GalacticUnicorn___del__);
MP_DEFINE_CONST_FUN_OBJ_1(GalacticUnicorn_clear_obj, GalacticUnicorn_clear);
MP_DEFINE_CONST_FUN_OBJ_2(GalacticUnicorn_update_obj, GalacticUnicorn_update);
@ -16,12 +23,25 @@ MP_DEFINE_CONST_FUN_OBJ_2(GalacticUnicorn_is_pressed_obj, GalacticUnicorn_is_pre
MP_DEFINE_CONST_FUN_OBJ_2(GalacticUnicorn_play_sample_obj, GalacticUnicorn_play_sample);
MP_DEFINE_CONST_FUN_OBJ_1(GalacticUnicorn_play_synth_obj, GalacticUnicorn_play_synth);
MP_DEFINE_CONST_FUN_OBJ_1(GalacticUnicorn_stop_playing_obj, GalacticUnicorn_stop_playing);
MP_DEFINE_CONST_FUN_OBJ_KW(GalacticUnicorn_channel_configure_obj, 7, GalacticUnicorn_channel_configure);
MP_DEFINE_CONST_FUN_OBJ_3(GalacticUnicorn_channel_freq_obj, GalacticUnicorn_channel_freq);
MP_DEFINE_CONST_FUN_OBJ_2(GalacticUnicorn_channel_trigger_attack_obj, GalacticUnicorn_channel_trigger_attack);
MP_DEFINE_CONST_FUN_OBJ_2(GalacticUnicorn_channel_trigger_release_obj, GalacticUnicorn_channel_trigger_release);
MP_DEFINE_CONST_FUN_OBJ_2(GalacticUnicorn_synth_channel_obj, GalacticUnicorn_synth_channel);
/***** Binding of Methods *****/
STATIC const mp_rom_map_elem_t Channel_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&Channel___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_configure), MP_ROM_PTR(&Channel_configure_obj) },
{ MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&Channel_freq_obj) },
{ MP_ROM_QSTR(MP_QSTR_trigger_attack), MP_ROM_PTR(&Channel_trigger_attack_obj) },
{ MP_ROM_QSTR(MP_QSTR_trigger_release), MP_ROM_PTR(&Channel_trigger_release_obj) },
{ MP_ROM_QSTR(MP_QSTR_play_tone), MP_ROM_PTR(&Channel_play_tone_obj) },
{ MP_ROM_QSTR(MP_QSTR_NOISE), MP_ROM_INT(128) },
{ MP_ROM_QSTR(MP_QSTR_SQUARE), MP_ROM_INT(64) },
{ MP_ROM_QSTR(MP_QSTR_SAW), MP_ROM_INT(32) },
{ MP_ROM_QSTR(MP_QSTR_TRIANGLE), MP_ROM_INT(16) },
{ MP_ROM_QSTR(MP_QSTR_SINE), MP_ROM_INT(8) },
{ MP_ROM_QSTR(MP_QSTR_WAVE), MP_ROM_INT(1) },
};
STATIC const mp_rom_map_elem_t GalacticUnicorn_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&GalacticUnicorn___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&GalacticUnicorn_clear_obj) },
@ -37,10 +57,7 @@ STATIC const mp_rom_map_elem_t GalacticUnicorn_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_play_sample), MP_ROM_PTR(&GalacticUnicorn_play_sample_obj) },
{ MP_ROM_QSTR(MP_QSTR_play_synth), MP_ROM_PTR(&GalacticUnicorn_play_synth_obj) },
{ MP_ROM_QSTR(MP_QSTR_stop_playing), MP_ROM_PTR(&GalacticUnicorn_stop_playing_obj) },
{ MP_ROM_QSTR(MP_QSTR_channel_configure), MP_ROM_PTR(&GalacticUnicorn_channel_configure_obj) },
{ MP_ROM_QSTR(MP_QSTR_channel_freq), MP_ROM_PTR(&GalacticUnicorn_channel_freq_obj) },
{ MP_ROM_QSTR(MP_QSTR_channel_trigger_attack), MP_ROM_PTR(&GalacticUnicorn_channel_trigger_attack_obj) },
{ MP_ROM_QSTR(MP_QSTR_channel_trigger_release), MP_ROM_PTR(&GalacticUnicorn_channel_trigger_release_obj) },
{ MP_ROM_QSTR(MP_QSTR_synth_channel), MP_ROM_PTR(&GalacticUnicorn_synth_channel_obj) },
{ MP_ROM_QSTR(MP_QSTR_WIDTH), MP_ROM_INT(53) },
{ MP_ROM_QSTR(MP_QSTR_HEIGHT), MP_ROM_INT(11) },
@ -54,18 +71,20 @@ STATIC const mp_rom_map_elem_t GalacticUnicorn_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_SWITCH_VOLUME_DOWN), MP_ROM_INT(8) },
{ MP_ROM_QSTR(MP_QSTR_SWITCH_BRIGHTNESS_UP), MP_ROM_INT(21) },
{ MP_ROM_QSTR(MP_QSTR_SWITCH_BRIGHTNESS_DOWN), MP_ROM_INT(26) },
{ MP_ROM_QSTR(MP_QSTR_WF_NOISE), MP_ROM_INT(128) },
{ MP_ROM_QSTR(MP_QSTR_WF_SQUARE), MP_ROM_INT(64) },
{ MP_ROM_QSTR(MP_QSTR_WF_SAW), MP_ROM_INT(32) },
{ MP_ROM_QSTR(MP_QSTR_WF_TRIANGLE), MP_ROM_INT(16) },
{ MP_ROM_QSTR(MP_QSTR_WF_SINE), MP_ROM_INT(8) },
{ MP_ROM_QSTR(MP_QSTR_WF_WAVE), MP_ROM_INT(1) },
};
STATIC MP_DEFINE_CONST_DICT(Channel_locals_dict, Channel_locals_dict_table);
STATIC MP_DEFINE_CONST_DICT(GalacticUnicorn_locals_dict, GalacticUnicorn_locals_dict_table);
/***** Class Definition *****/
const mp_obj_type_t Channel_type = {
{ &mp_type_type },
.name = MP_QSTR_Channel,
.print = Channel_print,
.make_new = Channel_make_new,
.locals_dict = (mp_obj_dict_t*)&Channel_locals_dict,
};
const mp_obj_type_t GalacticUnicorn_type = {
{ &mp_type_type },
.name = MP_QSTR_GalacticUnicorn,
@ -77,6 +96,7 @@ const mp_obj_type_t GalacticUnicorn_type = {
/***** Globals Table *****/
STATIC const mp_map_elem_t galactic_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_galactic) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_Channel), (mp_obj_t)&Channel_type },
{ MP_OBJ_NEW_QSTR(MP_QSTR_GalacticUnicorn), (mp_obj_t)&GalacticUnicorn_type },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_galactic_globals, galactic_globals_table);

View File

@ -13,6 +13,155 @@ extern "C" {
#include "py/builtin.h"
/********** Channel **********/
/***** Variables Struct *****/
typedef struct _Channel_obj_t {
mp_obj_base_t base;
AudioChannel* channel;
} _Channel_obj_t;
/***** Print *****/
void Channel_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
(void)kind; //Unused input parameter
//_Channel_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Channel_obj_t);
//AudioChannel* channel = self->channel;
mp_print_str(print, "Channel(");
mp_print_str(print, ")");
}
/***** Constructor *****/
mp_obj_t Channel_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
mp_raise_msg(&mp_type_RuntimeError, "Cannot create Channel objects. They can only be accessed from GalacticUnicorn.synth_channel()");
return mp_const_none;
}
/***** Destructor ******/
mp_obj_t Channel___del__(mp_obj_t self_in) {
return mp_const_none;
}
/***** Methods *****/
mp_obj_t Channel_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_waveforms, ARG_attack_ms, ARG_decay_ms, ARG_sustain, ARG_release_ms, ARG_volume };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_waveforms, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_attack_ms, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_decay_ms, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_sustain, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_release_ms, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_volumes, MP_ARG_REQUIRED | MP_ARG_INT },
};
// Parse args.
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
_Channel_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, _Channel_obj_t);
self->channel->waveforms = args[ARG_waveforms].u_int;
self->channel->attack_ms = args[ARG_attack_ms].u_int;
self->channel->decay_ms = args[ARG_decay_ms].u_int;
self->channel->sustain = args[ARG_sustain].u_int;
self->channel->release_ms = args[ARG_release_ms].u_int;
self->channel->volume = args[ARG_volume].u_int;
return mp_const_none;
}
mp_obj_t Channel_freq(mp_obj_t self_in, mp_obj_t freq_in) {
_Channel_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Channel_obj_t);
float freq = mp_obj_get_float(freq_in);
if(freq <= 0.0f) {
mp_raise_ValueError("freq out of range. Expected greater than 0.0");
}
self->channel->frequency = freq;
return mp_const_none;
}
mp_obj_t Channel_trigger_attack(mp_obj_t self_in) {
_Channel_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Channel_obj_t);
self->channel->trigger_attack();
return mp_const_none;
}
mp_obj_t Channel_trigger_release(mp_obj_t self_in) {
_Channel_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Channel_obj_t);
self->channel->trigger_release();
return mp_const_none;
}
mp_obj_t Channel_play_tone(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_freq, ARG_volume, ARG_fade_in, ARG_fade_out };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_freq, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_volume, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_fade_in, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_fade_out, MP_ARG_OBJ, {.u_obj = mp_const_none} },
};
// Parse args.
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
_Channel_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, _Channel_obj_t);
float freq = mp_obj_get_float(args[ARG_freq].u_obj);
if(freq <= 0.0f) {
mp_raise_ValueError("freq out of range. Expected greater than 0.0");
}
float volume = 1.0f;
if(args[ARG_volume].u_obj != mp_const_none) {
volume = mp_obj_get_float(args[ARG_volume].u_obj);
if(volume < 0.0f || volume > 1.0f) {
mp_raise_ValueError("volume out of range. Expected 0.0 to 1.0");
}
}
int fade_in_ms = 1;
if(args[ARG_fade_in].u_obj != mp_const_none) {
float fade_in = mp_obj_get_float(args[ARG_fade_in].u_obj);
if(fade_in <= 0.0f) {
mp_raise_ValueError("fade_in out of range. Expected greater than 0.0");
}
fade_in_ms = (uint16_t)(fade_in * 1000.0f);
}
int fade_out_ms = 1;
if(args[ARG_fade_out].u_obj != mp_const_none) {
float fade_out = mp_obj_get_float(args[ARG_fade_out].u_obj);
if(fade_out <= 0.0f) {
mp_raise_ValueError("fade_out out of range. Expected greater than 0.0");
}
fade_out_ms = (uint16_t)(fade_out * 1000.0f);
}
self->channel->frequency = freq;
self->channel->waveforms = Waveform::SINE;
self->channel->attack_ms = MAX(fade_in_ms, 1);
self->channel->decay_ms = 1;
self->channel->sustain = 0xffff;
self->channel->release_ms = MAX(fade_out_ms, 1);
self->channel->volume = (uint16_t)(volume * 0xffff);
self->channel->trigger_attack();
return mp_const_none;
}
/********** GalacticUnicorn **********/
/***** Variables Struct *****/
@ -173,55 +322,21 @@ extern mp_obj_t GalacticUnicorn_stop_playing(mp_obj_t self_in) {
return mp_const_none;
}
extern mp_obj_t GalacticUnicorn_channel_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_channel, ARG_waveforms, ARG_attack_ms, ARG_decay_ms, ARG_sustain, ARG_release_ms, ARG_volume };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_channel, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_waveforms, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_attack_ms, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_decay_ms, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_sustain, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_release_ms, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_volumes, MP_ARG_REQUIRED | MP_ARG_INT },
};
// Parse args.
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
_GalacticUnicorn_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, _GalacticUnicorn_obj_t);
int c = args[ARG_channel].u_int;
self->galactic->synth.channels[c].waveforms = args[ARG_waveforms].u_int;
self->galactic->synth.channels[c].attack_ms = args[ARG_attack_ms].u_int;
self->galactic->synth.channels[c].decay_ms = args[ARG_decay_ms].u_int;
self->galactic->synth.channels[c].sustain = args[ARG_sustain].u_int;
self->galactic->synth.channels[c].release_ms = args[ARG_release_ms].u_int;
self->galactic->synth.channels[c].volume = args[ARG_volume].u_int;
return mp_const_none;
}
extern mp_obj_t GalacticUnicorn_channel_freq(mp_obj_t self_in, mp_obj_t channel, mp_obj_t freq) {
extern mp_obj_t GalacticUnicorn_synth_channel(mp_obj_t self_in, mp_obj_t channel_in) {
_GalacticUnicorn_obj_t *self = MP_OBJ_TO_PTR2(self_in, _GalacticUnicorn_obj_t);
self->galactic->synth.channels[mp_obj_get_int(channel)].frequency = mp_obj_get_float(freq);
// Check that the channel is valid
int channel = mp_obj_get_int(channel_in);
if(channel < 0 || channel >= (int)PicoSynth::CHANNEL_COUNT) {
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("channel out of range. Expected 0 to %d"), PicoSynth::CHANNEL_COUNT - 1);
}
return mp_const_none;
}
// NOTE This seems to work, in that it give MP access to the calibration object
// Could very easily mess up in weird ways once object deletion is considered?
_Channel_obj_t *channel_obj = m_new_obj_with_finaliser(_Channel_obj_t);
channel_obj->base.type = &Channel_type;
channel_obj->channel = &self->galactic->synth_channel(channel);
extern mp_obj_t GalacticUnicorn_channel_trigger_attack(mp_obj_t self_in, mp_obj_t channel) {
_GalacticUnicorn_obj_t *self = MP_OBJ_TO_PTR2(self_in, _GalacticUnicorn_obj_t);
self->galactic->synth.channels[mp_obj_get_int(channel)].trigger_attack();
return mp_const_none;
}
extern mp_obj_t GalacticUnicorn_channel_trigger_release(mp_obj_t self_in, mp_obj_t channel) {
_GalacticUnicorn_obj_t *self = MP_OBJ_TO_PTR2(self_in, _GalacticUnicorn_obj_t);
self->galactic->synth.channels[mp_obj_get_int(channel)].trigger_release();
return mp_const_none;
return MP_OBJ_FROM_PTR(channel_obj);
}
}

View File

@ -2,9 +2,20 @@
#include "py/runtime.h"
/***** Extern of Class Definition *****/
extern const mp_obj_type_t Channel_type;
extern const mp_obj_type_t GalacticUnicorn_type;
/***** Extern of Class Methods *****/
extern void Channel_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind);
extern mp_obj_t Channel_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
extern mp_obj_t Channel___del__(mp_obj_t self_in);
extern mp_obj_t Channel_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t Channel_freq(mp_obj_t self_in, mp_obj_t freq_in);
extern mp_obj_t Channel_trigger_attack(mp_obj_t self_in);
extern mp_obj_t Channel_trigger_release(mp_obj_t self_in);
extern mp_obj_t Channel_play_tone(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern void GalacticUnicorn_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind);
extern mp_obj_t GalacticUnicorn_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
extern mp_obj_t GalacticUnicorn___del__(mp_obj_t self_in);
@ -28,7 +39,4 @@ extern mp_obj_t GalacticUnicorn_play_sample(mp_obj_t self_in, mp_obj_t data);
extern mp_obj_t GalacticUnicorn_play_synth(mp_obj_t self_in);
extern mp_obj_t GalacticUnicorn_stop_playing(mp_obj_t self_in);
extern mp_obj_t GalacticUnicorn_channel_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);;
extern mp_obj_t GalacticUnicorn_channel_freq(mp_obj_t self_in, mp_obj_t channel, mp_obj_t freq);
extern mp_obj_t GalacticUnicorn_channel_trigger_attack(mp_obj_t self_in, mp_obj_t channel);
extern mp_obj_t GalacticUnicorn_channel_trigger_release(mp_obj_t self_in, mp_obj_t channel);
extern mp_obj_t GalacticUnicorn_synth_channel(mp_obj_t self_in, mp_obj_t channel_in);