Update track progress in MusicService. Fix #127
This commit is contained in:
parent
f82aa71eb0
commit
34858d0a6c
|
@ -152,12 +152,20 @@ int Pinetime::Controllers::MusicService::OnCommand(uint16_t conn_handle, uint16_
|
||||||
albumName = s;
|
albumName = s;
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msStatusCharUuid.u) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msStatusCharUuid.u) == 0) {
|
||||||
playing = s[0];
|
playing = s[0];
|
||||||
|
// These variables need to be updated, because the progress may not be updated immediately,
|
||||||
|
// leading to getProgress() returning an incorrect position.
|
||||||
|
if (playing) {
|
||||||
|
trackProgressUpdateTime = xTaskGetTickCount();
|
||||||
|
} else {
|
||||||
|
trackProgress += static_cast<int>((static_cast<float>(xTaskGetTickCount() - trackProgressUpdateTime) / 1024.0f) * getPlaybackSpeed());
|
||||||
|
}
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msRepeatCharUuid.u) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msRepeatCharUuid.u) == 0) {
|
||||||
repeat = s[0];
|
repeat = s[0];
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msShuffleCharUuid.u) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msShuffleCharUuid.u) == 0) {
|
||||||
shuffle = s[0];
|
shuffle = s[0];
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msPositionCharUuid.u) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msPositionCharUuid.u) == 0) {
|
||||||
trackProgress = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
trackProgress = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
||||||
|
trackProgressUpdateTime = xTaskGetTickCount();
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msTotalLengthCharUuid.u) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msTotalLengthCharUuid.u) == 0) {
|
||||||
trackLength = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
trackLength = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msTrackNumberCharUuid.u) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msTrackNumberCharUuid.u) == 0) {
|
||||||
|
@ -191,7 +199,10 @@ float Pinetime::Controllers::MusicService::getPlaybackSpeed() const {
|
||||||
return playbackSpeed;
|
return playbackSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Pinetime::Controllers::MusicService::getProgress() const {
|
int Pinetime::Controllers::MusicService::getProgress() {
|
||||||
|
if (isPlaying()) {
|
||||||
|
return trackProgress + static_cast<int>((static_cast<float>(xTaskGetTickCount() - trackProgressUpdateTime) / 1024.0f) * getPlaybackSpeed());
|
||||||
|
}
|
||||||
return trackProgress;
|
return trackProgress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace Pinetime {
|
||||||
|
|
||||||
std::string getAlbum() const;
|
std::string getAlbum() const;
|
||||||
|
|
||||||
int getProgress() const;
|
int getProgress();
|
||||||
|
|
||||||
int getTrackLength() const;
|
int getTrackLength() const;
|
||||||
|
|
||||||
|
@ -81,6 +81,7 @@ namespace Pinetime {
|
||||||
int trackLength {0};
|
int trackLength {0};
|
||||||
int trackNumber {};
|
int trackNumber {};
|
||||||
int tracksTotal {};
|
int tracksTotal {};
|
||||||
|
TickType_t trackProgressUpdateTime {0};
|
||||||
|
|
||||||
float playbackSpeed {1.0f};
|
float playbackSpeed {1.0f};
|
||||||
|
|
||||||
|
|
|
@ -152,32 +152,27 @@ Music::~Music() {
|
||||||
void Music::Refresh() {
|
void Music::Refresh() {
|
||||||
if (artist != musicService.getArtist()) {
|
if (artist != musicService.getArtist()) {
|
||||||
artist = musicService.getArtist();
|
artist = musicService.getArtist();
|
||||||
currentLength = 0;
|
currentPosition = 0;
|
||||||
lv_label_set_text(txtArtist, artist.data());
|
lv_label_set_text(txtArtist, artist.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (track != musicService.getTrack()) {
|
if (track != musicService.getTrack()) {
|
||||||
track = musicService.getTrack();
|
track = musicService.getTrack();
|
||||||
currentLength = 0;
|
currentPosition = 0;
|
||||||
lv_label_set_text(txtTrack, track.data());
|
lv_label_set_text(txtTrack, track.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (album != musicService.getAlbum()) {
|
if (album != musicService.getAlbum()) {
|
||||||
album = musicService.getAlbum();
|
album = musicService.getAlbum();
|
||||||
currentLength = 0;
|
currentPosition = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playing != musicService.isPlaying()) {
|
if (playing != musicService.isPlaying()) {
|
||||||
playing = musicService.isPlaying();
|
playing = musicService.isPlaying();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Because we increment this ourselves,
|
if (currentPosition != musicService.getProgress()) {
|
||||||
// we can't compare with the old data directly
|
currentPosition = musicService.getProgress();
|
||||||
// have to update it when there's actually new data
|
|
||||||
// just to avoid unnecessary draws that make UI choppy
|
|
||||||
if (lastLength != musicService.getProgress()) {
|
|
||||||
currentLength = musicService.getProgress();
|
|
||||||
lastLength = currentLength;
|
|
||||||
UpdateLength();
|
UpdateLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +181,7 @@ void Music::Refresh() {
|
||||||
UpdateLength();
|
UpdateLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playing == Pinetime::Controllers::MusicService::MusicStatus::Playing) {
|
if (playing) {
|
||||||
lv_label_set_text_static(txtPlayPause, Symbols::pause);
|
lv_label_set_text_static(txtPlayPause, Symbols::pause);
|
||||||
if (xTaskGetTickCount() - 1024 >= lastIncrement) {
|
if (xTaskGetTickCount() - 1024 >= lastIncrement) {
|
||||||
|
|
||||||
|
@ -197,18 +192,12 @@ void Music::Refresh() {
|
||||||
}
|
}
|
||||||
frameB = !frameB;
|
frameB = !frameB;
|
||||||
|
|
||||||
if (currentLength < totalLength) {
|
if (currentPosition >= totalLength) {
|
||||||
currentLength +=
|
|
||||||
static_cast<int>((static_cast<float>(xTaskGetTickCount() - lastIncrement) / 1024.0f) * musicService.getPlaybackSpeed());
|
|
||||||
} else {
|
|
||||||
// Let's assume the getTrack finished, paused when the timer ends
|
// Let's assume the getTrack finished, paused when the timer ends
|
||||||
// and there's no new getTrack being sent to us
|
// and there's no new getTrack being sent to us
|
||||||
// TODO: ideally this would be configurable
|
|
||||||
playing = false;
|
playing = false;
|
||||||
}
|
}
|
||||||
lastIncrement = xTaskGetTickCount();
|
lastIncrement = xTaskGetTickCount();
|
||||||
|
|
||||||
UpdateLength();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
lv_label_set_text_static(txtPlayPause, Symbols::play);
|
lv_label_set_text_static(txtPlayPause, Symbols::play);
|
||||||
|
@ -221,15 +210,15 @@ void Music::UpdateLength() {
|
||||||
} else if (totalLength > (99 * 60)) {
|
} else if (totalLength > (99 * 60)) {
|
||||||
lv_label_set_text_fmt(txtTrackDuration,
|
lv_label_set_text_fmt(txtTrackDuration,
|
||||||
"%02d:%02d/%02d:%02d",
|
"%02d:%02d/%02d:%02d",
|
||||||
(currentLength / (60 * 60)) % 100,
|
(currentPosition / (60 * 60)) % 100,
|
||||||
((currentLength % (60 * 60)) / 60) % 100,
|
((currentPosition % (60 * 60)) / 60) % 100,
|
||||||
(totalLength / (60 * 60)) % 100,
|
(totalLength / (60 * 60)) % 100,
|
||||||
((totalLength % (60 * 60)) / 60) % 100);
|
((totalLength % (60 * 60)) / 60) % 100);
|
||||||
} else {
|
} else {
|
||||||
lv_label_set_text_fmt(txtTrackDuration,
|
lv_label_set_text_fmt(txtTrackDuration,
|
||||||
"%02d:%02d/%02d:%02d",
|
"%02d:%02d/%02d:%02d",
|
||||||
(currentLength / 60) % 100,
|
(currentPosition / 60) % 100,
|
||||||
(currentLength % 60) % 100,
|
(currentPosition % 60) % 100,
|
||||||
(totalLength / 60) % 100,
|
(totalLength / 60) % 100,
|
||||||
(totalLength % 60) % 100);
|
(totalLength % 60) % 100);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,10 +70,8 @@ namespace Pinetime {
|
||||||
|
|
||||||
/** Total length in seconds */
|
/** Total length in seconds */
|
||||||
int totalLength = 0;
|
int totalLength = 0;
|
||||||
/** Current length in seconds */
|
/** Current position in seconds */
|
||||||
int currentLength;
|
int currentPosition;
|
||||||
/** Last length */
|
|
||||||
int lastLength;
|
|
||||||
/** Last time an animation update or timer was incremented */
|
/** Last time an animation update or timer was incremented */
|
||||||
TickType_t lastIncrement = 0;
|
TickType_t lastIncrement = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue