diff --git a/src/W800_SDK_v1.00.10/app/gfx/gfx_task.c b/src/W800_SDK_v1.00.10/app/gfx/gfx_task.c index d7be08d..dd90fac 100644 --- a/src/W800_SDK_v1.00.10/app/gfx/gfx_task.c +++ b/src/W800_SDK_v1.00.10/app/gfx/gfx_task.c @@ -559,7 +559,7 @@ void gfx_task(void *param) music_player_screen_init(&musicPlayerScreen); music_player_screen_register_music_playback_control_cb(&musicPlayerScreen, &(sendMusicPlaybackBLECommandCb)); - music_player_screen_register_os_time_ms_ref_cb(&musicPlayerScreen, &(elapsed_ms)); + music_player_screen_register_music_player_time_ref_ms_cb(&musicPlayerScreen, &(elapsed_ms)); settings_screen_init(&settingsScreen); settings_screen_register_API_interface(&settingsScreen, &settingsScreenAPIInterface); diff --git a/src/W800_SDK_v1.00.10/app/gfx/music_player_screen.c b/src/W800_SDK_v1.00.10/app/gfx/music_player_screen.c index 9a287bf..165996c 100644 --- a/src/W800_SDK_v1.00.10/app/gfx/music_player_screen.c +++ b/src/W800_SDK_v1.00.10/app/gfx/music_player_screen.c @@ -4,7 +4,10 @@ #include "menu_screen.h" #include "translation.h" -void _set_UI_no_ble_connection(MusicPlayerScreen_t * const musicPlayerScreen, bool connected); +static void _set_UI_no_ble_connection(MusicPlayerScreen_t * const musicPlayerScreen, bool connected); +static void _update_playing_track_visuals(MusicPlayerScreen_t * const musicPlayerScreen); +static void _update_playing_track_ref_time(MusicPlayerScreen_t * const musicPlayerScreen); +static uint16_t _time_difference_in_ms(uint32_t referenceTimeMs, uint32_t currentTimeMs); static void gesture_event_cb(lv_event_t *e) { @@ -57,11 +60,37 @@ static void music_player_button_click_event_cb(lv_event_t *e) } else if(action == MUSIC_CONTROL_NEXT) { - musicPlayerScreen->musicPlaybackCtrlCb(e->code == LV_EVENT_SHORT_CLICKED ? MUSIC_CONTROL_NEXT : MUSIC_CONTROL_FORWARD); + if(e->code == LV_EVENT_SHORT_CLICKED) + { + musicPlayerScreen->musicPlaybackCtrlCb(MUSIC_CONTROL_NEXT); + } + else + { + musicPlayerScreen->musicPlaybackCtrlCb(MUSIC_CONTROL_FORWARD); + //Don't forget to add 10 seconds to the current song position + //10 seconds is the step used by the android AIMP player, this may vary + musicPlayerScreen->currentMusicPosition = musicPlayerScreen->currentMusicPosition/1000 + FAST_FORWARD_BACKWARD_STEP > musicPlayerScreen->currentMusicDuration ? + musicPlayerScreen->currentMusicDuration * 1000 : musicPlayerScreen->currentMusicPosition + FAST_FORWARD_BACKWARD_STEP * 1000; + _update_playing_track_visuals(musicPlayerScreen); + if(musicPlayerScreen->musicPlayerTimeRefmsCb)musicPlayerScreen->playerStartTimeRef = musicPlayerScreen->musicPlayerTimeRefmsCb(); + } } else if(action == MUSIC_CONTROL_PREVIOUS) { - musicPlayerScreen->musicPlaybackCtrlCb(e->code == LV_EVENT_SHORT_CLICKED ? MUSIC_CONTROL_PREVIOUS : MUSIC_CONTROL_REWIND); + if(e->code == LV_EVENT_SHORT_CLICKED) + { + musicPlayerScreen->musicPlaybackCtrlCb(MUSIC_CONTROL_PREVIOUS); + } + else + { + musicPlayerScreen->musicPlaybackCtrlCb(MUSIC_CONTROL_REWIND); + //Don't forget to remove 10 seconds to the current song position + //10 seconds is the step used by the android AIMP player, this may vary + musicPlayerScreen->currentMusicPosition = musicPlayerScreen->currentMusicPosition >= FAST_FORWARD_BACKWARD_STEP * 1000 ? + musicPlayerScreen->currentMusicPosition - FAST_FORWARD_BACKWARD_STEP * 1000 : 0; + _update_playing_track_visuals(musicPlayerScreen); + if(musicPlayerScreen->musicPlayerTimeRefmsCb)musicPlayerScreen->playerStartTimeRef = musicPlayerScreen->musicPlayerTimeRefmsCb(); + } } else { @@ -74,7 +103,11 @@ static void track_position_update_cb(lv_timer_t *timer) { MusicPlayerScreen_t *musicPlayerScreen = timer->user_data; - music_player_screen_set_music_position(musicPlayerScreen, ++musicPlayerScreen->currentMusicPosition); + if(musicPlayerScreen->currentMusicPosition == musicPlayerScreen->currentMusicDuration * 1000) return; + + //If the callback get's called, this means we are in the music play state + _update_playing_track_ref_time(musicPlayerScreen); + _update_playing_track_visuals(musicPlayerScreen); } void music_player_screen_init(MusicPlayerScreen_t * const musicPlayerScreen) @@ -100,7 +133,7 @@ void music_player_screen_register_music_playback_control_cb(MusicPlayerScreen_t musicPlayerScreen->musicPlaybackCtrlCb = musicPlaybackCtrlCb; } -void music_player_screen_register_os_time_ms_ref_cb(MusicPlayerScreen_t * const musicPlayerScreen, MusicPlayerTimeRefCb_t musicPlayerTimeRefCb) +void music_player_screen_register_music_player_time_ref_ms_cb(MusicPlayerScreen_t * const musicPlayerScreen, MusicPlayerTimeRefmsCb_t musicPlayerTimeRefmsCb) { if(!musicPlayerScreen) { @@ -108,7 +141,7 @@ void music_player_screen_register_os_time_ms_ref_cb(MusicPlayerScreen_t * const return; } - musicPlayerScreen->musicPlayerTimeRefCb = musicPlayerTimeRefCb; + musicPlayerScreen->musicPlayerTimeRefmsCb = musicPlayerTimeRefmsCb; } void music_player_screen_notify_BLE_connection_state(MusicPlayerScreen_t * const musicPlayerScreen, bool connected) @@ -137,9 +170,7 @@ void music_player_screen_set_playing_music_title_and_artist(MusicPlayerScreen_t if(title) { - strncpy(musicPlayerScreen->titleText, title, sizeof musicPlayerScreen->titleText); - musicPlayerScreen->titleText[sizeof(musicPlayerScreen->titleText) - 1] = '\0'; - + strncpy(musicPlayerScreen->titleText, title, sizeof(musicPlayerScreen->titleText)-1); if(musicPlayerScreen->titleLabel) { lv_label_set_text_static(musicPlayerScreen->titleLabel, musicPlayerScreen->titleText); @@ -148,9 +179,7 @@ void music_player_screen_set_playing_music_title_and_artist(MusicPlayerScreen_t if(artist) { - strncpy(musicPlayerScreen->artistText, artist, sizeof musicPlayerScreen->artistText); - musicPlayerScreen->artistText[sizeof(musicPlayerScreen->artistText) - 1] = '\0'; - + strncpy(musicPlayerScreen->artistText, artist, sizeof(musicPlayerScreen->artistText)-1); if(musicPlayerScreen->artistLabel) { lv_label_set_text_static(musicPlayerScreen->artistLabel, musicPlayerScreen->artistText); @@ -188,22 +217,13 @@ void music_player_screen_set_music_position(MusicPlayerScreen_t * const musicPla } positionInSeconds = positionInSeconds > musicPlayerScreen->currentMusicDuration ? musicPlayerScreen->currentMusicDuration : positionInSeconds; - musicPlayerScreen->currentMusicPosition = positionInSeconds; + musicPlayerScreen->currentMusicPosition = positionInSeconds * 1000; - //Let's update the time ref - if(musicPlayerScreen->musicPlayerTimeRefCb) - musicPlayerScreen->osTimeRef = musicPlayerScreen->musicPlayerTimeRefCb(); - - //If the widget is currently displayed, we update it as well ! - if(!musicPlayerScreen->playbackArc) return; - - lv_arc_set_value(musicPlayerScreen->playbackArc, musicPlayerScreen->currentMusicPosition); - - if(positionInSeconds < 3600)sprintf(musicPlayerScreen->positionTimeLabel.text, "%s%u:%s%u", positionInSeconds / 60 < 10 ? "0":"", positionInSeconds / 60, positionInSeconds % 60 < 10 ? "0":"", positionInSeconds % 60); - else sprintf(musicPlayerScreen->positionTimeLabel.text, "%s%u:%s%u:%s%u", positionInSeconds / 3600 < 10 ? "0":"", positionInSeconds / 3600, - (positionInSeconds % 3600) / 60 < 10 ? "0":"", (positionInSeconds % 3600) / 60, - (positionInSeconds % 3600) % 60 < 10 ? "0":"", (positionInSeconds % 3600) % 60); - lv_label_set_text_static(musicPlayerScreen->positionTimeLabel.label, musicPlayerScreen->positionTimeLabel.text); + //Let's update the current music position visually + if(music_player_screen_is_in_use(musicPlayerScreen)) + { + _update_playing_track_visuals(musicPlayerScreen); + } } void music_player_screen_set_music_playing_state(MusicPlayerScreen_t * const musicPlayerScreen, MusicPlaybackCtrlAction_e playingState) @@ -218,12 +238,15 @@ void music_player_screen_set_music_playing_state(MusicPlayerScreen_t * const mus musicPlayerScreen->currentPlayState = playingState; - if(musicPlayerScreen->currentPlayState == MUSIC_CONTROL_PLAY) - lv_timer_resume(musicPlayerScreen->timePositionTimer); - else - lv_timer_pause(musicPlayerScreen->timePositionTimer); + if(musicPlayerScreen->musicPlayerTimeRefmsCb) + musicPlayerScreen->playerStartTimeRef = musicPlayerScreen->musicPlayerTimeRefmsCb(); - if(!musicPlayerScreen->playPauseBtn.label) return; + if(!music_player_screen_is_in_use(musicPlayerScreen)) return; + + if(musicPlayerScreen->currentPlayState == MUSIC_CONTROL_PLAY) + lv_timer_resume(musicPlayerScreen->trackPlayCursorUpdateTimer); + else + lv_timer_pause(musicPlayerScreen->trackPlayCursorUpdateTimer); strcpy(musicPlayerScreen->playPauseBtn.icon, musicPlayerScreen->currentPlayState == MUSIC_CONTROL_PLAY ? LV_SYMBOL_PAUSE : LV_SYMBOL_PLAY); lv_label_set_text_static(musicPlayerScreen->playPauseBtn.label, musicPlayerScreen->playPauseBtn.icon); @@ -419,23 +442,17 @@ void music_player_screen_create(MusicPlayerScreen_t * const musicPlayerScreen) _set_UI_no_ble_connection(musicPlayerScreen, musicPlayerScreen->ble_connection_state); - if(musicPlayerScreen->timePositionTimer) + if(musicPlayerScreen->trackPlayCursorUpdateTimer) { - LV_LOG_ERROR("timePositionTimer should be NULL here !"); - lv_timer_del(musicPlayerScreen->timePositionTimer); - musicPlayerScreen->timePositionTimer = NULL; + LV_LOG_ERROR("trackPlayCursorUpdateTimer should be NULL here !"); + lv_timer_del(musicPlayerScreen->trackPlayCursorUpdateTimer); + musicPlayerScreen->trackPlayCursorUpdateTimer = NULL; } - musicPlayerScreen->timePositionTimer = lv_timer_create(&(track_position_update_cb), 1000, musicPlayerScreen); - //If the music was not currently playing, no need to start the music position update timer - if(musicPlayerScreen->currentPlayState != MUSIC_CONTROL_PLAY) - { - lv_timer_pause(musicPlayerScreen->timePositionTimer); - } - else if(musicPlayerScreen->musicPlayerTimeRefCb) //When we left the app, the music was running so we need to recompute the current position - { - musicPlayerScreen->currentMusicPosition += (musicPlayerScreen->musicPlayerTimeRefCb() - musicPlayerScreen->osTimeRef) / 1000; //We want seconds - } - music_player_screen_set_music_position(musicPlayerScreen, musicPlayerScreen->currentMusicPosition); + musicPlayerScreen->trackPlayCursorUpdateTimer = lv_timer_create(&(track_position_update_cb), 333, musicPlayerScreen); + if(musicPlayerScreen->currentPlayState != MUSIC_CONTROL_PLAY) lv_timer_pause(musicPlayerScreen->trackPlayCursorUpdateTimer); + if(musicPlayerScreen->currentPlayState == MUSIC_CONTROL_PLAY) _update_playing_track_ref_time(musicPlayerScreen); + + _update_playing_track_visuals(musicPlayerScreen); //We register the event callback to handle gestures lv_obj_add_event_cb(musicPlayerScreen->display, &(gesture_event_cb), LV_EVENT_GESTURE, musicPlayerScreen); @@ -450,12 +467,11 @@ void music_player_screen_destroy(MusicPlayerScreen_t * const musicPlayerScreen) LV_LOG_ERROR("NULL pointer given !"); return; } - - lv_timer_del(musicPlayerScreen->timePositionTimer); + lv_timer_del(musicPlayerScreen->trackPlayCursorUpdateTimer); memset(musicPlayerScreen, 0, offsetof(MusicPlayerScreen_t, musicPlaybackCtrlCb)); } -void _set_UI_no_ble_connection(MusicPlayerScreen_t * const musicPlayerScreen, bool connected) +static void _set_UI_no_ble_connection(MusicPlayerScreen_t * const musicPlayerScreen, bool connected) { if(connected) { @@ -479,3 +495,32 @@ void _set_UI_no_ble_connection(MusicPlayerScreen_t * const musicPlayerScreen, bo lv_obj_add_flag(musicPlayerScreen->artistLabel, LV_OBJ_FLAG_HIDDEN); } } + +static void _update_playing_track_visuals(MusicPlayerScreen_t * const musicPlayerScreen) +{ + //Do not forget to put the current music position back in seconds + uint16_t positionInSeconds = musicPlayerScreen->currentMusicPosition/1000; + lv_arc_set_value(musicPlayerScreen->playbackArc, positionInSeconds); + + if(positionInSeconds < 3600)sprintf(musicPlayerScreen->positionTimeLabel.text, "%s%u:%s%u", positionInSeconds / 60 < 10 ? "0":"", positionInSeconds / 60, positionInSeconds % 60 < 10 ? "0":"", positionInSeconds % 60); + else sprintf(musicPlayerScreen->positionTimeLabel.text, "%s%u:%s%u:%s%u", positionInSeconds / 3600 < 10 ? "0":"", positionInSeconds / 3600, + (positionInSeconds % 3600) / 60 < 10 ? "0":"", (positionInSeconds % 3600) / 60, + (positionInSeconds % 3600) % 60 < 10 ? "0":"", (positionInSeconds % 3600) % 60); + lv_label_set_text_static(musicPlayerScreen->positionTimeLabel.label, musicPlayerScreen->positionTimeLabel.text); +} + +static void _update_playing_track_ref_time(MusicPlayerScreen_t * const musicPlayerScreen) +{ + //Let's compute the time that has passed and update the current song position + uint32_t currentTimeMs = musicPlayerScreen->musicPlayerTimeRefmsCb ? musicPlayerScreen->musicPlayerTimeRefmsCb() : 0; + uint16_t timeDifferenceMs = _time_difference_in_ms(musicPlayerScreen->playerStartTimeRef, currentTimeMs); + musicPlayerScreen->playerStartTimeRef = currentTimeMs; + + musicPlayerScreen->currentMusicPosition = musicPlayerScreen->currentMusicPosition + timeDifferenceMs > musicPlayerScreen->currentMusicDuration * 1000 ? + musicPlayerScreen->currentMusicDuration * 1000 : musicPlayerScreen->currentMusicPosition + timeDifferenceMs; +} + +static uint16_t _time_difference_in_ms(uint32_t referenceTimeMs, uint32_t currentTimeMs) +{ + return currentTimeMs - referenceTimeMs; +} diff --git a/src/W800_SDK_v1.00.10/app/gfx/music_player_screen.h b/src/W800_SDK_v1.00.10/app/gfx/music_player_screen.h index 1045d07..01dae9d 100644 --- a/src/W800_SDK_v1.00.10/app/gfx/music_player_screen.h +++ b/src/W800_SDK_v1.00.10/app/gfx/music_player_screen.h @@ -3,6 +3,8 @@ #include "lvgl.h" +#define FAST_FORWARD_BACKWARD_STEP (10) + typedef enum MusicPlaybackCtrlAction { MUSIC_CONTROL_PLAY = 0, @@ -17,7 +19,7 @@ typedef enum MusicPlaybackCtrlAction } MusicPlaybackCtrlAction_e; typedef void (*MusicPlaybackCtrlCb_t)(MusicPlaybackCtrlAction_e musicPlaybackCtrlAction); -typedef uint32_t (*MusicPlayerTimeRefCb_t)(void); +typedef uint32_t (*MusicPlayerTimeRefmsCb_t)(void); typedef struct PlayerButton { @@ -45,16 +47,16 @@ typedef struct MusicPlayerScreen lv_obj_t *titleLabel; lv_obj_t *artistLabel; TimeLabel_t positionTimeLabel, durationTimeLabel; - lv_timer_t *timePositionTimer; + lv_timer_t *trackPlayCursorUpdateTimer; //Should not be erased attributes MusicPlaybackCtrlCb_t musicPlaybackCtrlCb; - MusicPlayerTimeRefCb_t musicPlayerTimeRefCb; + MusicPlayerTimeRefmsCb_t musicPlayerTimeRefmsCb; MusicPlaybackCtrlAction_e currentPlayState; - uint16_t currentMusicDuration; //The currently playing music's total duration in seconds. - uint16_t currentMusicPosition; //The currently playing music's cursor position in seconds. - uint32_t osTimeRef; //Time reference used to compute the time elaspsed when the player is not running, but the song is playing. char titleText[60]; char artistText[30]; + uint16_t currentMusicDuration; //The currently playing music's total duration in seconds. + uint32_t currentMusicPosition; //The currently playing music's cursor position in milliseconds. + uint32_t playerStartTimeRef; bool ble_connection_state; } MusicPlayerScreen_t; @@ -68,7 +70,7 @@ void music_player_screen_init(MusicPlayerScreen_t * const musicPlayerScreen); void music_player_screen_register_music_playback_control_cb(MusicPlayerScreen_t * const musicPlayerScreen, MusicPlaybackCtrlCb_t musicPlaybackCtrlCb); -void music_player_screen_register_os_time_ms_ref_cb(MusicPlayerScreen_t * const musicPlayerScreen, MusicPlayerTimeRefCb_t musicPlayerTimeRefCb); +void music_player_screen_register_music_player_time_ref_ms_cb(MusicPlayerScreen_t * const musicPlayerScreen, MusicPlayerTimeRefmsCb_t musicPlayerTimeRefmsCb); void music_player_screen_notify_BLE_connection_state(MusicPlayerScreen_t * const musicPlayerScreen, bool connected);