diff --git a/components/micropython/usermodule/mp_media.c b/components/micropython/usermodule/mp_media.c index 07554e86d8ea2f1c3ef813c56ce13a59bb7df5a7..0e138eb4b76a429948703cb386cb255c9e0a604c 100644 --- a/components/micropython/usermodule/mp_media.c +++ b/components/micropython/usermodule/mp_media.c @@ -77,6 +77,17 @@ STATIC mp_obj_t mp_seek_relative(mp_obj_t time) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_seek_relative_obj, mp_seek_relative); +STATIC mp_obj_t mp_set_volume(mp_obj_t volume) { + st3m_media_set_volume(mp_obj_get_float(volume)); + return 0; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_set_volume_obj, mp_set_volume); + +STATIC mp_obj_t mp_get_volume(void) { + return mp_obj_new_float(st3m_media_get_volume()); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_get_volume_obj, mp_get_volume); + STATIC mp_obj_t mp_set(mp_obj_t key, mp_obj_t value) { st3m_media_set(mp_obj_str_get_str(key), mp_obj_get_float(value)); return 0; @@ -108,6 +119,8 @@ STATIC const mp_rom_map_elem_t globals_table[] = { { MP_ROM_QSTR(MP_QSTR_get_time), MP_ROM_PTR(&mp_get_time_obj) }, { MP_ROM_QSTR(MP_QSTR_seek), MP_ROM_PTR(&mp_seek_obj) }, { MP_ROM_QSTR(MP_QSTR_seek_relative), MP_ROM_PTR(&mp_seek_relative_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_volume), MP_ROM_PTR(&mp_set_volume_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_volume), MP_ROM_PTR(&mp_get_volume_obj) }, { MP_ROM_QSTR(MP_QSTR_set), MP_ROM_PTR(&mp_set_obj) }, { MP_ROM_QSTR(MP_QSTR_get), MP_ROM_PTR(&mp_get_obj) }, { MP_ROM_QSTR(MP_QSTR_get_string), MP_ROM_PTR(&mp_get_string_obj) }, diff --git a/components/st3m/st3m_media.c b/components/st3m/st3m_media.c index def69c2204a9e520d6594fe4cd32d568654b4c98..cc01ef87437b7f8a9439e0c50dd52350b1c07f54 100644 --- a/components/st3m/st3m_media.c +++ b/components/st3m/st3m_media.c @@ -18,10 +18,10 @@ static int16_t *audio_buffer = NULL; // st3m_audio_player_function void bl00mbox_audio_render(int16_t *rx, int16_t *tx, uint16_t len); -static inline int16_t mix_and_clip(int16_t a, int16_t b) { - if (a == 0) return b; +static inline int16_t mix_and_clip(int16_t a, int16_t b, int16_t gain) { + if (a == 0 && gain == 4096) return b; int32_t val = a; - val += b; + val += (b * gain) >> 12; if (val > 32767) { val = 32767; } else if (val < -32767) { @@ -38,7 +38,8 @@ void st3m_media_audio_render(int16_t *rx, int16_t *tx, uint16_t len) { (audio_media->audio_r + 1 - AUDIO_BUF_SIZE != audio_media->audio_w)) { tx[i] = mix_and_clip( - tx[i], audio_media->audio_buffer[audio_media->audio_r++]); + tx[i], audio_media->audio_buffer[audio_media->audio_r++], + audio_media->volume); if (audio_media->audio_r >= AUDIO_BUF_SIZE) audio_media->audio_r = 0; } @@ -101,6 +102,16 @@ void st3m_media_seek_relative(float time) { st3m_media_seek((audio_media->position * audio_media->duration) + time); } +void st3m_media_set_volume(float volume) { + if (!audio_media) return; + audio_media->volume = volume * 4096; +} + +float st3m_media_get_volume(void) { + if (!audio_media) return 0; + return audio_media->volume / 4096.0; +} + void st3m_media_draw(Ctx *ctx) { if (audio_media && audio_media->draw) audio_media->draw(audio_media, ctx); } @@ -211,6 +222,7 @@ int st3m_media_load(const char *path) { audio_media->audio_buffer = audio_buffer; audio_media->audio_r = 0; audio_media->audio_w = 1; + audio_media->volume = 4096; return 1; } diff --git a/components/st3m/st3m_media.h b/components/st3m/st3m_media.h index 714fa47eee7d78d9757ae1ad8348c20c430babce..a0286395f2e506b89d855ef0a956155aaa7feeed 100644 --- a/components/st3m/st3m_media.h +++ b/components/st3m/st3m_media.h @@ -49,6 +49,9 @@ struct _st3m_media { // decoder should seek to this relative if not -1, and set it to -1 float seek; + // audio volume + int volume; + // if set to 1 playback is momentarily stopped but can be resumed, // this is toggled by st3m_media_play | st3m_media_pause int paused; @@ -82,6 +85,10 @@ float st3m_media_get_position(void); void st3m_media_seek(float position); // seek a relative amount of seconds forward or with negative values back void st3m_media_seek_relative(float seconds_jump); +// set audio volume (0.0 - 1.0) +void st3m_media_set_volume(float volume); +// get audio volume +float st3m_media_get_volume(void); // get decoder specific string or NULL if not existing, free returned value // common values: