Use native sample rate for MP3 playback

This commit is contained in:
Mateusz Faderewski 2023-08-18 15:37:56 +02:00
parent bd7e33ed71
commit f1649c2436
7 changed files with 97 additions and 21 deletions

View File

@ -39,6 +39,7 @@ SRCS = \
menu/png_decoder.c \ menu/png_decoder.c \
menu/rom_database.c \ menu/rom_database.c \
menu/settings.c \ menu/settings.c \
menu/sound.c \
menu/views/browser.c \ menu/views/browser.c \
menu/views/credits.c \ menu/views/credits.c \
menu/views/error.c \ menu/views/error.c \

@ -1 +1 @@
Subproject commit a04292bf16db0931dc3ef616fa189c59f200bc1c Subproject commit 251c821158cfc6099baa5577680223dc9897ef57

View File

@ -13,6 +13,7 @@
#include "mp3_player.h" #include "mp3_player.h"
#include "png_decoder.h" #include "png_decoder.h"
#include "settings.h" #include "settings.h"
#include "sound.h"
#include "utils/fs.h" #include "utils/fs.h"
#include "views/views.h" #include "views/views.h"
@ -55,13 +56,10 @@ static void menu_init (boot_params_t *boot_params) {
controller_init(); controller_init();
timer_init(); timer_init();
rtc_init(); rtc_init();
audio_init(44100, 2);
mixer_init(2);
rspq_init(); rspq_init();
rdpq_init(); rdpq_init();
fonts_init(); fonts_init();
mp3player_mixer_init(); sound_init_default();
boot_pending = false; boot_pending = false;
@ -114,10 +112,9 @@ static void menu_deinit (menu_t *menu) {
flashcart_deinit(); flashcart_deinit();
sound_close();
rdpq_close(); rdpq_close();
rspq_close(); rspq_close();
mixer_close();
audio_close();
rtc_close(); rtc_close();
timer_close(); timer_close();
@ -150,8 +147,6 @@ static struct views_s {
void menu_run (boot_params_t *boot_params) { void menu_run (boot_params_t *boot_params) {
menu_init(boot_params); menu_init(boot_params);
int audio_buffer_length = audio_get_buffer_length();
while (!boot_pending && (exception_reset_time() < RESET_TIME_LENGTH)) { while (!boot_pending && (exception_reset_time() < RESET_TIME_LENGTH)) {
surface_t *display = (frame_counter >= FRAMERATE_DIVIDER) ? display_try_get() : NULL; 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); time(&menu->current_time);
} }
while (audio_can_write()) { sound_poll();
short *audio_buffer = audio_write_begin();
mixer_poll(audio_buffer, audio_buffer_length);
audio_write_end();
}
png_decoder_poll(); png_decoder_poll();
} }

View File

@ -2,6 +2,7 @@
#include <libdragon.h> #include <libdragon.h>
#include "mp3_player.h" #include "mp3_player.h"
#include "sound.h"
#include "utils/fs.h" #include "utils/fs.h"
#include "utils/utils.h" #include "utils/utils.h"
@ -11,7 +12,6 @@
#include <minimp3/minimp3.h> #include <minimp3/minimp3.h>
#define MIXER_CHANNEL (0)
#define SEEK_PREDECODE_FRAMES (5) #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. // 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. // 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) { mp3player_err_t mp3player_init (void) {
@ -230,7 +230,7 @@ mp3player_err_t mp3player_process (void) {
} }
bool mp3player_is_playing (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) { bool mp3player_is_finished (void) {
@ -249,14 +249,14 @@ mp3player_err_t mp3player_play (void) {
} }
mp3player_reset_decoder(); mp3player_reset_decoder();
} }
mixer_ch_play(MIXER_CHANNEL, &p->wave); mixer_ch_play(SOUND_MP3_PLAYER_CHANNEL, &p->wave);
} }
return MP3PLAYER_OK; return MP3PLAYER_OK;
} }
void mp3player_stop (void) { void mp3player_stop (void) {
if (mp3player_is_playing()) { 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) { void mp3player_mute (bool mute) {
float volume = mute ? 0.0f : 1.0f; 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) { mp3player_err_t mp3player_seek (int seconds) {

57
src/menu/sound.c Normal file
View File

@ -0,0 +1,57 @@
#include <stdbool.h>
#include <libdragon.h>
#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;
}
}

20
src/menu/sound.h Normal file
View File

@ -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

View File

@ -1,4 +1,5 @@
#include "../mp3_player.h" #include "../mp3_player.h"
#include "../sound.h"
#include "views.h" #include "views.h"
@ -109,6 +110,7 @@ static void draw (menu_t *menu, surface_t *d) {
} }
static void deinit (void) { static void deinit (void) {
sound_init_default();
mp3player_deinit(); mp3player_deinit();
} }
@ -130,8 +132,13 @@ void view_music_player_init (menu_t *menu) {
menu_show_error(menu, convert_error_message(err)); menu_show_error(menu, convert_error_message(err));
mp3player_deinit(); mp3player_deinit();
} else { } else {
sound_init_mp3_playback();
mp3player_mute(false); 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); path_free(path);