diff --git a/Makefile b/Makefile index dab647a1..e2b1742c 100644 --- a/Makefile +++ b/Makefile @@ -39,6 +39,7 @@ SRCS = \ menu/png_decoder.c \ menu/rom_database.c \ menu/settings.c \ + menu/sound.c \ menu/views/browser.c \ menu/views/credits.c \ menu/views/error.c \ diff --git a/libdragon b/libdragon index a04292bf..251c8211 160000 --- a/libdragon +++ b/libdragon @@ -1 +1 @@ -Subproject commit a04292bf16db0931dc3ef616fa189c59f200bc1c +Subproject commit 251c821158cfc6099baa5577680223dc9897ef57 diff --git a/src/menu/menu.c b/src/menu/menu.c index 6ec767ec..bb552560 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -13,6 +13,7 @@ #include "mp3_player.h" #include "png_decoder.h" #include "settings.h" +#include "sound.h" #include "utils/fs.h" #include "views/views.h" @@ -55,13 +56,10 @@ static void menu_init (boot_params_t *boot_params) { controller_init(); timer_init(); rtc_init(); - audio_init(44100, 2); - mixer_init(2); rspq_init(); rdpq_init(); - fonts_init(); - mp3player_mixer_init(); + sound_init_default(); boot_pending = false; @@ -114,10 +112,9 @@ static void menu_deinit (menu_t *menu) { flashcart_deinit(); + sound_close(); rdpq_close(); rspq_close(); - mixer_close(); - audio_close(); rtc_close(); timer_close(); @@ -150,8 +147,6 @@ static struct views_s { void menu_run (boot_params_t *boot_params) { menu_init(boot_params); - int audio_buffer_length = audio_get_buffer_length(); - while (!boot_pending && (exception_reset_time() < RESET_TIME_LENGTH)) { surface_t *display = (frame_counter >= FRAMERATE_DIVIDER) ? display_try_get() : NULL; @@ -182,11 +177,7 @@ void menu_run (boot_params_t *boot_params) { time(&menu->current_time); } - while (audio_can_write()) { - short *audio_buffer = audio_write_begin(); - mixer_poll(audio_buffer, audio_buffer_length); - audio_write_end(); - } + sound_poll(); png_decoder_poll(); } diff --git a/src/menu/mp3_player.c b/src/menu/mp3_player.c index 76e43da4..bf5ded4f 100644 --- a/src/menu/mp3_player.c +++ b/src/menu/mp3_player.c @@ -2,6 +2,7 @@ #include #include "mp3_player.h" +#include "sound.h" #include "utils/fs.h" #include "utils/utils.h" @@ -11,7 +12,6 @@ #include -#define MIXER_CHANNEL (0) #define SEEK_PREDECODE_FRAMES (5) @@ -119,7 +119,7 @@ void mp3player_mixer_init (void) { // NOTE: Deliberately setting max_frequency to twice of actual maximum samplerate of mp3 file. // It's tricking mixer into creating buffer long enough for appending data created by mp3dec_decode_frame. - mixer_ch_set_limits(MIXER_CHANNEL, 16, 96000, 0); + mixer_ch_set_limits(SOUND_MP3_PLAYER_CHANNEL, 16, 96000, 0); } mp3player_err_t mp3player_init (void) { @@ -230,7 +230,7 @@ mp3player_err_t mp3player_process (void) { } bool mp3player_is_playing (void) { - return mixer_ch_playing(MIXER_CHANNEL); + return mixer_ch_playing(SOUND_MP3_PLAYER_CHANNEL); } bool mp3player_is_finished (void) { @@ -249,14 +249,14 @@ mp3player_err_t mp3player_play (void) { } mp3player_reset_decoder(); } - mixer_ch_play(MIXER_CHANNEL, &p->wave); + mixer_ch_play(SOUND_MP3_PLAYER_CHANNEL, &p->wave); } return MP3PLAYER_OK; } void mp3player_stop (void) { if (mp3player_is_playing()) { - mixer_ch_stop(MIXER_CHANNEL); + mixer_ch_stop(SOUND_MP3_PLAYER_CHANNEL); } } @@ -271,7 +271,7 @@ mp3player_err_t mp3player_toggle (void) { void mp3player_mute (bool mute) { float volume = mute ? 0.0f : 1.0f; - mixer_ch_set_vol(MIXER_CHANNEL, volume, volume); + mixer_ch_set_vol(SOUND_MP3_PLAYER_CHANNEL, volume, volume); } mp3player_err_t mp3player_seek (int seconds) { diff --git a/src/menu/sound.c b/src/menu/sound.c new file mode 100644 index 00000000..2286169f --- /dev/null +++ b/src/menu/sound.c @@ -0,0 +1,57 @@ +#include + +#include + +#include "mp3_player.h" + + +#define DEFAULT_FREQUENCY (44100) +#define NUM_BUFFERS (2) +#define NUM_CHANNELS (2) + + +static bool sound_initialized = false; + + +void sound_init_default (void) { + if (audio_get_frequency() != DEFAULT_FREQUENCY) { + if (sound_initialized) { + mixer_close(); + audio_close(); + } + audio_init(DEFAULT_FREQUENCY, NUM_BUFFERS); + mixer_init(NUM_CHANNELS); + mp3player_mixer_init(); + sound_initialized = true; + } +} + +void sound_init_mp3_playback (void) { + int frequency = mp3player_get_samplerate(); + if ((frequency > 0) && (audio_get_frequency() != frequency)) { + if (sound_initialized) { + mixer_close(); + audio_close(); + } + audio_init(frequency, NUM_BUFFERS); + mixer_init(NUM_CHANNELS); + mp3player_mixer_init(); + sound_initialized = true; + } +} + +void sound_poll (void) { + if (sound_initialized && audio_can_write()) { + short *audio_buffer = audio_write_begin(); + mixer_poll(audio_buffer, audio_get_buffer_length()); + audio_write_end(); + } +} + +void sound_close (void) { + if (sound_initialized) { + mixer_close(); + audio_close(); + sound_initialized = false; + } +} diff --git a/src/menu/sound.h b/src/menu/sound.h new file mode 100644 index 00000000..784dfca0 --- /dev/null +++ b/src/menu/sound.h @@ -0,0 +1,20 @@ +/** + * @file sound.h + * @brief Menu Sound + * @ingroup menu + */ + +#ifndef SOUND_H__ +#define SOUND_H__ + + +#define SOUND_MP3_PLAYER_CHANNEL (0) + + +void sound_init_default (void); +void sound_init_mp3_playback (void); +void sound_poll (void); +void sound_close (void); + + +#endif diff --git a/src/menu/views/music_player.c b/src/menu/views/music_player.c index c85ad3c3..4d059626 100644 --- a/src/menu/views/music_player.c +++ b/src/menu/views/music_player.c @@ -1,4 +1,5 @@ #include "../mp3_player.h" +#include "../sound.h" #include "views.h" @@ -109,6 +110,7 @@ static void draw (menu_t *menu, surface_t *d) { } static void deinit (void) { + sound_init_default(); mp3player_deinit(); } @@ -130,8 +132,13 @@ void view_music_player_init (menu_t *menu) { menu_show_error(menu, convert_error_message(err)); mp3player_deinit(); } else { + sound_init_mp3_playback(); mp3player_mute(false); - mp3player_play(); + err = mp3player_play(); + if (err != MP3PLAYER_OK) { + menu_show_error(menu, convert_error_message(err)); + mp3player_deinit(); + } } path_free(path);