mirror of
https://github.com/Polprzewodnikowy/N64FlashcartMenu.git
synced 2024-11-22 10:39:20 +01:00
MP3 player improvements - track duration and info display
This commit is contained in:
parent
b3509f4295
commit
d61a1a1cc7
@ -5,6 +5,7 @@
|
|||||||
#include "actions.h"
|
#include "actions.h"
|
||||||
#include "menu_state.h"
|
#include "menu_state.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
#include "mp3player.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "utils/fs.h"
|
#include "utils/fs.h"
|
||||||
#include "views/views.h"
|
#include "views/views.h"
|
||||||
@ -24,6 +25,8 @@ static void menu_init (settings_t *settings) {
|
|||||||
rspq_init();
|
rspq_init();
|
||||||
rdpq_init();
|
rdpq_init();
|
||||||
|
|
||||||
|
mp3player_mixer_init();
|
||||||
|
|
||||||
boot_pending = false;
|
boot_pending = false;
|
||||||
|
|
||||||
menu = calloc(1, sizeof(menu_t));
|
menu = calloc(1, sizeof(menu_t));
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include "libs/minimp3/minimp3_ex.h"
|
#include "libs/minimp3/minimp3_ex.h"
|
||||||
|
|
||||||
|
|
||||||
#define BUFFER_SIZE (16 * 1024)
|
|
||||||
#define MIXER_CHANNEL (0)
|
#define MIXER_CHANNEL (0)
|
||||||
|
|
||||||
|
|
||||||
@ -17,19 +16,18 @@ typedef struct {
|
|||||||
bool loaded;
|
bool loaded;
|
||||||
bool io_error;
|
bool io_error;
|
||||||
|
|
||||||
mp3dec_t dec;
|
|
||||||
mp3dec_frame_info_t info;
|
|
||||||
|
|
||||||
FIL fil;
|
FIL fil;
|
||||||
FSIZE_t data_start;
|
FSIZE_t data_start;
|
||||||
|
|
||||||
uint8_t buffer[BUFFER_SIZE];
|
mp3dec_t dec;
|
||||||
|
mp3dec_frame_info_t info;
|
||||||
|
|
||||||
|
uint8_t buffer[24 * 1024];
|
||||||
uint8_t *buffer_ptr;
|
uint8_t *buffer_ptr;
|
||||||
size_t buffer_left;
|
size_t buffer_left;
|
||||||
|
|
||||||
short samples[MINIMP3_MAX_SAMPLES_PER_FRAME];
|
float duration;
|
||||||
short *samples_ptr;
|
float bitrate;
|
||||||
int samples_left;
|
|
||||||
|
|
||||||
waveform_t wave;
|
waveform_t wave;
|
||||||
} mp3player_t;
|
} mp3player_t;
|
||||||
@ -41,8 +39,6 @@ static void mp3player_reset_decoder (void) {
|
|||||||
mp3dec_init(&p->dec);
|
mp3dec_init(&p->dec);
|
||||||
p->buffer_ptr = p->buffer;
|
p->buffer_ptr = p->buffer;
|
||||||
p->buffer_left = 0;
|
p->buffer_left = 0;
|
||||||
p->samples_ptr = p->samples;
|
|
||||||
p->samples_left = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mp3player_fill_buffer (void) {
|
static void mp3player_fill_buffer (void) {
|
||||||
@ -61,59 +57,64 @@ static void mp3player_fill_buffer (void) {
|
|||||||
p->buffer_ptr = p->buffer;
|
p->buffer_ptr = p->buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f_read(&p->fil, p->buffer + p->buffer_left, BUFFER_SIZE - p->buffer_left, &bytes_read) == FR_OK) {
|
if (f_read(&p->fil, p->buffer + p->buffer_left, sizeof(p->buffer) - p->buffer_left, &bytes_read) == FR_OK) {
|
||||||
p->buffer_left += bytes_read;
|
p->buffer_left += bytes_read;
|
||||||
} else {
|
} else {
|
||||||
p->io_error = true;
|
p->io_error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mp3player_decode_samples (short *buffer, int buffer_samples) {
|
static void mp3player_wave_read (void *ctx, samplebuffer_t *sbuf, int wpos, int wlen, bool seeking) {
|
||||||
if (p->samples_left > 0) {
|
while (wlen > 0) {
|
||||||
int samples_to_copy = MIN(p->samples_left, buffer_samples);
|
|
||||||
|
|
||||||
memcpy(buffer, p->samples_ptr, samples_to_copy * sizeof(short) * p->info.channels);
|
|
||||||
|
|
||||||
p->samples_ptr += samples_to_copy * p->info.channels;
|
|
||||||
p->samples_left -= samples_to_copy;
|
|
||||||
|
|
||||||
buffer += samples_to_copy * p->info.channels;
|
|
||||||
buffer_samples -= samples_to_copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (buffer_samples > 0) {
|
|
||||||
mp3player_fill_buffer();
|
mp3player_fill_buffer();
|
||||||
|
|
||||||
int samples = mp3dec_decode_frame(&p->dec, p->buffer_ptr, p->buffer_left, p->samples, &p->info);
|
int samples = mp3dec_decode_frame(&p->dec, p->buffer_ptr, p->buffer_left, NULL, &p->info);
|
||||||
|
|
||||||
|
if (samples > 0) {
|
||||||
|
short *buffer = (short *) (samplebuffer_append(sbuf, samples));
|
||||||
|
|
||||||
|
p->buffer_ptr += p->info.frame_offset;
|
||||||
|
p->buffer_left -= p->info.frame_offset;
|
||||||
|
|
||||||
|
mp3dec_decode_frame(&p->dec, p->buffer_ptr, p->buffer_left, buffer, &p->info);
|
||||||
|
|
||||||
|
wlen -= samples;
|
||||||
|
}
|
||||||
|
|
||||||
p->buffer_ptr += p->info.frame_bytes;
|
p->buffer_ptr += p->info.frame_bytes;
|
||||||
p->buffer_left -= p->info.frame_bytes;
|
p->buffer_left -= p->info.frame_bytes;
|
||||||
|
|
||||||
if (samples > 0) {
|
|
||||||
int samples_to_copy = MIN(samples, buffer_samples);
|
|
||||||
|
|
||||||
memcpy(buffer, p->samples, samples_to_copy * sizeof(short) * p->info.channels);
|
|
||||||
|
|
||||||
p->samples_ptr = p->samples + samples_to_copy * p->info.channels;
|
|
||||||
p->samples_left = samples - samples_to_copy;
|
|
||||||
|
|
||||||
buffer += samples_to_copy * p->info.channels;
|
|
||||||
buffer_samples -= samples_to_copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p->info.frame_bytes == 0) {
|
if (p->info.frame_bytes == 0) {
|
||||||
memset(buffer, 0, buffer_samples * sizeof(short) * p->info.channels);
|
short *buffer = (short *) (samplebuffer_append(sbuf, wlen));
|
||||||
buffer_samples = 0;
|
|
||||||
|
memset(buffer, 0, wlen * sizeof(short) * p->info.channels);
|
||||||
|
|
||||||
|
wlen = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mp3player_wave_read (void *ctx, samplebuffer_t *sbuf, int wpos, int wlen, bool seeking) {
|
static void mp3player_calculate_duration (int samples) {
|
||||||
short *buf = (short *) (samplebuffer_append(sbuf, wlen));
|
uint32_t frames;
|
||||||
mp3player_decode_samples(buf, wlen);
|
int delay, padding;
|
||||||
|
|
||||||
|
long data_size = (f_size(&p->fil) - p->data_start);
|
||||||
|
if (mp3dec_check_vbrtag((const uint8_t *) (p->buffer_ptr), p->info.frame_bytes, &frames, &delay, &padding) > 0) {
|
||||||
|
p->duration = (frames * samples) / (float) (p->info.hz);
|
||||||
|
p->bitrate = (data_size * 8) / p->duration;
|
||||||
|
} else {
|
||||||
|
p->bitrate = p->info.bitrate_kbps * 1000;
|
||||||
|
p->duration = data_size / (p->bitrate / 8);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
mp3player_err_t mp3player_init (void) {
|
mp3player_err_t mp3player_init (void) {
|
||||||
p = calloc(1, sizeof(mp3player_t));
|
p = calloc(1, sizeof(mp3player_t));
|
||||||
|
|
||||||
@ -166,20 +167,26 @@ mp3player_err_t mp3player_load (char *path) {
|
|||||||
|
|
||||||
size_t id3v2_skip = mp3dec_skip_id3v2((const uint8_t *) (p->buffer_ptr), p->buffer_left);
|
size_t id3v2_skip = mp3dec_skip_id3v2((const uint8_t *) (p->buffer_ptr), p->buffer_left);
|
||||||
if (id3v2_skip > 0) {
|
if (id3v2_skip > 0) {
|
||||||
f_lseek(&p->fil, f_tell(&p->fil) - p->buffer_left + id3v2_skip);
|
if (f_lseek(&p->fil, f_tell(&p->fil) - p->buffer_left + id3v2_skip) != FR_OK) {
|
||||||
|
return MP3PLAYER_ERR_IO;
|
||||||
|
}
|
||||||
mp3player_reset_decoder();
|
mp3player_reset_decoder();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp3dec_decode_frame(&p->dec, p->buffer_ptr, p->buffer_left, NULL, &p->info) > 0) {
|
int samples = mp3dec_decode_frame(&p->dec, p->buffer_ptr, p->buffer_left, NULL, &p->info);
|
||||||
mp3dec_init(&p->dec);
|
if (samples > 0) {
|
||||||
|
|
||||||
p->loaded = true;
|
p->loaded = true;
|
||||||
p->data_start = f_tell(&p->fil) - p->buffer_left + p->info.frame_offset;
|
p->data_start = f_tell(&p->fil) - p->buffer_left + p->info.frame_offset;
|
||||||
|
|
||||||
|
p->buffer_ptr += p->info.frame_offset;
|
||||||
|
p->buffer_left -= p->info.frame_offset;
|
||||||
|
|
||||||
p->wave.channels = p->info.channels;
|
p->wave.channels = p->info.channels;
|
||||||
p->wave.frequency = p->info.hz;
|
p->wave.frequency = p->info.hz;
|
||||||
|
|
||||||
|
mp3player_calculate_duration(samples);
|
||||||
|
|
||||||
return MP3PLAYER_OK;
|
return MP3PLAYER_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,7 +227,7 @@ bool mp3player_is_playing (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool mp3player_is_finished (void) {
|
bool mp3player_is_finished (void) {
|
||||||
return f_eof(&p->fil) && p->buffer_left == 0 && p->samples_left == 0;
|
return p->loaded && f_eof(&p->fil) && p->buffer_left == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp3player_err_t mp3player_play (void) {
|
mp3player_err_t mp3player_play (void) {
|
||||||
@ -255,15 +262,20 @@ mp3player_err_t mp3player_toggle (void) {
|
|||||||
return MP3PLAYER_OK;
|
return MP3PLAYER_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mp3player_mute (bool mute) {
|
||||||
|
float volume = mute ? 0.f : 1.f;
|
||||||
|
mixer_ch_set_vol(MIXER_CHANNEL, volume, volume);
|
||||||
|
}
|
||||||
|
|
||||||
mp3player_err_t mp3player_seek (int seconds) {
|
mp3player_err_t mp3player_seek (int seconds) {
|
||||||
// NOTE: Rough approximation using last frame bitrate to calculate number of bytes to be skipped.
|
// NOTE: Rough approximation using average bitrate to calculate number of bytes to be skipped.
|
||||||
// Good enough but not very accurate for variable bitrate files.
|
// Good enough but not very accurate for variable bitrate files.
|
||||||
|
|
||||||
if (!p->loaded) {
|
if (!p->loaded) {
|
||||||
return MP3PLAYER_ERR_NO_FILE;
|
return MP3PLAYER_ERR_NO_FILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
long bytes_to_move = (long) (((p->info.bitrate_kbps * 1024) * seconds) / 8);
|
long bytes_to_move = (long) ((p->bitrate * seconds) / 8);
|
||||||
if (bytes_to_move == 0) {
|
if (bytes_to_move == 0) {
|
||||||
return MP3PLAYER_OK;
|
return MP3PLAYER_OK;
|
||||||
}
|
}
|
||||||
@ -279,14 +291,47 @@ mp3player_err_t mp3player_seek (int seconds) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mp3player_reset_decoder();
|
mp3player_reset_decoder();
|
||||||
|
mp3player_fill_buffer();
|
||||||
|
|
||||||
|
if (p->io_error) {
|
||||||
|
return MP3PLAYER_ERR_IO;
|
||||||
|
}
|
||||||
|
|
||||||
return MP3PLAYER_OK;
|
return MP3PLAYER_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float mp3player_get_duration (void) {
|
||||||
|
if (!p->loaded) {
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p->duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
float mp3player_get_bitrate (void) {
|
||||||
|
if (!p->loaded) {
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p->bitrate;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mp3player_get_samplerate (void) {
|
||||||
|
if (!p->loaded) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p->info.hz;
|
||||||
|
}
|
||||||
|
|
||||||
float mp3player_get_progress (void) {
|
float mp3player_get_progress (void) {
|
||||||
// NOTE: Rough approximation using file pointer instead of processed samples.
|
// NOTE: Rough approximation using file pointer instead of processed samples.
|
||||||
// Good enough but not very accurate for variable bitrate files.
|
// Good enough but not very accurate for variable bitrate files.
|
||||||
|
|
||||||
|
if (!p->loaded) {
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
FSIZE_t data_size = f_size(&p->fil) - p->data_start;
|
FSIZE_t data_size = f_size(&p->fil) - p->data_start;
|
||||||
FSIZE_t data_consumed = f_tell(&p->fil) - p->buffer_left;
|
FSIZE_t data_consumed = f_tell(&p->fil) - p->buffer_left;
|
||||||
FSIZE_t data_position = (data_consumed > p->data_start) ? (data_consumed - p->data_start) : 0;
|
FSIZE_t data_position = (data_consumed > p->data_start) ? (data_consumed - p->data_start) : 0;
|
||||||
|
@ -14,6 +14,7 @@ typedef enum {
|
|||||||
} mp3player_err_t;
|
} mp3player_err_t;
|
||||||
|
|
||||||
|
|
||||||
|
void mp3player_mixer_init (void);
|
||||||
mp3player_err_t mp3player_init (void);
|
mp3player_err_t mp3player_init (void);
|
||||||
void mp3player_deinit (void);
|
void mp3player_deinit (void);
|
||||||
mp3player_err_t mp3player_load (char *path);
|
mp3player_err_t mp3player_load (char *path);
|
||||||
@ -24,7 +25,11 @@ bool mp3player_is_finished (void);
|
|||||||
mp3player_err_t mp3player_play (void);
|
mp3player_err_t mp3player_play (void);
|
||||||
void mp3player_stop (void);
|
void mp3player_stop (void);
|
||||||
mp3player_err_t mp3player_toggle (void);
|
mp3player_err_t mp3player_toggle (void);
|
||||||
|
void mp3player_mute (bool mute);
|
||||||
mp3player_err_t mp3player_seek (int seconds);
|
mp3player_err_t mp3player_seek (int seconds);
|
||||||
|
float mp3player_get_duration (void);
|
||||||
|
float mp3player_get_bitrate (void);
|
||||||
|
int mp3player_get_samplerate (void);
|
||||||
float mp3player_get_progress (void);
|
float mp3player_get_progress (void);
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,6 +6,13 @@
|
|||||||
#include "../mp3player.h"
|
#include "../mp3player.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define SEEK_SECONDS 10
|
||||||
|
#define SEEK_UNMUTE_TIMEOUT 17
|
||||||
|
|
||||||
|
|
||||||
|
static int unmute_counter;
|
||||||
|
|
||||||
|
|
||||||
static void format_name (char *buffer, char *name) {
|
static void format_name (char *buffer, char *name) {
|
||||||
int cutoff_length = 57;
|
int cutoff_length = 57;
|
||||||
int name_length = strlen(name);
|
int name_length = strlen(name);
|
||||||
@ -18,8 +25,31 @@ static void format_name (char *buffer, char *name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void format_elapsed_duration (char *buffer, float elapsed, float duration) {
|
||||||
|
strcpy(buffer, " ");
|
||||||
|
|
||||||
|
if (duration >= 3600) {
|
||||||
|
sprintf(buffer + strlen(buffer), "%02d:", (int) (elapsed) / 3600);
|
||||||
|
}
|
||||||
|
sprintf(buffer + strlen(buffer), "%02d:%02d", ((int) (elapsed) % 3600) / 60, (int) (elapsed) % 60);
|
||||||
|
|
||||||
|
strcat(buffer, " / ");
|
||||||
|
|
||||||
|
if (duration >= 3600) {
|
||||||
|
sprintf(buffer + strlen(buffer), "%02d:", (int) (duration) / 3600);
|
||||||
|
}
|
||||||
|
sprintf(buffer + strlen(buffer), "%02d:%02d", ((int) (duration) % 3600) / 60, (int) (duration) % 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void process (menu_t *menu) {
|
static void process (menu_t *menu) {
|
||||||
|
if (unmute_counter > 0) {
|
||||||
|
unmute_counter -= 1;
|
||||||
|
if (unmute_counter == 0) {
|
||||||
|
mp3player_mute(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mp3player_process() != MP3PLAYER_OK) {
|
if (mp3player_process() != MP3PLAYER_OK) {
|
||||||
menu->next_mode = MENU_MODE_ERROR;
|
menu->next_mode = MENU_MODE_ERROR;
|
||||||
} else if (menu->actions.back) {
|
} else if (menu->actions.back) {
|
||||||
@ -29,7 +59,9 @@ static void process (menu_t *menu) {
|
|||||||
menu->next_mode = MENU_MODE_ERROR;
|
menu->next_mode = MENU_MODE_ERROR;
|
||||||
}
|
}
|
||||||
} else if (menu->actions.go_left || menu->actions.go_right) {
|
} else if (menu->actions.go_left || menu->actions.go_right) {
|
||||||
int seconds = ((menu->actions.go_left ? -1 : 1) * 10);
|
mp3player_mute(true);
|
||||||
|
unmute_counter = SEEK_UNMUTE_TIMEOUT;
|
||||||
|
int seconds = (menu->actions.go_left ? -SEEK_SECONDS : SEEK_SECONDS);
|
||||||
if (mp3player_seek(seconds) != MP3PLAYER_OK) {
|
if (mp3player_seek(seconds) != MP3PLAYER_OK) {
|
||||||
menu->next_mode = MENU_MODE_ERROR;
|
menu->next_mode = MENU_MODE_ERROR;
|
||||||
}
|
}
|
||||||
@ -65,6 +97,31 @@ static void draw (menu_t *menu, surface_t *d) {
|
|||||||
format_name(buffer, menu->browser.list[menu->browser.selected].name);
|
format_name(buffer, menu->browser.list[menu->browser.selected].name);
|
||||||
rdpq_font_print(menu->assets.font, buffer);
|
rdpq_font_print(menu->assets.font, buffer);
|
||||||
|
|
||||||
|
text_y += layout->line_height * 2;
|
||||||
|
rdpq_font_begin(text_color);
|
||||||
|
rdpq_font_position(text_x, text_y + menu->assets.font_height);
|
||||||
|
rdpq_font_print(menu->assets.font, "Track elapsed / length:");
|
||||||
|
text_y += layout->line_height;
|
||||||
|
rdpq_font_position(text_x, text_y + menu->assets.font_height);
|
||||||
|
format_elapsed_duration(buffer, mp3player_get_duration() * mp3player_get_progress(), mp3player_get_duration());
|
||||||
|
rdpq_font_print(menu->assets.font, buffer);
|
||||||
|
|
||||||
|
text_y += layout->line_height * 2;
|
||||||
|
rdpq_font_begin(text_color);
|
||||||
|
rdpq_font_position(text_x, text_y + menu->assets.font_height);
|
||||||
|
rdpq_font_print(menu->assets.font, "Average bitrate:");
|
||||||
|
text_y += layout->line_height;
|
||||||
|
rdpq_font_position(text_x, text_y + menu->assets.font_height);
|
||||||
|
rdpq_font_printf(menu->assets.font, " %.0f kbps", mp3player_get_bitrate() / 1000);
|
||||||
|
|
||||||
|
text_y += layout->line_height * 2;
|
||||||
|
rdpq_font_begin(text_color);
|
||||||
|
rdpq_font_position(text_x, text_y + menu->assets.font_height);
|
||||||
|
rdpq_font_print(menu->assets.font, "Samplerate:");
|
||||||
|
text_y += layout->line_height;
|
||||||
|
rdpq_font_position(text_x, text_y + menu->assets.font_height);
|
||||||
|
rdpq_font_printf(menu->assets.font, " %d Hz", mp3player_get_samplerate());
|
||||||
|
|
||||||
// Actions bar
|
// Actions bar
|
||||||
text_y = layout->actions_y + layout->offset_text_y;
|
text_y = layout->actions_y + layout->offset_text_y;
|
||||||
rdpq_font_position(text_x, text_y + menu->assets.font_height);
|
rdpq_font_position(text_x, text_y + menu->assets.font_height);
|
||||||
@ -77,7 +134,7 @@ static void draw (menu_t *menu, surface_t *d) {
|
|||||||
}
|
}
|
||||||
text_y += layout->line_height;
|
text_y += layout->line_height;
|
||||||
rdpq_font_position(text_x, text_y + menu->assets.font_height);
|
rdpq_font_position(text_x, text_y + menu->assets.font_height);
|
||||||
rdpq_font_print(menu->assets.font, "B: Exit | Left/Right: Rewind/Fast forward");
|
rdpq_font_print(menu->assets.font, "B: Exit | Left / Right: Rewind / Fast forward");
|
||||||
rdpq_font_end();
|
rdpq_font_end();
|
||||||
|
|
||||||
rdpq_detach_show();
|
rdpq_detach_show();
|
||||||
@ -87,6 +144,8 @@ static void draw (menu_t *menu, surface_t *d) {
|
|||||||
void view_player_init (menu_t *menu) {
|
void view_player_init (menu_t *menu) {
|
||||||
mp3player_err_t error;
|
mp3player_err_t error;
|
||||||
|
|
||||||
|
unmute_counter = 0;
|
||||||
|
|
||||||
error = mp3player_init();
|
error = mp3player_init();
|
||||||
if (error != MP3PLAYER_OK) {
|
if (error != MP3PLAYER_OK) {
|
||||||
menu->next_mode = MENU_MODE_ERROR;
|
menu->next_mode = MENU_MODE_ERROR;
|
||||||
@ -102,6 +161,7 @@ void view_player_init (menu_t *menu) {
|
|||||||
menu->next_mode = MENU_MODE_ERROR;
|
menu->next_mode = MENU_MODE_ERROR;
|
||||||
mp3player_deinit();
|
mp3player_deinit();
|
||||||
} else {
|
} else {
|
||||||
|
mp3player_mute(false);
|
||||||
mp3player_play();
|
mp3player_play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user