Moved AudioPlayerState+position+duration+frequency to a single struct.

This commit is contained in:
John Preston 2016-07-10 16:02:22 +03:00
parent 99b15719cf
commit 1fee0822fb
13 changed files with 198 additions and 253 deletions

View File

@ -4402,61 +4402,48 @@ bool HistoryDocument::updateStatusText() const {
} else if (_data->loading()) { } else if (_data->loading()) {
statusSize = _data->loadOffset(); statusSize = _data->loadOffset();
} else if (_data->loaded()) { } else if (_data->loaded()) {
if (_data->voice()) { statusSize = FileStatusSizeLoaded;
AudioMsgId playing; if (audioPlayer()) {
AudioPlayerState playingState = AudioPlayerStopped; if (_data->voice()) {
int64 playingPosition = 0, playingDuration = 0; AudioMsgId playing;
int32 playingFrequency = 0; auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Voice);
if (audioPlayer()) { if (playing == AudioMsgId(_data, _parent->fullId()) && !(playbackState.state & AudioPlayerStoppedMask) && playbackState.state != AudioPlayerFinishing) {
audioPlayer()->currentState(&playing, AudioMsgId::Type::Voice, &playingState, &playingPosition, &playingDuration, &playingFrequency); if (auto voice = Get<HistoryDocumentVoice>()) {
} bool was = voice->_playback;
voice->ensurePlayback(this);
if (playing == AudioMsgId(_data, _parent->fullId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { if (!was || playbackState.position != voice->_playback->_position) {
if (auto voice = Get<HistoryDocumentVoice>()) { float64 prg = playbackState.duration ? snap(float64(playbackState.position) / playbackState.duration, 0., 1.) : 0.;
bool was = voice->_playback; if (voice->_playback->_position < playbackState.position) {
voice->ensurePlayback(this); voice->_playback->a_progress.start(prg);
if (!was || playingPosition != voice->_playback->_position) { } else {
float64 prg = playingDuration ? snap(float64(playingPosition) / playingDuration, 0., 1.) : 0.; voice->_playback->a_progress = anim::fvalue(0., prg);
if (voice->_playback->_position < playingPosition) { }
voice->_playback->a_progress.start(prg); voice->_playback->_position = playbackState.position;
} else { voice->_playback->_a_progress.start();
voice->_playback->a_progress = anim::fvalue(0., prg);
} }
voice->_playback->_position = playingPosition; }
voice->_playback->_a_progress.start();
statusSize = -1 - (playbackState.position / (playbackState.frequency ? playbackState.frequency : AudioVoiceMsgFrequency));
realDuration = playbackState.duration / (playbackState.frequency ? playbackState.frequency : AudioVoiceMsgFrequency);
showPause = (playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerResuming || playbackState.state == AudioPlayerStarting);
} else {
if (auto voice = Get<HistoryDocumentVoice>()) {
voice->checkPlaybackFinished();
} }
} }
} else if (_data->song()) {
statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)); AudioMsgId playing;
realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency); auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Song);
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting); if (playing == AudioMsgId(_data, _parent->fullId()) && !(playbackState.state & AudioPlayerStoppedMask) && playbackState.state != AudioPlayerFinishing) {
} else { statusSize = -1 - (playbackState.position / (playbackState.frequency ? playbackState.frequency : AudioVoiceMsgFrequency));
statusSize = FileStatusSizeLoaded; realDuration = playbackState.duration / (playbackState.frequency ? playbackState.frequency : AudioVoiceMsgFrequency);
if (auto voice = Get<HistoryDocumentVoice>()) { showPause = (playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerResuming || playbackState.state == AudioPlayerStarting);
voice->checkPlaybackFinished(); } else {
}
if (!showPause && (playing == AudioMsgId(_data, _parent->fullId())) && App::main() && App::main()->player()->seekingSong(playing)) {
showPause = true;
} }
} }
} else if (_data->song()) {
AudioMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped;
int64 playingPosition = 0, playingDuration = 0;
int32 playingFrequency = 0;
if (audioPlayer()) {
audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState, &playingPosition, &playingDuration, &playingFrequency);
}
if (playing == AudioMsgId(_data, _parent->fullId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency));
realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency);
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
} else {
statusSize = FileStatusSizeLoaded;
}
if (!showPause && (playing == AudioMsgId(_data, _parent->fullId())) && App::main() && App::main()->player()->seekingSong(playing)) {
showPause = true;
}
} else {
statusSize = FileStatusSizeLoaded;
} }
} else { } else {
statusSize = FileStatusSizeReady; statusSize = FileStatusSizeReady;

View File

@ -854,39 +854,29 @@ bool File::updateStatusText() const {
statusSize = document->loadOffset(); statusSize = document->loadOffset();
} else if (document->loaded()) { } else if (document->loaded()) {
if (document->voice()) { if (document->voice()) {
AudioMsgId playing; statusSize = FileStatusSizeLoaded;
AudioPlayerState playingState = AudioPlayerStopped;
int64 playingPosition = 0, playingDuration = 0;
int32 playingFrequency = 0;
if (audioPlayer()) { if (audioPlayer()) {
audioPlayer()->currentState(&playing, AudioMsgId::Type::Voice, &playingState, &playingPosition, &playingDuration, &playingFrequency); AudioMsgId playing;
} auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Voice);
if (playing == AudioMsgId(document, FullMsgId()) && !(playbackState.state & AudioPlayerStoppedMask) && playbackState.state != AudioPlayerFinishing) {
if (playing == AudioMsgId(document, FullMsgId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { statusSize = -1 - (playbackState.position / (playbackState.frequency ? playbackState.frequency : AudioVoiceMsgFrequency));
statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)); realDuration = playbackState.duration / (playbackState.frequency ? playbackState.frequency : AudioVoiceMsgFrequency);
realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency); showPause = (playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerResuming || playbackState.state == AudioPlayerStarting);
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting); }
} else {
statusSize = FileStatusSizeLoaded;
} }
} else if (document->song()) { } else if (document->song()) {
AudioMsgId playing; statusSize = FileStatusSizeLoaded;
AudioPlayerState playingState = AudioPlayerStopped;
int64 playingPosition = 0, playingDuration = 0;
int32 playingFrequency = 0;
if (audioPlayer()) { if (audioPlayer()) {
audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState, &playingPosition, &playingDuration, &playingFrequency); AudioMsgId playing;
} auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Song);
if (playing == AudioMsgId(document, FullMsgId()) && !(playbackState.state & AudioPlayerStoppedMask) && playbackState.state != AudioPlayerFinishing) {
if (playing == AudioMsgId(document, FullMsgId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { statusSize = -1 - (playbackState.position / (playbackState.frequency ? playbackState.frequency : AudioVoiceMsgFrequency));
statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)); realDuration = playbackState.duration / (playbackState.frequency ? playbackState.frequency : AudioVoiceMsgFrequency);
realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency); showPause = (playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerResuming || playbackState.state == AudioPlayerStarting);
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting); }
} else { if (!showPause && (playing == AudioMsgId(document, FullMsgId())) && App::main() && App::main()->player()->seekingSong(playing)) {
statusSize = FileStatusSizeLoaded; showPause = true;
} }
if (!showPause && (playing == AudioMsgId(document, FullMsgId())) && App::main() && App::main()->player()->seekingSong(playing)) {
showPause = true;
} }
} else { } else {
statusSize = FileStatusSizeLoaded; statusSize = FileStatusSizeLoaded;

View File

@ -91,7 +91,6 @@ MainWidget::MainWidget(MainWindow *window) : TWidget(window)
connect(&updateNotifySettingTimer, SIGNAL(timeout()), this, SLOT(onUpdateNotifySettings())); connect(&updateNotifySettingTimer, SIGNAL(timeout()), this, SLOT(onUpdateNotifySettings()));
if (audioPlayer()) { if (audioPlayer()) {
connect(audioPlayer(), SIGNAL(updated(const AudioMsgId&)), this, SLOT(audioPlayProgress(const AudioMsgId&))); connect(audioPlayer(), SIGNAL(updated(const AudioMsgId&)), this, SLOT(audioPlayProgress(const AudioMsgId&)));
connect(audioPlayer(), SIGNAL(stopped(const AudioMsgId&)), this, SLOT(audioPlayProgress(const AudioMsgId&)));
} }
connect(&_updateMutedTimer, SIGNAL(timeout()), this, SLOT(onUpdateMuted())); connect(&_updateMutedTimer, SIGNAL(timeout()), this, SLOT(onUpdateMuted()));
connect(&_viewsIncrementTimer, SIGNAL(timeout()), this, SLOT(onViewsIncrement())); connect(&_viewsIncrementTimer, SIGNAL(timeout()), this, SLOT(onViewsIncrement()));
@ -1530,13 +1529,14 @@ void MainWidget::ui_autoplayMediaInlineAsync(qint32 channelId, qint32 msgId) {
} }
void MainWidget::audioPlayProgress(const AudioMsgId &audioId) { void MainWidget::audioPlayProgress(const AudioMsgId &audioId) {
if (audioId.type() == AudioMsgId::Type::Video) {
return;
}
AudioMsgId playing; AudioMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped; auto playbackState = audioPlayer()->currentState(&playing, audioId.type());
int64 playingPosition = 0, playingDuration = 0; if (playing == audioId && playbackState.state == AudioPlayerStoppedAtStart) {
int32 playingFrequency = 0; playbackState.state = AudioPlayerStopped;
audioPlayer()->currentState(&playing, audioId.type(), &playingState, &playingPosition, &playingDuration, &playingFrequency);
if (playing == audioId && playingState == AudioPlayerStoppedAtStart) {
playingState = AudioPlayerStopped;
audioPlayer()->clearStoppedAtStart(audioId); audioPlayer()->clearStoppedAtStart(audioId);
DocumentData *audio = audioId.audio(); DocumentData *audio = audioId.audio();
@ -1551,9 +1551,9 @@ void MainWidget::audioPlayProgress(const AudioMsgId &audioId) {
} }
if (playing == audioId && audioId.type() == AudioMsgId::Type::Song) { if (playing == audioId && audioId.type() == AudioMsgId::Type::Song) {
_player->updateState(playing, playingState, playingPosition, playingDuration, playingFrequency); _player->updateState(playing, playbackState);
if (!(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { if (!(playbackState.state & AudioPlayerStoppedMask) && playbackState.state != AudioPlayerFinishing) {
if (!_player->isOpened()) { if (!_player->isOpened()) {
_player->openPlayer(); _player->openPlayer();
if (_player->isHidden() && !_a_show.animating()) { if (_player->isHidden() && !_a_show.animating()) {
@ -1609,12 +1609,9 @@ void MainWidget::documentLoadProgress(FileLoader *loader) {
if (!document->loaded() && document->loading() && document->song() && audioPlayer()) { if (!document->loaded() && document->loading() && document->song() && audioPlayer()) {
AudioMsgId playing; AudioMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped; auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Song);
int64 playingPosition = 0, playingDuration = 0;
int32 playingFrequency = 0;
audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState, &playingPosition, &playingDuration, &playingFrequency);
if (playing.audio() == document && !_player->isHidden()) { if (playing.audio() == document && !_player->isHidden()) {
_player->updateState(playing, playingState, playingPosition, playingDuration, playingFrequency); _player->updateState(playing, playbackState);
} }
} }
} }

View File

@ -263,12 +263,10 @@ void AudioPlayer::AudioMsg::clear() {
audio = AudioMsgId(); audio = AudioMsgId();
file = FileLocation(); file = FileLocation();
data = QByteArray(); data = QByteArray();
position = duration = 0; playbackState = defaultState();
frequency = AudioVoiceMsgFrequency;
skipStart = skipEnd = 0; skipStart = skipEnd = 0;
loading = false; loading = false;
started = 0; started = 0;
state = AudioPlayerStopped;
if (alIsSource(source)) { if (alIsSource(source)) {
alSourceStop(source); alSourceStop(source);
} }
@ -305,7 +303,7 @@ _loader(new AudioPlayerLoaders(&_loaderThread)) {
connect(_fader, SIGNAL(playPositionUpdated(const AudioMsgId&)), this, SIGNAL(updated(const AudioMsgId&))); connect(_fader, SIGNAL(playPositionUpdated(const AudioMsgId&)), this, SIGNAL(updated(const AudioMsgId&)));
connect(_fader, SIGNAL(audioStopped(const AudioMsgId&)), this, SLOT(onStopped(const AudioMsgId&))); connect(_fader, SIGNAL(audioStopped(const AudioMsgId&)), this, SLOT(onStopped(const AudioMsgId&)));
connect(_fader, SIGNAL(error(const AudioMsgId&)), this, SLOT(onError(const AudioMsgId&))); connect(_fader, SIGNAL(error(const AudioMsgId&)), this, SLOT(onError(const AudioMsgId&)));
connect(this, SIGNAL(stoppedOnError(const AudioMsgId&)), this, SIGNAL(stopped(const AudioMsgId&)), Qt::QueuedConnection); connect(this, SIGNAL(stoppedOnError(const AudioMsgId&)), this, SIGNAL(updated(const AudioMsgId&)), Qt::QueuedConnection);
_loaderThread.start(); _loaderThread.start();
_faderThread.start(); _faderThread.start();
} }
@ -350,7 +348,7 @@ void AudioPlayer::onError(const AudioMsgId &audio) {
} }
void AudioPlayer::onStopped(const AudioMsgId &audio) { void AudioPlayer::onStopped(const AudioMsgId &audio) {
emit stopped(audio); emit updated(audio);
if (audio.type() == AudioMsgId::Type::Voice) { if (audio.type() == AudioMsgId::Type::Voice) {
emit unsuppressSong(); emit unsuppressSong();
} }
@ -399,7 +397,7 @@ bool AudioPlayer::updateCurrentStarted(AudioMsgId::Type type, int32 pos) {
return false; return false;
} }
} }
data->started = data->position = pos + data->skipStart; data->started = data->playbackState.position = pos + data->skipStart;
return true; return true;
} }
@ -407,16 +405,16 @@ bool AudioPlayer::fadedStop(AudioMsgId::Type type, bool *fadedStart) {
auto current = dataForType(type); auto current = dataForType(type);
if (!current) return false; if (!current) return false;
switch (current->state) { switch (current->playbackState.state) {
case AudioPlayerStarting: case AudioPlayerStarting:
case AudioPlayerResuming: case AudioPlayerResuming:
case AudioPlayerPlaying: case AudioPlayerPlaying:
current->state = AudioPlayerFinishing; current->playbackState.state = AudioPlayerFinishing;
updateCurrentStarted(type); updateCurrentStarted(type);
if (fadedStart) *fadedStart = true; if (fadedStart) *fadedStart = true;
break; break;
case AudioPlayerPausing: case AudioPlayerPausing:
current->state = AudioPlayerFinishing; current->playbackState.state = AudioPlayerFinishing;
if (fadedStart) *fadedStart = true; if (fadedStart) *fadedStart = true;
break; break;
case AudioPlayerPaused: case AudioPlayerPaused:
@ -473,7 +471,7 @@ void AudioPlayer::play(const AudioMsgId &audio, int64 position) {
onError(audio); onError(audio);
} }
} else { } else {
current->state = fadedStart ? AudioPlayerStarting : AudioPlayerPlaying; current->playbackState.state = fadedStart ? AudioPlayerStarting : AudioPlayerPlaying;
current->loading = true; current->loading = true;
emit loaderOnStart(audio, position); emit loaderOnStart(audio, position);
if (type == AudioMsgId::Type::Voice) { if (type == AudioMsgId::Type::Voice) {
@ -507,7 +505,7 @@ void AudioPlayer::playFromVideo(const AudioMsgId &audio, int64 position, std_::u
current->videoData = std_::move(data); current->videoData = std_::move(data);
_loader->startFromVideo(current->videoData->videoPlayId); _loader->startFromVideo(current->videoData->videoPlayId);
current->state = AudioPlayerPlaying; current->playbackState.state = AudioPlayerPlaying;
current->loading = true; current->loading = true;
emit loaderOnStart(audio, position); emit loaderOnStart(audio, position);
} }
@ -539,19 +537,19 @@ void AudioPlayer::pauseresume(AudioMsgId::Type type, bool fast) {
case AudioMsgId::Type::Song: suppressGain = suppressSongGain * cSongVolume(); break; case AudioMsgId::Type::Song: suppressGain = suppressSongGain * cSongVolume(); break;
} }
switch (current->state) { switch (current->playbackState.state) {
case AudioPlayerPausing: case AudioPlayerPausing:
case AudioPlayerPaused: case AudioPlayerPaused:
case AudioPlayerPausedAtEnd: { case AudioPlayerPausedAtEnd: {
if (current->state == AudioPlayerPaused) { if (current->playbackState.state == AudioPlayerPaused) {
updateCurrentStarted(type); updateCurrentStarted(type);
} else if (current->state == AudioPlayerPausedAtEnd) { } else if (current->playbackState.state == AudioPlayerPausedAtEnd) {
if (alIsSource(current->source)) { if (alIsSource(current->source)) {
alSourcei(current->source, AL_SAMPLE_OFFSET, qMax(current->position - current->skipStart, 0LL)); alSourcei(current->source, AL_SAMPLE_OFFSET, qMax(current->playbackState.position - current->skipStart, 0LL));
if (!checkCurrentALError(type)) return; if (!checkCurrentALError(type)) return;
} }
} }
current->state = fast ? AudioPlayerPlaying : AudioPlayerResuming; current->playbackState.state = fast ? AudioPlayerPlaying : AudioPlayerResuming;
ALint state = AL_INITIAL; ALint state = AL_INITIAL;
alGetSourcei(current->source, AL_SOURCE_STATE, &state); alGetSourcei(current->source, AL_SOURCE_STATE, &state);
@ -571,11 +569,11 @@ void AudioPlayer::pauseresume(AudioMsgId::Type type, bool fast) {
case AudioPlayerStarting: case AudioPlayerStarting:
case AudioPlayerResuming: case AudioPlayerResuming:
case AudioPlayerPlaying: case AudioPlayerPlaying:
current->state = AudioPlayerPausing; current->playbackState.state = AudioPlayerPausing;
updateCurrentStarted(type); updateCurrentStarted(type);
if (type == AudioMsgId::Type::Voice) emit unsuppressSong(); if (type == AudioMsgId::Type::Voice) emit unsuppressSong();
break; break;
case AudioPlayerFinishing: current->state = AudioPlayerPausing; break; case AudioPlayerFinishing: current->playbackState.state = AudioPlayerPausing; break;
} }
emit faderOnTimer(); emit faderOnTimer();
} }
@ -593,7 +591,7 @@ void AudioPlayer::seek(int64 position) {
auto audio = current->audio; auto audio = current->audio;
bool isSource = alIsSource(current->source); bool isSource = alIsSource(current->source);
bool fastSeek = (position >= current->skipStart && position < current->duration - current->skipEnd - (current->skipEnd ? AudioVoiceMsgFrequency : 0)); bool fastSeek = (position >= current->skipStart && position < current->playbackState.duration - current->skipEnd - (current->skipEnd ? AudioVoiceMsgFrequency : 0));
if (fastSeek && isSource) { if (fastSeek && isSource) {
alSourcei(current->source, AL_SAMPLE_OFFSET, position - current->skipStart); alSourcei(current->source, AL_SAMPLE_OFFSET, position - current->skipStart);
if (!checkCurrentALError(type)) return; if (!checkCurrentALError(type)) return;
@ -604,12 +602,12 @@ void AudioPlayer::seek(int64 position) {
setStoppedState(current); setStoppedState(current);
if (isSource) alSourceStop(current->source); if (isSource) alSourceStop(current->source);
} }
switch (current->state) { switch (current->playbackState.state) {
case AudioPlayerPausing: case AudioPlayerPausing:
case AudioPlayerPaused: case AudioPlayerPaused:
case AudioPlayerPausedAtEnd: { case AudioPlayerPausedAtEnd: {
if (current->state == AudioPlayerPausedAtEnd) { if (current->playbackState.state == AudioPlayerPausedAtEnd) {
current->state = AudioPlayerPaused; current->playbackState.state = AudioPlayerPaused;
} }
lock.unlock(); lock.unlock();
return pauseresume(type, true); return pauseresume(type, true);
@ -617,7 +615,7 @@ void AudioPlayer::seek(int64 position) {
case AudioPlayerStarting: case AudioPlayerStarting:
case AudioPlayerResuming: case AudioPlayerResuming:
case AudioPlayerPlaying: case AudioPlayerPlaying:
current->state = AudioPlayerPausing; current->playbackState.state = AudioPlayerPausing;
updateCurrentStarted(type); updateCurrentStarted(type);
if (type == AudioMsgId::Type::Voice) emit unsuppressSong(); if (type == AudioMsgId::Type::Voice) emit unsuppressSong();
break; break;
@ -683,31 +681,24 @@ void AudioPlayer::stopAndClear() {
} }
} }
void AudioPlayer::currentState(AudioMsgId *audio, AudioMsgId::Type type, AudioPlayerState *state, int64 *position, int64 *duration, int32 *frequency) { AudioPlaybackState AudioPlayer::currentState(AudioMsgId *audio, AudioMsgId::Type type) {
QMutexLocker lock(&playerMutex); QMutexLocker lock(&playerMutex);
auto current = dataForType(type); auto current = dataForType(type);
if (!current) return; if (!current) return AudioPlaybackState();
if (audio) *audio = current->audio; if (audio) *audio = current->audio;
return currentState(current, state, position, duration, frequency); return current->playbackState;
}
void AudioPlayer::currentState(AudioMsg *current, AudioPlayerState *state, int64 *position, int64 *duration, int32 *frequency) {
if (state) *state = current->state;
if (position) *position = current->position;
if (duration) *duration = current->duration;
if (frequency) *frequency = current->frequency;
} }
void AudioPlayer::setStoppedState(AudioMsg *current, AudioPlayerState state) { void AudioPlayer::setStoppedState(AudioMsg *current, AudioPlayerState state) {
current->state = state; current->playbackState.state = state;
current->position = 0; current->playbackState.position = 0;
} }
void AudioPlayer::clearStoppedAtStart(const AudioMsgId &audio) { void AudioPlayer::clearStoppedAtStart(const AudioMsgId &audio) {
QMutexLocker lock(&playerMutex); QMutexLocker lock(&playerMutex);
auto data = dataForType(audio.type()); auto data = dataForType(audio.type());
if (data && data->audio == audio && data->state == AudioPlayerStoppedAtStart) { if (data && data->audio == audio && data->playbackState.state == AudioPlayerStoppedAtStart) {
setStoppedState(data); setStoppedState(data);
} }
} }
@ -843,7 +834,7 @@ void AudioPlayerFader::onTimer() {
auto updatePlayback = [this, voice, &hasPlaying, &hasFading](AudioMsgId::Type type, int index, float64 suppressGain, bool suppressGainChanged) { auto updatePlayback = [this, voice, &hasPlaying, &hasFading](AudioMsgId::Type type, int index, float64 suppressGain, bool suppressGainChanged) {
auto data = voice->dataForType(type, index); auto data = voice->dataForType(type, index);
if ((data->state & AudioPlayerStoppedMask) || data->state == AudioPlayerPaused || !data->source) return; if ((data->playbackState.state & AudioPlayerStoppedMask) || data->playbackState.state == AudioPlayerPaused || !data->source) return;
int32 emitSignals = updateOnePlayback(data, hasPlaying, hasFading, suppressGain, suppressGainChanged); int32 emitSignals = updateOnePlayback(data, hasPlaying, hasFading, suppressGain, suppressGainChanged);
if (emitSignals & EmitError) emit error(data->audio); if (emitSignals & EmitError) emit error(data->audio);
@ -894,7 +885,7 @@ int32 AudioPlayerFader::updateOnePlayback(AudioPlayer::AudioMsg *m, bool &hasPla
if (!_checkALError()) { setStoppedState(m, AudioPlayerStoppedAtError); return EmitError; } if (!_checkALError()) { setStoppedState(m, AudioPlayerStoppedAtError); return EmitError; }
int32 emitSignals = 0; int32 emitSignals = 0;
switch (m->state) { switch (m->playbackState.state) {
case AudioPlayerFinishing: case AudioPlayerFinishing:
case AudioPlayerPausing: case AudioPlayerPausing:
case AudioPlayerStarting: case AudioPlayerStarting:
@ -914,17 +905,17 @@ int32 AudioPlayerFader::updateOnePlayback(AudioPlayer::AudioMsg *m, bool &hasPla
alSourcef(m->source, AL_GAIN, 1); alSourcef(m->source, AL_GAIN, 1);
if (!_checkALError()) { setStoppedState(m, AudioPlayerStoppedAtError); return EmitError; } if (!_checkALError()) { setStoppedState(m, AudioPlayerStoppedAtError); return EmitError; }
} }
if (m->state == AudioPlayerPausing) { if (m->playbackState.state == AudioPlayerPausing) {
m->state = AudioPlayerPausedAtEnd; m->playbackState.state = AudioPlayerPausedAtEnd;
} else { } else {
setStoppedState(m, AudioPlayerStoppedAtEnd); setStoppedState(m, AudioPlayerStoppedAtEnd);
} }
emitSignals |= EmitStopped; emitSignals |= EmitStopped;
} else if (1000 * (pos + m->skipStart - m->started) >= AudioFadeDuration * m->frequency) { } else if (1000 * (pos + m->skipStart - m->started) >= AudioFadeDuration * m->playbackState.frequency) {
fading = false; fading = false;
alSourcef(m->source, AL_GAIN, 1. * suppressGain); alSourcef(m->source, AL_GAIN, 1. * suppressGain);
if (!_checkALError()) { setStoppedState(m, AudioPlayerStoppedAtError); return EmitError; } if (!_checkALError()) { setStoppedState(m, AudioPlayerStoppedAtError); return EmitError; }
switch (m->state) { switch (m->playbackState.state) {
case AudioPlayerFinishing: case AudioPlayerFinishing:
alSourceStop(m->source); alSourceStop(m->source);
if (!_checkALError()) { setStoppedState(m, AudioPlayerStoppedAtError); return EmitError; } if (!_checkALError()) { setStoppedState(m, AudioPlayerStoppedAtError); return EmitError; }
@ -934,17 +925,17 @@ int32 AudioPlayerFader::updateOnePlayback(AudioPlayer::AudioMsg *m, bool &hasPla
case AudioPlayerPausing: case AudioPlayerPausing:
alSourcePause(m->source); alSourcePause(m->source);
if (!_checkALError()) { setStoppedState(m, AudioPlayerStoppedAtError); return EmitError; } if (!_checkALError()) { setStoppedState(m, AudioPlayerStoppedAtError); return EmitError; }
m->state = AudioPlayerPaused; m->playbackState.state = AudioPlayerPaused;
break; break;
case AudioPlayerStarting: case AudioPlayerStarting:
case AudioPlayerResuming: case AudioPlayerResuming:
m->state = AudioPlayerPlaying; m->playbackState.state = AudioPlayerPlaying;
playing = true; playing = true;
break; break;
} }
} else { } else {
float64 newGain = 1000. * (pos + m->skipStart - m->started) / (AudioFadeDuration * m->frequency); float64 newGain = 1000. * (pos + m->skipStart - m->started) / (AudioFadeDuration * m->playbackState.frequency);
if (m->state == AudioPlayerPausing || m->state == AudioPlayerFinishing) { if (m->playbackState.state == AudioPlayerPausing || m->playbackState.state == AudioPlayerFinishing) {
newGain = 1. - newGain; newGain = 1. - newGain;
} }
alSourcef(m->source, AL_GAIN, newGain * suppressGain); alSourcef(m->source, AL_GAIN, newGain * suppressGain);
@ -966,12 +957,12 @@ int32 AudioPlayerFader::updateOnePlayback(AudioPlayer::AudioMsg *m, bool &hasPla
if (!_checkALError()) { setStoppedState(m, AudioPlayerStoppedAtError); return EmitError; } if (!_checkALError()) { setStoppedState(m, AudioPlayerStoppedAtError); return EmitError; }
} }
} }
if (state == AL_PLAYING && pos + m->skipStart - m->position >= AudioCheckPositionDelta) { if (state == AL_PLAYING && pos + m->skipStart - m->playbackState.position >= AudioCheckPositionDelta) {
m->position = pos + m->skipStart; m->playbackState.position = pos + m->skipStart;
emitSignals |= EmitPositionUpdated; emitSignals |= EmitPositionUpdated;
} }
if (playing || m->state == AudioPlayerStarting || m->state == AudioPlayerResuming) { if (playing || m->playbackState.state == AudioPlayerStarting || m->playbackState.state == AudioPlayerResuming) {
if (!m->loading && m->skipEnd > 0 && m->position + AudioPreloadSamples + m->skipEnd > m->duration) { if (!m->loading && m->skipEnd > 0 && m->playbackState.position + AudioPreloadSamples + m->skipEnd > m->playbackState.duration) {
m->loading = true; m->loading = true;
emitSignals |= EmitNeedToPreload; emitSignals |= EmitNeedToPreload;
} }
@ -983,8 +974,8 @@ int32 AudioPlayerFader::updateOnePlayback(AudioPlayer::AudioMsg *m, bool &hasPla
} }
void AudioPlayerFader::setStoppedState(AudioPlayer::AudioMsg *m, AudioPlayerState state) { void AudioPlayerFader::setStoppedState(AudioPlayer::AudioMsg *m, AudioPlayerState state) {
m->state = state; m->playbackState.state = state;
m->position = 0; m->playbackState.position = 0;
} }
void AudioPlayerFader::onPauseTimer() { void AudioPlayerFader::onPauseTimer() {

View File

@ -48,12 +48,17 @@ class AudioPlayerLoaders;
struct VideoSoundData; struct VideoSoundData;
struct VideoSoundPart; struct VideoSoundPart;
struct AudioPlaybackState {
AudioPlayerState state = AudioPlayerStopped;
int64 position = 0;
int64 duration = 0;
int32 frequency = 0;
};
class AudioPlayer : public QObject { class AudioPlayer : public QObject {
Q_OBJECT Q_OBJECT
public: public:
AudioPlayer(); AudioPlayer();
void play(const AudioMsgId &audio, int64 position = 0); void play(const AudioMsgId &audio, int64 position = 0);
@ -64,10 +69,11 @@ public:
// Video player audio stream interface. // Video player audio stream interface.
void playFromVideo(const AudioMsgId &audio, int64 position, std_::unique_ptr<VideoSoundData> &&data); void playFromVideo(const AudioMsgId &audio, int64 position, std_::unique_ptr<VideoSoundData> &&data);
void feedFromVideo(VideoSoundPart &&part); void feedFromVideo(VideoSoundPart &&part);
AudioPlaybackState getStateForVideo(uint64 playId);
void stopAndClear(); void stopAndClear();
void currentState(AudioMsgId *audio, AudioMsgId::Type type, AudioPlayerState *state = 0, int64 *position = 0, int64 *duration = 0, int32 *frequency = 0); AudioPlaybackState currentState(AudioMsgId *audio, AudioMsgId::Type type);
void clearStoppedAtStart(const AudioMsgId &audio); void clearStoppedAtStart(const AudioMsgId &audio);
@ -76,14 +82,11 @@ public:
~AudioPlayer(); ~AudioPlayer();
public slots: public slots:
void onError(const AudioMsgId &audio); void onError(const AudioMsgId &audio);
void onStopped(const AudioMsgId &audio); void onStopped(const AudioMsgId &audio);
signals: signals:
void updated(const AudioMsgId &audio); void updated(const AudioMsgId &audio);
void stopped(const AudioMsgId &audio);
void stoppedOnError(const AudioMsgId &audio); void stoppedOnError(const AudioMsgId &audio);
void loaderOnStart(const AudioMsgId &audio, qint64 position); void loaderOnStart(const AudioMsgId &audio, qint64 position);
void loaderOnCancel(const AudioMsgId &audio); void loaderOnCancel(const AudioMsgId &audio);
@ -97,7 +100,6 @@ signals:
void songVolumeChanged(); void songVolumeChanged();
private: private:
bool fadedStop(AudioMsgId::Type type, bool *fadedStart = 0); bool fadedStop(AudioMsgId::Type type, bool *fadedStart = 0);
bool updateCurrentStarted(AudioMsgId::Type type, int32 pos = -1); bool updateCurrentStarted(AudioMsgId::Type type, int32 pos = -1);
bool checkCurrentALError(AudioMsgId::Type type); bool checkCurrentALError(AudioMsgId::Type type);
@ -109,14 +111,11 @@ private:
FileLocation file; FileLocation file;
QByteArray data; QByteArray data;
int64 position = 0; AudioPlaybackState playbackState = defaultState();
int64 duration = 0;
int32 frequency = AudioVoiceMsgFrequency;
int64 skipStart = 0; int64 skipStart = 0;
int64 skipEnd = 0; int64 skipEnd = 0;
bool loading = false; bool loading = false;
int64 started = 0; int64 started = 0;
AudioPlayerState state = AudioPlayerStopped;
uint32 source = 0; uint32 source = 0;
int32 nextBuffer = 0; int32 nextBuffer = 0;
@ -124,9 +123,16 @@ private:
int64 samplesCount[3] = { 0 }; int64 samplesCount[3] = { 0 };
std_::unique_ptr<VideoSoundData> videoData; std_::unique_ptr<VideoSoundData> videoData;
private:
static AudioPlaybackState defaultState() {
AudioPlaybackState result;
result.frequency = AudioVoiceMsgFrequency;
return result;
}
}; };
void currentState(AudioMsg *current, AudioPlayerState *state, int64 *position, int64 *duration, int32 *frequency);
void setStoppedState(AudioMsg *current, AudioPlayerState state = AudioPlayerStopped); void setStoppedState(AudioMsg *current, AudioPlayerState state = AudioPlayerStopped);
AudioMsg *dataForType(AudioMsgId::Type type, int index = -1); // -1 uses currentIndex(type) AudioMsg *dataForType(AudioMsgId::Type type, int index = -1); // -1 uses currentIndex(type)
@ -141,6 +147,8 @@ private:
AudioMsg _songData[AudioSimultaneousLimit]; AudioMsg _songData[AudioSimultaneousLimit];
AudioMsg _videoData; AudioMsg _videoData;
uint64 _lastVideoPlayId;
AudioPlaybackState _lastVideoPlaybackState;
QMutex _mutex; QMutex _mutex;

View File

@ -112,8 +112,8 @@ AudioMsgId AudioPlayerLoaders::clear(AudioMsgId::Type type) {
} }
void AudioPlayerLoaders::setStoppedState(AudioPlayer::AudioMsg *m, AudioPlayerState state) { void AudioPlayerLoaders::setStoppedState(AudioPlayer::AudioMsg *m, AudioPlayerState state) {
m->state = state; m->playbackState.state = state;
m->position = 0; m->playbackState.position = 0;
} }
void AudioPlayerLoaders::emitError(AudioMsgId::Type type) { void AudioPlayerLoaders::emitError(AudioMsgId::Type type) {
@ -153,7 +153,7 @@ void AudioPlayerLoaders::loadData(AudioMsgId audio, qint64 position) {
{ {
QMutexLocker lock(internal::audioPlayerMutex()); QMutexLocker lock(internal::audioPlayerMutex());
AudioPlayer::AudioMsg *m = checkLoader(type); AudioPlayer::AudioMsg *m = checkLoader(type);
if (m) m->state = AudioPlayerStoppedAtStart; if (m) m->playbackState.state = AudioPlayerStoppedAtStart;
} }
emitError(type); emitError(type);
return; return;
@ -200,8 +200,8 @@ void AudioPlayerLoaders::loadData(AudioMsgId audio, qint64 position) {
m->nextBuffer = 0; m->nextBuffer = 0;
} }
m->skipStart = position; m->skipStart = position;
m->skipEnd = m->duration - position; m->skipEnd = m->playbackState.duration - position;
m->position = 0; m->playbackState.position = 0;
m->started = 0; m->started = 0;
} }
if (samplesCount) { if (samplesCount) {
@ -280,12 +280,12 @@ void AudioPlayerLoaders::loadData(AudioMsgId audio, qint64 position) {
if (finished) { if (finished) {
m->skipEnd = 0; m->skipEnd = 0;
m->duration = m->skipStart + m->samplesCount[0] + m->samplesCount[1] + m->samplesCount[2]; m->playbackState.duration = m->skipStart + m->samplesCount[0] + m->samplesCount[1] + m->samplesCount[2];
clear(type); clear(type);
} }
m->loading = false; m->loading = false;
if (m->state == AudioPlayerResuming || m->state == AudioPlayerPlaying || m->state == AudioPlayerStarting) { if (m->playbackState.state == AudioPlayerResuming || m->playbackState.state == AudioPlayerPlaying || m->playbackState.state == AudioPlayerStarting) {
ALint state = AL_INITIAL; ALint state = AL_INITIAL;
alGetSourcei(m->source, AL_SOURCE_STATE, &state); alGetSourcei(m->source, AL_SOURCE_STATE, &state);
if (internal::audioCheckError()) { if (internal::audioCheckError()) {
@ -356,7 +356,7 @@ AudioPlayerLoader *AudioPlayerLoaders::setupLoader(const AudioMsgId &audio, Setu
if (audio.type() == AudioMsgId::Type::Video) { if (audio.type() == AudioMsgId::Type::Video) {
if (!data->videoData) { if (!data->videoData) {
data->state = AudioPlayerStoppedAtError; data->playbackState.state = AudioPlayerStoppedAtError;
emit error(audio); emit error(audio);
LOG(("Audio Error: video sound data not ready")); LOG(("Audio Error: video sound data not ready"));
return nullptr; return nullptr;
@ -369,17 +369,17 @@ AudioPlayerLoader *AudioPlayerLoaders::setupLoader(const AudioMsgId &audio, Setu
} }
if (!l->open(position)) { if (!l->open(position)) {
data->state = AudioPlayerStoppedAtStart; data->playbackState.state = AudioPlayerStoppedAtStart;
return nullptr; return nullptr;
} }
int64 duration = l->duration(); int64 duration = l->duration();
if (duration <= 0) { if (duration <= 0) {
data->state = AudioPlayerStoppedAtStart; data->playbackState.state = AudioPlayerStoppedAtStart;
return nullptr; return nullptr;
} }
data->duration = duration; data->playbackState.duration = duration;
data->frequency = l->frequency(); data->playbackState.frequency = l->frequency();
if (!data->frequency) data->frequency = AudioVoiceMsgFrequency; if (!data->playbackState.frequency) data->playbackState.frequency = AudioVoiceMsgFrequency;
err = SetupNoErrorStarted; err = SetupNoErrorStarted;
} else { } else {
if (!data->skipEnd) { if (!data->skipEnd) {

View File

@ -35,7 +35,6 @@ namespace internal {
class FFMpegReaderImplementation : public ReaderImplementation { class FFMpegReaderImplementation : public ReaderImplementation {
public: public:
FFMpegReaderImplementation(FileLocation *location, QByteArray *data); FFMpegReaderImplementation(FileLocation *location, QByteArray *data);
bool readNextFrame() override; bool readNextFrame() override;

View File

@ -26,7 +26,6 @@ class MediaView : public TWidget, public RPCSender, public ClickHandlerHost {
Q_OBJECT Q_OBJECT
public: public:
MediaView(); MediaView();
void paintEvent(QPaintEvent *e) override; void paintEvent(QPaintEvent *e) override;
@ -83,7 +82,6 @@ public:
void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) override; void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) override;
public slots: public slots:
void onHideControls(bool force = false); void onHideControls(bool force = false);
void onDropdownHiding(); void onDropdownHiding();
@ -109,7 +107,6 @@ public slots:
void updateImage(); void updateImage();
private: private:
void displayPhoto(PhotoData *photo, HistoryItem *item); void displayPhoto(PhotoData *photo, HistoryItem *item);
void displayDocument(DocumentData *doc, HistoryItem *item); void displayDocument(DocumentData *doc, HistoryItem *item);
void findCurrent(); void findCurrent();

View File

@ -556,20 +556,15 @@ bool Voice::updateStatusText() const {
if (_data->status == FileDownloadFailed || _data->status == FileUploadFailed) { if (_data->status == FileDownloadFailed || _data->status == FileUploadFailed) {
statusSize = FileStatusSizeFailed; statusSize = FileStatusSizeFailed;
} else if (_data->loaded()) { } else if (_data->loaded()) {
AudioMsgId playing; statusSize = FileStatusSizeLoaded;
AudioPlayerState playingState = AudioPlayerStopped;
int64 playingPosition = 0, playingDuration = 0;
int32 playingFrequency = 0;
if (audioPlayer()) { if (audioPlayer()) {
audioPlayer()->currentState(&playing, AudioMsgId::Type::Voice, &playingState, &playingPosition, &playingDuration, &playingFrequency); AudioMsgId playing;
} auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Voice);
if (playing == AudioMsgId(_data, _parent->fullId()) && !(playbackState.state & AudioPlayerStoppedMask) && playbackState.state != AudioPlayerFinishing) {
if (playing == AudioMsgId(_data, _parent->fullId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { statusSize = -1 - (playbackState.position / (playbackState.frequency ? playbackState.frequency : AudioVoiceMsgFrequency));
statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)); realDuration = playbackState.duration / (playbackState.frequency ? playbackState.frequency : AudioVoiceMsgFrequency);
realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency); showPause = (playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerResuming || playbackState.state == AudioPlayerStarting);
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting); }
} else {
statusSize = FileStatusSizeLoaded;
} }
} else { } else {
statusSize = FileStatusSizeReady; statusSize = FileStatusSizeReady;
@ -865,23 +860,18 @@ bool Document::updateStatusText() const {
statusSize = _data->loadOffset(); statusSize = _data->loadOffset();
} else if (_data->loaded()) { } else if (_data->loaded()) {
if (_data->song()) { if (_data->song()) {
AudioMsgId playing; statusSize = FileStatusSizeLoaded;
AudioPlayerState playingState = AudioPlayerStopped;
int64 playingPosition = 0, playingDuration = 0;
int32 playingFrequency = 0;
if (audioPlayer()) { if (audioPlayer()) {
audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState, &playingPosition, &playingDuration, &playingFrequency); AudioMsgId playing;
} auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Song);
if (playing == AudioMsgId(_data, _parent->fullId()) && !(playbackState.state & AudioPlayerStoppedMask) && playbackState.state != AudioPlayerFinishing) {
if (playing == AudioMsgId(_data, _parent->fullId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { statusSize = -1 - (playbackState.position / (playbackState.frequency ? playbackState.frequency : AudioVoiceMsgFrequency));
statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)); realDuration = playbackState.duration / (playbackState.frequency ? playbackState.frequency : AudioVoiceMsgFrequency);
realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency); showPause = (playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerResuming || playbackState.state == AudioPlayerStarting);
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting); }
} else { if (!showPause && (playing == AudioMsgId(_data, _parent->fullId())) && App::main() && App::main()->player()->seekingSong(playing)) {
statusSize = FileStatusSizeLoaded; showPause = true;
} }
if (!showPause && (playing == AudioMsgId(_data, _parent->fullId())) && App::main() && App::main()->player()->seekingSong(playing)) {
showPause = true;
} }
} else { } else {
statusSize = FileStatusSizeLoaded; statusSize = FileStatusSizeLoaded;

View File

@ -2092,8 +2092,7 @@ int32 OverviewWidget::lastScrollTop() const {
int32 OverviewWidget::countBestScroll() const { int32 OverviewWidget::countBestScroll() const {
if (type() == OverviewMusicFiles && audioPlayer()) { if (type() == OverviewMusicFiles && audioPlayer()) {
AudioMsgId playing; AudioMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped; audioPlayer()->currentState(&playing, AudioMsgId::Type::Song);
audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState);
if (playing) { if (playing) {
int32 top = _inner.itemTop(playing.contextId()); int32 top = _inner.itemTop(playing.contextId());
if (top >= 0) { if (top >= 0) {

View File

@ -169,18 +169,15 @@ void PlayerWidget::mousePressEvent(QMouseEvent *e) {
rtlupdate(_volumeRect); rtlupdate(_volumeRect);
} else if (_over == OverPlayback) { } else if (_over == OverPlayback) {
AudioMsgId playing; AudioMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped; auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Song);
int64 playingPosition = 0, playingDuration = 0; if (playing == _song && playbackState.duration) {
int32 playingFrequency = 0; if (playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerStarting || playbackState.state == AudioPlayerResuming) {
audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState, &playingPosition, &playingDuration, &playingFrequency);
if (playing == _song && playingDuration) {
if (playingState == AudioPlayerPlaying || playingState == AudioPlayerStarting || playingState == AudioPlayerResuming) {
audioPlayer()->pauseresume(AudioMsgId::Type::Song); audioPlayer()->pauseresume(AudioMsgId::Type::Song);
} }
_down = OverPlayback; _down = OverPlayback;
_downProgress = snap((pos.x() - _playbackRect.x()) / float64(_playbackRect.width()), 0., 1.); _downProgress = snap((pos.x() - _playbackRect.x()) / float64(_playbackRect.width()), 0., 1.);
_downDuration = playingDuration; _downDuration = playbackState.duration;
_downFrequency = (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency); _downFrequency = (playbackState.frequency ? playbackState.frequency : AudioVoiceMsgFrequency);
rtlupdate(_playbackRect); rtlupdate(_playbackRect);
updateDownTime(); updateDownTime();
@ -444,12 +441,9 @@ void PlayerWidget::mouseReleaseEvent(QMouseEvent *e) {
} else if (_down == OverPlayback) { } else if (_down == OverPlayback) {
mouseMoveEvent(e); mouseMoveEvent(e);
AudioMsgId playing; AudioMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped; auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Song);
int64 playingPosition = 0, playingDuration = 0; if (playing == _song && playbackState.duration) {
int32 playingFrequency = 0; _downDuration = playbackState.duration;
audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState, &playingPosition, &playingDuration, &playingFrequency);
if (playing == _song && playingDuration) {
_downDuration = playingDuration;
audioPlayer()->seek(qRound(_downProgress * _downDuration)); audioPlayer()->seek(qRound(_downProgress * _downDuration));
_showPause = true; _showPause = true;
@ -468,10 +462,9 @@ void PlayerWidget::playPressed() {
if (!_song || isHidden()) return; if (!_song || isHidden()) return;
AudioMsgId playing; AudioMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped; auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Song);
audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState); if (playing == _song && !(playbackState.state & AudioPlayerStoppedMask)) {
if (playing == _song && !(playingState & AudioPlayerStoppedMask)) { if (playbackState.state == AudioPlayerPausing || playbackState.state == AudioPlayerPaused || playbackState.state == AudioPlayerPausedAtEnd) {
if (playingState == AudioPlayerPausing || playingState == AudioPlayerPaused || playingState == AudioPlayerPausedAtEnd) {
audioPlayer()->pauseresume(AudioMsgId::Type::Song); audioPlayer()->pauseresume(AudioMsgId::Type::Song);
} }
} else { } else {
@ -484,10 +477,9 @@ void PlayerWidget::pausePressed() {
if (!_song || isHidden()) return; if (!_song || isHidden()) return;
AudioMsgId playing; AudioMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped; auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Song);
audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState); if (playing == _song && !(playbackState.state & AudioPlayerStoppedMask)) {
if (playing == _song && !(playingState & AudioPlayerStoppedMask)) { if (playbackState.state == AudioPlayerStarting || playbackState.state == AudioPlayerResuming || playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerFinishing) {
if (playingState == AudioPlayerStarting || playingState == AudioPlayerResuming || playingState == AudioPlayerPlaying || playingState == AudioPlayerFinishing) {
audioPlayer()->pauseresume(AudioMsgId::Type::Song); audioPlayer()->pauseresume(AudioMsgId::Type::Song);
} }
} }
@ -497,9 +489,8 @@ void PlayerWidget::playPausePressed() {
if (!_song || isHidden()) return; if (!_song || isHidden()) return;
AudioMsgId playing; AudioMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped; auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Song);
audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState); if (playing == _song && !(playbackState.state & AudioPlayerStoppedMask)) {
if (playing == _song && !(playingState & AudioPlayerStoppedMask)) {
audioPlayer()->pauseresume(AudioMsgId::Type::Song); audioPlayer()->pauseresume(AudioMsgId::Type::Song);
} else { } else {
audioPlayer()->play(_song); audioPlayer()->play(_song);
@ -581,12 +572,12 @@ void PlayerWidget::step_progress(float64 ms, bool timer) {
} }
void PlayerWidget::updateState() { void PlayerWidget::updateState() {
updateState(AudioMsgId(), AudioPlayerStopped, 0, 0, 0); updateState(AudioMsgId(), AudioPlaybackState());
} }
void PlayerWidget::updateState(AudioMsgId playing, AudioPlayerState playingState, int64 playingPosition, int64 playingDuration, int32 playingFrequency) { void PlayerWidget::updateState(AudioMsgId playing, AudioPlaybackState playbackState) {
if (!playing) { if (!playing) {
audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState, &playingPosition, &playingDuration, &playingFrequency); playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Song);
} }
bool songChanged = false; bool songChanged = false;
@ -622,20 +613,20 @@ void PlayerWidget::updateState(AudioMsgId playing, AudioPlayerState playingState
qint64 position = 0, duration = 0, display = 0; qint64 position = 0, duration = 0, display = 0;
if (playing == _song) { if (playing == _song) {
if (!(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { if (!(playbackState.state & AudioPlayerStoppedMask) && playbackState.state != AudioPlayerFinishing) {
display = position = playingPosition; display = position = playbackState.position;
duration = playingDuration; duration = playbackState.duration;
} else { } else {
display = playingDuration; display = playbackState.duration;
} }
display = display / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency); display = display / (playbackState.frequency ? playbackState.frequency : AudioVoiceMsgFrequency);
} else if (_song) { } else if (_song) {
display = _song.audio()->song()->duration; display = _song.audio()->song()->duration;
} }
bool showPause = false, stopped = ((playingState & AudioPlayerStoppedMask) || playingState == AudioPlayerFinishing); bool showPause = false, stopped = ((playbackState.state & AudioPlayerStoppedMask) || playbackState.state == AudioPlayerFinishing);
bool wasPlaying = (_duration != 0); bool wasPlaying = (_duration != 0);
if (!stopped) { if (!stopped) {
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting); showPause = (playbackState.state == AudioPlayerPlaying || playbackState.state == AudioPlayerResuming || playbackState.state == AudioPlayerStarting);
} }
QString time; QString time;
float64 progress = 0.; float64 progress = 0.;
@ -686,7 +677,7 @@ void PlayerWidget::updateState(AudioMsgId playing, AudioPlayerState playingState
_loaded = loaded; _loaded = loaded;
} }
if (wasPlaying && playingState == AudioPlayerStoppedAtEnd) { if (wasPlaying && playbackState.state == AudioPlayerStoppedAtEnd) {
if (_repeat) { if (_repeat) {
if (_song.audio()) { if (_song.audio()) {
audioPlayer()->play(_song, OverviewMusicFiles); audioPlayer()->play(_song, OverviewMusicFiles);

View File

@ -47,7 +47,7 @@ public:
void step_progress(float64 ms, bool timer); void step_progress(float64 ms, bool timer);
void step_state(uint64 ms, bool timer); void step_state(uint64 ms, bool timer);
void updateState(AudioMsgId playing, AudioPlayerState playingState, int64 playingPosition, int64 playingDuration, int32 playingFrequency); void updateState(AudioMsgId playing, AudioPlaybackState playbackState);
void updateState(); void updateState();
void clearSelection(); void clearSelection();

View File

@ -953,9 +953,8 @@ void DocumentOpenClickHandler::doOpen(DocumentData *data, ActionOnLoad action) {
if (!location.isEmpty() || (!data->data().isEmpty() && (playVoice || playMusic || playVideo || playAnimation))) { if (!location.isEmpty() || (!data->data().isEmpty() && (playVoice || playMusic || playVideo || playAnimation))) {
if (playVoice) { if (playVoice) {
AudioMsgId playing; AudioMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped; auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Voice);
audioPlayer()->currentState(&playing, AudioMsgId::Type::Voice, &playingState); if (playing == AudioMsgId(data, msgId) && !(playbackState.state & AudioPlayerStoppedMask) && playbackState.state != AudioPlayerFinishing) {
if (playing == AudioMsgId(data, msgId) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
audioPlayer()->pauseresume(AudioMsgId::Type::Voice); audioPlayer()->pauseresume(AudioMsgId::Type::Voice);
} else { } else {
AudioMsgId audio(data, msgId); AudioMsgId audio(data, msgId);
@ -967,9 +966,8 @@ void DocumentOpenClickHandler::doOpen(DocumentData *data, ActionOnLoad action) {
} }
} else if (playMusic) { } else if (playMusic) {
AudioMsgId playing; AudioMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped; auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Song);
audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState); if (playing == AudioMsgId(data, msgId) && !(playbackState.state & AudioPlayerStoppedMask) && playbackState.state != AudioPlayerFinishing) {
if (playing == AudioMsgId(data, msgId) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
audioPlayer()->pauseresume(AudioMsgId::Type::Song); audioPlayer()->pauseresume(AudioMsgId::Type::Song);
} else { } else {
AudioMsgId song(data, msgId); AudioMsgId song(data, msgId);
@ -1252,9 +1250,8 @@ void DocumentData::performActionOnLoad() {
if (playVoice) { if (playVoice) {
if (loaded()) { if (loaded()) {
AudioMsgId playing; AudioMsgId playing;
AudioPlayerState state = AudioPlayerStopped; auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Voice);
audioPlayer()->currentState(&playing, AudioMsgId::Type::Voice, &state); if (playing == AudioMsgId(this, _actionOnLoadMsgId) && !(playbackState.state & AudioPlayerStoppedMask) && playbackState.state != AudioPlayerFinishing) {
if (playing == AudioMsgId(this, _actionOnLoadMsgId) && !(state & AudioPlayerStoppedMask) && state != AudioPlayerFinishing) {
audioPlayer()->pauseresume(AudioMsgId::Type::Voice); audioPlayer()->pauseresume(AudioMsgId::Type::Voice);
} else { } else {
audioPlayer()->play(AudioMsgId(this, _actionOnLoadMsgId)); audioPlayer()->play(AudioMsgId(this, _actionOnLoadMsgId));
@ -1264,9 +1261,8 @@ void DocumentData::performActionOnLoad() {
} else if (playMusic) { } else if (playMusic) {
if (loaded()) { if (loaded()) {
AudioMsgId playing; AudioMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped; auto playbackState = audioPlayer()->currentState(&playing, AudioMsgId::Type::Song);
audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState); if (playing == AudioMsgId(this, _actionOnLoadMsgId) && !(playbackState.state & AudioPlayerStoppedMask) && playbackState.state != AudioPlayerFinishing) {
if (playing == AudioMsgId(this, _actionOnLoadMsgId) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
audioPlayer()->pauseresume(AudioMsgId::Type::Song); audioPlayer()->pauseresume(AudioMsgId::Type::Song);
} else { } else {
AudioMsgId song(this, _actionOnLoadMsgId); AudioMsgId song(this, _actionOnLoadMsgId);