Reworked the way the playing track time is computed so that there no sync issues when we leave the music player app while a song is still playing

This commit is contained in:
anschrammh 2023-09-26 23:26:35 +02:00
parent b0ba6c36e4
commit 08be2b5946
3 changed files with 64 additions and 33 deletions

View File

@ -15,6 +15,7 @@
#include <windows.h>
#include <time.h>
#include <sys/time.h>
#include "watch_face.h"
#include "settings_screen.h"
#include "menu_screen.h"
@ -79,6 +80,16 @@ static void musicPlaybackCtrlCb(MusicPlaybackCtrlAction_e musicPlaybackCtrlActio
LV_LOG_USER("Action to perform : %u", musicPlaybackCtrlAction);
}
static uint32_t musicPlayerTimeRefmsCb(void)
{
struct timeval ref;
gettimeofday(&ref, NULL);
uint32_t ms_time = ref.tv_sec*1000 + ref.tv_usec/1000;
return ms_time;
}
WatchFace_t watchFace;
MenuScreen_t menuScreen;
CompassScreen_t compassScreen;
@ -117,11 +128,12 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLi
find_my_phone_screen_notify_BLE_connection_state(&findMyPhoneScreen, true);
music_player_screen_init(&musicPlayerScreen);
music_player_screen_register_music_playback_control_cb(&musicPlayerScreen, &(musicPlaybackCtrlCb));
music_player_screen_register_music_player_time_ref_ms_cb(&musicPlayerScreen, &(musicPlayerTimeRefmsCb));
music_player_screen_set_playing_music_title_and_artist(&musicPlayerScreen, "Sun Is Up Hoho Haha", "Inna");
music_player_screen_notify_BLE_connection_state(&musicPlayerScreen, true);
music_player_screen_set_music_duration(&musicPlayerScreen, 3*60+42);
music_player_screen_set_music_position(&musicPlayerScreen, 3*60+12);
//music_player_screen_set_music_playing_state(&musicPlayerScreen, MUSIC_CONTROL_PLAY);
music_player_screen_set_music_position(&musicPlayerScreen, 2*60+12);
music_player_screen_set_music_playing_state(&musicPlayerScreen, MUSIC_CONTROL_PLAY);
altimeter_screen_register_measurement_cb(&altimeterScreen, &(alti_meas_cb));

View File

@ -4,8 +4,9 @@
#include "menu_screen.h"
static void _set_UI_no_ble_connection(MusicPlayerScreen_t * const musicPlayerScreen, bool connected);
static void _update_playing_track_position(MusicPlayerScreen_t * const musicPlayerScreen, uint16_t positionInSeconds);
static uint16_t _time_difference_in_seconds(uint32_t referenceTimeMs, uint32_t currentTimeMs);
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)
{
@ -66,7 +67,11 @@ static void music_player_button_click_event_cb(lv_event_t *e)
{
musicPlayerScreen->musicPlaybackCtrlCb(MUSIC_CONTROL_FORWARD);
//Don't forget to add 10 seconds to the current song position
music_player_screen_set_music_position(musicPlayerScreen, musicPlayerScreen->currentMusicPosition + 10);
//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)
@ -79,8 +84,11 @@ static void music_player_button_click_event_cb(lv_event_t *e)
{
musicPlayerScreen->musicPlaybackCtrlCb(MUSIC_CONTROL_REWIND);
//Don't forget to remove 10 seconds to the current song position
uint16_t musicPositionToSet = musicPlayerScreen->currentMusicPosition >= 10 ? musicPlayerScreen->currentMusicPosition - 10 : 0;
music_player_screen_set_music_position(musicPlayerScreen, musicPositionToSet);
//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
@ -93,12 +101,12 @@ static void music_player_button_click_event_cb(lv_event_t *e)
static void track_position_update_cb(lv_timer_t *timer)
{
MusicPlayerScreen_t *musicPlayerScreen = timer->user_data;
uint32_t current_time = musicPlayerScreen->musicPlayerTimeRefmsCb ? musicPlayerScreen->musicPlayerTimeRefmsCb() : 0;
_update_playing_track_position(
musicPlayerScreen,
musicPlayerScreen->currentMusicPosition +
_time_difference_in_seconds(musicPlayerScreen->playerStartTimeRef, current_time)
);
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)
@ -161,9 +169,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);
@ -172,9 +178,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);
@ -212,9 +216,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;
_update_playing_track_position(musicPlayerScreen, positionInSeconds);
//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)
@ -430,7 +438,6 @@ void music_player_screen_create(MusicPlayerScreen_t * const musicPlayerScreen)
lv_obj_set_style_arc_color(musicPlayerScreen->playbackArc, lv_palette_main(LV_PALETTE_LIME), LV_PART_INDICATOR);
lv_obj_set_style_arc_color(musicPlayerScreen->playbackArc, lv_color_make(100,100,100), LV_PART_MAIN);
music_player_screen_set_music_duration(musicPlayerScreen, musicPlayerScreen->currentMusicDuration);
_update_playing_track_position(musicPlayerScreen, musicPlayerScreen->currentMusicPosition);
_set_UI_no_ble_connection(musicPlayerScreen, musicPlayerScreen->ble_connection_state);
@ -440,8 +447,11 @@ void music_player_screen_create(MusicPlayerScreen_t * const musicPlayerScreen)
lv_timer_del(musicPlayerScreen->trackPlayCursorUpdateTimer);
musicPlayerScreen->trackPlayCursorUpdateTimer = NULL;
}
musicPlayerScreen->trackPlayCursorUpdateTimer = lv_timer_create(&(track_position_update_cb), 1000, musicPlayerScreen);
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);
@ -485,14 +495,10 @@ static void _set_UI_no_ble_connection(MusicPlayerScreen_t * const musicPlayerScr
}
}
static void _update_playing_track_position(MusicPlayerScreen_t * const musicPlayerScreen, uint16_t positionInSeconds)
static void _update_playing_track_visuals(MusicPlayerScreen_t * const musicPlayerScreen)
{
//If the widget is currently displayed, we update it as well !
if(!musicPlayerScreen->playbackArc) return;
//Let's check that the track current position is not greater than the track's duration
positionInSeconds = positionInSeconds > musicPlayerScreen->currentMusicDuration ? musicPlayerScreen->currentMusicDuration : positionInSeconds;
//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);
@ -502,7 +508,18 @@ static void _update_playing_track_position(MusicPlayerScreen_t * const musicPlay
lv_label_set_text_static(musicPlayerScreen->positionTimeLabel.label, musicPlayerScreen->positionTimeLabel.text);
}
static uint16_t _time_difference_in_seconds(uint32_t referenceTimeMs, uint32_t currentTimeMs)
static void _update_playing_track_ref_time(MusicPlayerScreen_t * const musicPlayerScreen)
{
return (currentTimeMs - referenceTimeMs)/1000;
//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;
}

View File

@ -3,6 +3,8 @@
#include "lvgl.h"
#define FAST_FORWARD_BACKWARD_STEP (10)
typedef enum MusicPlaybackCtrlAction
{
MUSIC_CONTROL_PLAY = 0,
@ -53,7 +55,7 @@ typedef struct MusicPlayerScreen
char titleText[60];
char artistText[30];
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 currentMusicPosition; //The currently playing music's cursor position in milliseconds.
uint32_t playerStartTimeRef;
bool ble_connection_state;
} MusicPlayerScreen_t;