Exposed remaining AudioChannel parameters

pull/537/head
ZodiusInfuser 2022-08-26 19:32:39 +01:00 zatwierdzone przez Phil Howard
rodzic 2695982182
commit df79caf34e
7 zmienionych plików z 347 dodań i 136 usunięć

Wyświetl plik

@ -68,7 +68,7 @@ int main() {
i++;
graphics.set_pen(0, 0, 0);
graphics.clear();
float s = 0.8f;//0.65f + (sin(i / 25.0f) * 0.15f);
float a = 1.0f;// (sin(i / 25.0f) * 100.0f);
@ -76,7 +76,7 @@ int main() {
float y = (cos((i) / 40.0f) * 5.0f);
graphics.set_pen(255, 255, 255);
text("Galactic Unicorn", Point(x, y), s, a);
uint8_t *p = (uint8_t *)graphics.frame_buffer;
for(size_t i = 0; i < 53 * 11; i++) {
int x = i % 53;
@ -92,14 +92,11 @@ int main() {
b = hue_map[x][2];
}
galactic_unicorn.set_pixel(x, y, r, g, b);
graphics.set_pen(r, g, b);
graphics.pixel(Point(x, y));
}
}
printf("done\n");
return 0;

Wyświetl plik

@ -56,6 +56,20 @@ namespace pimoroni {
adsr_step = 0;
}
void AudioChannel::restore() {
// Put all the parameters back to their initial values
waveforms = 0;
frequency = 660;
volume = 0xffff;
attack_ms = 2;
decay_ms = 6;
sustain = 0xffff;
release_ms = 1;
pulse_width = 0x7fff;
noise = 0;
}
bool PicoSynth::is_audio_playing() {
if(volume == 0) {
return false;

Wyświetl plik

@ -69,11 +69,11 @@ namespace pimoroni {
struct AudioChannel {
uint8_t waveforms = 0; // bitmask for enabled waveforms (see Waveform enum for values)
uint16_t frequency = 660; // frequency of the voice (Hz)
uint16_t volume = 0xffff; // channel volume
uint16_t volume = UINT16_MAX; // channel volume
uint16_t attack_ms = 2; // attack period (cannot be zero)
uint16_t decay_ms = 6; // decay period (cannot be zero)
uint16_t sustain = 0xffff; // sustain volume
uint16_t sustain = UINT16_MAX; // sustain volume
uint16_t release_ms = 1; // release period
uint16_t pulse_width = 0x7fff; // duty cycle of square wave (default 50%)
int16_t noise = 0; // current noise value
@ -101,6 +101,7 @@ namespace pimoroni {
void trigger_sustain();
void trigger_release();
void off();
void restore();
};
class PicoSynth {

Wyświetl plik

@ -712,7 +712,7 @@ def next_beat():
global beat
for i in range(5):
if notes[i][beat] > 0:
channels[i].freq(notes[i][beat])
channels[i].frequency(notes[i][beat])
channels[i].trigger_attack()
elif notes[i][beat] == -1:
channels[i].trigger_release()
@ -736,36 +736,36 @@ while True:
if gu.is_pressed(GalacticUnicorn.SWITCH_A):
if not was_a_pressed:
channel0.configure(Channel.TRIANGLE + Channel.SQUARE,
16,
168,
0,
168,
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)
channel0.configure(waveforms=Channel.TRIANGLE + Channel.SQUARE,
attack=0.016,
decay=0.168,
sustain=0,
release=0.168,
volume=0)
channel1.configure(waveforms=Channel.SINE + Channel.SQUARE,
attack=0.038,
decay=0.300,
sustain=0,
release=0,
volume=12000/65535)
channel2.configure(waveforms=Channel.NOISE,
attack=0.005,
decay=0.010,
sustain=16000/65535,
release=0.100,
volume=0)
channel3.configure(waveforms=Channel.NOISE,
attack=0.005,
decay=0.005,
sustain=8000/65535,
release=0.040,
volume=0)
channel4.configure(waveforms=Channel.SQUARE,
attack=0.010,
decay=0.100,
sustain=0,
release=0.500,
volume=0)
if not synthing:
beat = 0
next_beat()
@ -797,7 +797,7 @@ while True:
timer.deinit()
freq_b = 600
channel1.play_tone(freq_b, 0.06, fade_in=0.5)
channel1.play_tone(freq_b, 0.06, attack=0.5)
gu.play_synth()
synthing = False
@ -822,57 +822,57 @@ while True:
if gu.is_pressed(GalacticUnicorn.SWITCH_BRIGHTNESS_UP):
# gu.adjust_brightness(+0.01)
if bool_playing:
freq_b += 10
channel1.freq(freq_b)
freq_b = min(freq_b + 10, 20000)
channel1.frequency(freq_b)
if gu.is_pressed(GalacticUnicorn.SWITCH_BRIGHTNESS_DOWN):
# gu.adjust_brightness(-0.01)
if bool_playing:
freq_b -= 10
channel1.freq(freq_b)
freq_b = max(freq_b - 10, 10)
channel1.frequency(max(freq_b, 10))
if gu.is_pressed(GalacticUnicorn.SWITCH_VOLUME_UP):
if bool_playing:
freq_a += 10
channel0.freq(freq_a)
freq_a = min(freq_a + 10, 20000)
channel0.frequency(freq_a)
if gu.is_pressed(GalacticUnicorn.SWITCH_VOLUME_DOWN):
if bool_playing:
freq_a -= 10
channel0.freq(freq_a)
freq_a = max(freq_a - 10, 10)
channel0.frequency(freq_a)
if gu.is_pressed(GalacticUnicorn.SWITCH_SLEEP):
if not was_z_pressed:
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)
channel0.configure(waveforms=Channel.TRIANGLE + Channel.SQUARE,
attack=0.016,
decay=0.168,
sustain=0xafff/65535,
release=0.168,
volume=10000/65535)
channel1.configure(waveforms=Channel.SINE + Channel.SQUARE,
attack=0.038,
decay=0.300,
sustain=0,
release=0,
volume=12000/65535)
channel2.configure(waveforms=Channel.NOISE,
attack=0.005,
decay=0.010,
sustain=16000/65535,
release=0.100,
volume=18000/65535)
channel3.configure(waveforms=Channel.NOISE,
attack=0.005,
decay=0.005,
sustain=8000/65535,
release=0.040,
volume=8000/65535)
channel4.configure(waveforms=Channel.SQUARE,
attack=0.010,
decay=0.100,
sustain=0,
release=0.500,
volume=12000/65535)
if not synthing:
beat = 0
next_beat()

Wyświetl plik

@ -3,11 +3,20 @@
/***** 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_KW(Channel_configure_obj, 1, Channel_configure);
MP_DEFINE_CONST_FUN_OBJ_1(Channel_restore_obj, Channel_restore);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(Channel_waveforms_obj, 1, 2, Channel_waveforms);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(Channel_frequency_obj, 1, 2, Channel_frequency);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(Channel_volume_obj, 1, 2, Channel_volume);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(Channel_attack_duration_obj, 1, 2, Channel_attack_duration);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(Channel_decay_duration_obj, 1, 2, Channel_decay_duration);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(Channel_sustain_level_obj, 1, 2, Channel_sustain_level);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(Channel_release_duration_obj, 1, 2, Channel_release_duration);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(Channel_pulse_width_obj, 1, 2, Channel_pulse_width);
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(Channel_stop_playing_obj, Channel_stop_playing);
MP_DEFINE_CONST_FUN_OBJ_1(GalacticUnicorn___del___obj, GalacticUnicorn___del__);
MP_DEFINE_CONST_FUN_OBJ_1(GalacticUnicorn_clear_obj, GalacticUnicorn_clear);
@ -29,7 +38,15 @@ MP_DEFINE_CONST_FUN_OBJ_2(GalacticUnicorn_synth_channel_obj, GalacticUnicorn_syn
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_restore), MP_ROM_PTR(&Channel_restore_obj) },
{ MP_ROM_QSTR(MP_QSTR_waveforms), MP_ROM_PTR(&Channel_waveforms_obj) },
{ MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&Channel_frequency_obj) },
{ MP_ROM_QSTR(MP_QSTR_volume), MP_ROM_PTR(&Channel_volume_obj) },
{ MP_ROM_QSTR(MP_QSTR_attack_duration), MP_ROM_PTR(&Channel_attack_duration_obj) },
{ MP_ROM_QSTR(MP_QSTR_decay_duration), MP_ROM_PTR(&Channel_decay_duration_obj) },
{ MP_ROM_QSTR(MP_QSTR_sustain_level), MP_ROM_PTR(&Channel_sustain_level_obj) },
{ MP_ROM_QSTR(MP_QSTR_release_duration), MP_ROM_PTR(&Channel_release_duration_obj) },
{ MP_ROM_QSTR(MP_QSTR_pulse_width), MP_ROM_PTR(&Channel_pulse_width_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) },

Wyświetl plik

@ -45,17 +45,86 @@ mp_obj_t Channel___del__(mp_obj_t self_in) {
}
/***** Helper Functions *****/
void set_channel_waveforms(AudioChannel& channel, mp_obj_t in) {
int waveforms = mp_obj_get_int(in);
const int mask = (NOISE | SQUARE | SAW | TRIANGLE | SINE | WAVE);
if(waveforms < 0 || (waveforms & mask) == 0) {
mp_raise_ValueError("waveforms invalid. Expected a combination of NOISE, SQUARE, SAW, TRIANGLE, SINE, or WAVE");
}
channel.waveforms = (uint8_t)waveforms;
}
void set_channel_frequency(AudioChannel& channel, mp_obj_t in) {
int freq = mp_obj_get_int(in);
if(freq <= 0 || freq > UINT16_MAX) {
mp_raise_ValueError("frequency out of range. Expected greater than 0Hz to 65535Hz");
}
channel.frequency = (uint16_t)freq;
}
void set_channel_volume(AudioChannel& channel, mp_obj_t in) {
float volume = mp_obj_get_float(in);
if(volume < 0.0f || volume > 1.0f) {
mp_raise_ValueError("volume out of range. Expected 0.0 to 1.0");
}
channel.volume = (uint16_t)(volume * UINT16_MAX);
}
void set_channel_attack(AudioChannel& channel, mp_obj_t in) {
int attack_ms = (int)(mp_obj_get_float(in) * 1000.0f);
if(attack_ms < 0 || attack_ms > UINT16_MAX) {
mp_raise_ValueError("attack out of range. Expected 0.0s to 65.5s");
}
channel.attack_ms = MAX(attack_ms, 1);
}
void set_channel_decay(AudioChannel& channel, mp_obj_t in) {
int decay_ms = (int)(mp_obj_get_float(in) * 1000.0f);
if(decay_ms < 0 || decay_ms > UINT16_MAX) {
mp_raise_ValueError("decay out of range. Expected 0.0s to 65.5s");
}
channel.decay_ms = MAX(decay_ms, 1);
}
void set_channel_sustain(AudioChannel& channel, mp_obj_t in) {
float sustain = mp_obj_get_float(in);
if(sustain < 0.0f || sustain > 1.0f) {
mp_raise_ValueError("sustain out of range. Expected 0.0 to 1.0");
}
channel.sustain = (uint16_t)(sustain * UINT16_MAX);
}
void set_channel_release(AudioChannel& channel, mp_obj_t in) {
int release_ms = (int)(mp_obj_get_float(in) * 1000.0f);
if(release_ms < 0 || release_ms > UINT16_MAX) {
mp_raise_ValueError("release out of range. Expected 0.0s to 65.5s");
}
channel.release_ms = MAX(release_ms, 1);
}
void set_channel_pulse_width(AudioChannel& channel, mp_obj_t in) {
float pulse_width = mp_obj_get_float(in);
if(pulse_width < 0.0f || pulse_width > 1.0f) {
mp_raise_ValueError("pulse_width out of range. Expected 0.0 to 1.0");
}
channel.pulse_width = (uint16_t)(pulse_width * UINT16_MAX);
}
/***** 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 };
enum { ARG_self, ARG_waveforms, ARG_frequency, ARG_volume, ARG_attack, ARG_decay, ARG_sustain, ARG_release, ARG_pulse_width };
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 },
{ MP_QSTR_waveforms, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_frequency, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_volume, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_attack, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_decay, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_sustain, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_release, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_pulse_width, MP_ARG_OBJ, {.u_obj = mp_const_none} }
};
// Parse args.
@ -64,25 +133,140 @@ mp_obj_t Channel_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw
_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;
mp_obj_t waveforms = args[ARG_waveforms].u_obj;
if(waveforms != mp_const_none) {
set_channel_waveforms(*self->channel, waveforms);
}
mp_obj_t frequency = args[ARG_frequency].u_obj;
if(frequency != mp_const_none) {
set_channel_frequency(*self->channel, frequency);
}
mp_obj_t volume = args[ARG_volume].u_obj;
if(volume != mp_const_none) {
set_channel_volume(*self->channel, volume);
}
mp_obj_t attack = args[ARG_attack].u_obj;
if(attack != mp_const_none) {
set_channel_attack(*self->channel, attack);
}
mp_obj_t decay = args[ARG_decay].u_obj;
if(decay != mp_const_none) {
set_channel_decay(*self->channel, decay);
}
mp_obj_t sustain = args[ARG_sustain].u_obj;
if(sustain != mp_const_none) {
set_channel_sustain(*self->channel, sustain);
}
mp_obj_t release = args[ARG_release].u_obj;
if(release != mp_const_none) {
set_channel_release(*self->channel, release);
}
mp_obj_t pulse_width = args[ARG_pulse_width].u_obj;
if(pulse_width != mp_const_none) {
set_channel_pulse_width(*self->channel, pulse_width);
}
return mp_const_none;
}
mp_obj_t Channel_freq(mp_obj_t self_in, mp_obj_t freq_in) {
mp_obj_t Channel_restore(mp_obj_t self_in) {
_Channel_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Channel_obj_t);
self->channel->restore();
return mp_const_none;
}
float freq = mp_obj_get_float(freq_in);
if(freq <= 0.0f) {
mp_raise_ValueError("freq out of range. Expected greater than 0.0");
mp_obj_t Channel_waveforms(size_t n_args, const mp_obj_t *args) {
_Channel_obj_t *self = MP_OBJ_TO_PTR2(args[0], _Channel_obj_t);
if(n_args == 1) {
return mp_obj_new_int(self->channel->waveforms);
}
self->channel->frequency = freq;
set_channel_waveforms(*self->channel, args[1]);
return mp_const_none;
}
mp_obj_t Channel_frequency(size_t n_args, const mp_obj_t *args) {
_Channel_obj_t *self = MP_OBJ_TO_PTR2(args[0], _Channel_obj_t);
if(n_args == 1) {
return mp_obj_new_int(self->channel->frequency);
}
set_channel_frequency(*self->channel, args[1]);
return mp_const_none;
}
mp_obj_t Channel_volume(size_t n_args, const mp_obj_t *args) {
_Channel_obj_t *self = MP_OBJ_TO_PTR2(args[0], _Channel_obj_t);
if(n_args == 1) {
return mp_obj_new_float((float)self->channel->volume / UINT16_MAX);
}
set_channel_volume(*self->channel, args[1]);
return mp_const_none;
}
mp_obj_t Channel_attack_duration(size_t n_args, const mp_obj_t *args) {
_Channel_obj_t *self = MP_OBJ_TO_PTR2(args[0], _Channel_obj_t);
if(n_args == 1) {
return mp_obj_new_float((float)self->channel->attack_ms / 1000.0f);
}
set_channel_attack(*self->channel, args[1]);
return mp_const_none;
}
mp_obj_t Channel_decay_duration(size_t n_args, const mp_obj_t *args) {
_Channel_obj_t *self = MP_OBJ_TO_PTR2(args[0], _Channel_obj_t);
if(n_args == 1) {
return mp_obj_new_float((float)self->channel->decay_ms / 1000.0f);
}
set_channel_decay(*self->channel, args[1]);
return mp_const_none;
}
mp_obj_t Channel_sustain_level(size_t n_args, const mp_obj_t *args) {
_Channel_obj_t *self = MP_OBJ_TO_PTR2(args[0], _Channel_obj_t);
if(n_args == 1) {
return mp_obj_new_float((float)self->channel->sustain / UINT16_MAX);
}
set_channel_sustain(*self->channel, args[1]);
return mp_const_none;
}
mp_obj_t Channel_release_duration(size_t n_args, const mp_obj_t *args) {
_Channel_obj_t *self = MP_OBJ_TO_PTR2(args[0], _Channel_obj_t);
if(n_args == 1) {
return mp_obj_new_float((float)self->channel->release_ms / 1000.0f);
}
set_channel_release(*self->channel, args[1]);
return mp_const_none;
}
mp_obj_t Channel_pulse_width(size_t n_args, const mp_obj_t *args) {
_Channel_obj_t *self = MP_OBJ_TO_PTR2(args[0], _Channel_obj_t);
if(n_args == 1) {
return mp_obj_new_float((float)self->channel->pulse_width / 0xffff);
}
set_channel_pulse_width(*self->channel, args[1]);
return mp_const_none;
}
@ -104,10 +288,10 @@ mp_obj_t Channel_play_tone(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw
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_frequency, 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} },
{ MP_QSTR_attack, MP_ARG_OBJ, {.u_obj = mp_const_none} },
{ MP_QSTR_release, MP_ARG_OBJ, {.u_obj = mp_const_none} },
};
// Parse args.
@ -116,45 +300,35 @@ mp_obj_t Channel_play_tone(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw
_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");
set_channel_frequency(*self->channel, args[ARG_freq].u_obj);
mp_obj_t volume = args[ARG_volume].u_obj;
if(volume != mp_const_none) {
set_channel_volume(*self->channel, volume);
}
else {
self->channel->volume = UINT16_MAX;
}
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");
}
mp_obj_t attack_ms = args[ARG_fade_in].u_obj;
if(attack_ms != mp_const_none) {
set_channel_attack(*self->channel, attack_ms);
}
else {
self->channel->attack_ms = 1;
}
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);
mp_obj_t release_ms = args[ARG_fade_out].u_obj;
if(release_ms != mp_const_none) {
set_channel_release(*self->channel, release_ms);
}
else {
self->channel->release_ms = 1;
}
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->sustain = UINT16_MAX;
self->channel->trigger_attack();

Wyświetl plik

@ -10,11 +10,19 @@ extern void Channel_print(const mp_print_t *print, mp_obj_t self_in, mp_print_ki
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_restore(mp_obj_t self_in);
extern mp_obj_t Channel_waveforms(size_t n_args, const mp_obj_t *args);
extern mp_obj_t Channel_frequency(size_t n_args, const mp_obj_t *args);
extern mp_obj_t Channel_volume(size_t n_args, const mp_obj_t *args);
extern mp_obj_t Channel_attack_duration(size_t n_args, const mp_obj_t *args);
extern mp_obj_t Channel_decay_duration(size_t n_args, const mp_obj_t *args);
extern mp_obj_t Channel_sustain_level(size_t n_args, const mp_obj_t *args);
extern mp_obj_t Channel_release_duration(size_t n_args, const mp_obj_t *args);
extern mp_obj_t Channel_pulse_width(size_t n_args, const mp_obj_t *args);
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 mp_obj_t Channel_stop_playing(mp_obj_t self_in);
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);