diff --git a/Telegram/SourceFiles/audio.cpp b/Telegram/SourceFiles/audio.cpp index 8b94575b2..dfdfd17f5 100644 --- a/Telegram/SourceFiles/audio.cpp +++ b/Telegram/SourceFiles/audio.cpp @@ -41,13 +41,13 @@ extern "C" { #undef iconv #undef iconv_close -iconv_t iconv_open (const char* tocode, const char* fromcode) { +iconv_t iconv_open(const char* tocode, const char* fromcode) { return libiconv_open(tocode, fromcode); } -size_t iconv (iconv_t cd, char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft) { +size_t iconv(iconv_t cd, char** inbuf, size_t *inbytesleft, char** outbuf, size_t *outbytesleft) { return libiconv(cd, inbuf, inbytesleft, outbuf, outbytesleft); } -int iconv_close (iconv_t cd) { +int iconv_close(iconv_t cd) { return libiconv_close(cd); } #endif // Q_OS_MAC @@ -98,7 +98,6 @@ bool _checkALError() { } Q_DECLARE_METATYPE(AudioMsgId); -Q_DECLARE_METATYPE(SongMsgId); Q_DECLARE_METATYPE(VoiceWaveform); void audioInit() { if (!capture) { @@ -209,7 +208,6 @@ void audioInit() { if (!_checkALError()) return audioFinish(); qRegisterMetaType(); - qRegisterMetaType(); qRegisterMetaType(); player = new AudioPlayer(); @@ -263,7 +261,8 @@ void audioFinish() { cSetHasAudioPlayer(false); } -void AudioPlayer::Msg::clearData() { +void AudioPlayer::AudioMsg::clear() { + audio = AudioMsgId(); file = FileLocation(); data = QByteArray(); position = duration = 0; @@ -293,26 +292,18 @@ _loader(new AudioPlayerLoaders(&_loaderThread)) { connect(this, SIGNAL(suppressAll()), _fader, SLOT(onSuppressAll())); connect(this, SIGNAL(songVolumeChanged()), _fader, SLOT(onSongVolumeChanged())); connect(this, SIGNAL(loaderOnStart(const AudioMsgId&,qint64)), _loader, SLOT(onStart(const AudioMsgId&,qint64))); - connect(this, SIGNAL(loaderOnStart(const SongMsgId&,qint64)), _loader, SLOT(onStart(const SongMsgId&,qint64))); connect(this, SIGNAL(loaderOnCancel(const AudioMsgId&)), _loader, SLOT(onCancel(const AudioMsgId&))); - connect(this, SIGNAL(loaderOnCancel(const SongMsgId&)), _loader, SLOT(onCancel(const SongMsgId&))); connect(&_faderThread, SIGNAL(started()), _fader, SLOT(onInit())); connect(&_loaderThread, SIGNAL(started()), _loader, SLOT(onInit())); connect(&_faderThread, SIGNAL(finished()), _fader, SLOT(deleteLater())); connect(&_loaderThread, SIGNAL(finished()), _loader, SLOT(deleteLater())); connect(_loader, SIGNAL(needToCheck()), _fader, SLOT(onTimer())); connect(_loader, SIGNAL(error(const AudioMsgId&)), this, SLOT(onError(const AudioMsgId&))); - connect(_loader, SIGNAL(error(const SongMsgId&)), this, SLOT(onError(const SongMsgId&))); connect(_fader, SIGNAL(needToPreload(const AudioMsgId&)), _loader, SLOT(onLoad(const AudioMsgId&))); - connect(_fader, SIGNAL(needToPreload(const SongMsgId&)), _loader, SLOT(onLoad(const SongMsgId&))); connect(_fader, SIGNAL(playPositionUpdated(const AudioMsgId&)), this, SIGNAL(updated(const AudioMsgId&))); - connect(_fader, SIGNAL(playPositionUpdated(const SongMsgId&)), this, SIGNAL(updated(const SongMsgId&))); connect(_fader, SIGNAL(audioStopped(const AudioMsgId&)), this, SLOT(onStopped(const AudioMsgId&))); - connect(_fader, SIGNAL(audioStopped(const SongMsgId&)), this, SLOT(onStopped(const SongMsgId&))); connect(_fader, SIGNAL(error(const AudioMsgId&)), this, SLOT(onError(const AudioMsgId&))); - connect(_fader, SIGNAL(error(const SongMsgId&)), this, SLOT(onError(const SongMsgId&))); connect(this, SIGNAL(stoppedOnError(const AudioMsgId&)), this, SIGNAL(stopped(const AudioMsgId&)), Qt::QueuedConnection); - connect(this, SIGNAL(stoppedOnError(const SongMsgId&)), this, SIGNAL(stopped(const SongMsgId&)), Qt::QueuedConnection); _loaderThread.start(); _faderThread.start(); } @@ -323,31 +314,23 @@ AudioPlayer::~AudioPlayer() { player = 0; } - for (int32 i = 0; i < AudioVoiceMsgSimultaneously; ++i) { - alSourceStop(_audioData[i].source); - if (alIsBuffer(_audioData[i].buffers[0])) { - alDeleteBuffers(3, _audioData[i].buffers); - for (int32 j = 0; j < 3; ++j) { - _audioData[i].buffers[j] = _audioData[i].samplesCount[j] = 0; + auto clearAudioMsg = [](AudioMsg *msg) { + alSourceStop(msg->source); + if (alIsBuffer(msg->buffers[0])) { + alDeleteBuffers(3, msg->buffers); + for (int j = 0; j < 3; ++j) { + msg->buffers[j] = msg->samplesCount[j] = 0; } } - if (alIsSource(_audioData[i].source)) { - alDeleteSources(1, &_audioData[i].source); - _audioData[i].source = 0; - } - } - for (int32 i = 0; i < AudioSongSimultaneously; ++i) { - alSourceStop(_songData[i].source); - if (alIsBuffer(_songData[i].buffers[0])) { - alDeleteBuffers(3, _songData[i].buffers); - for (int32 j = 0; j < 3; ++j) { - _songData[i].buffers[j] = _songData[i].samplesCount[j] = 0; - } - } - if (alIsSource(_songData[i].source)) { - alDeleteSources(1, &_songData[i].source); - _songData[i].source = 0; + if (alIsSource(msg->source)) { + alDeleteSources(1, &msg->source); + msg->source = 0; } + }; + + for (int i = 0; i < AudioSimultaneousLimit; ++i) { + clearAudioMsg(dataForType(AudioMsgId::Type::Voice, i)); + clearAudioMsg(dataForType(AudioMsgId::Type::Song, i)); } _faderThread.quit(); _loaderThread.quit(); @@ -357,28 +340,45 @@ AudioPlayer::~AudioPlayer() { void AudioPlayer::onError(const AudioMsgId &audio) { emit stoppedOnError(audio); - emit unsuppressSong(); -} - -void AudioPlayer::onError(const SongMsgId &song) { - emit stoppedOnError(song); + if (audio.type() == AudioMsgId::Type::Voice) { + emit unsuppressSong(); + } } void AudioPlayer::onStopped(const AudioMsgId &audio) { emit stopped(audio); - emit unsuppressSong(); -} - -void AudioPlayer::onStopped(const SongMsgId &song) { - emit stopped(song); -} - -bool AudioPlayer::updateCurrentStarted(MediaOverviewType type, int32 pos) { - Msg *data = 0; - switch (type) { - case OverviewVoiceFiles: data = &_audioData[_audioCurrent]; break; - case OverviewFiles: data = &_songData[_songCurrent]; break; + if (audio.type() == AudioMsgId::Type::Voice) { + emit unsuppressSong(); } +} + +AudioPlayer::AudioMsg *AudioPlayer::dataForType(AudioMsgId::Type type, int index) { + if (index < 0) index = *currentIndex(type); + switch (type) { + case AudioMsgId::Type::Voice: return &_audioData[index]; + case AudioMsgId::Type::Song: return &_songData[index]; + } + return nullptr; +} + +const AudioPlayer::AudioMsg *AudioPlayer::dataForType(AudioMsgId::Type type, int index) const { + return const_cast(this)->dataForType(type, index); +} + +int *AudioPlayer::currentIndex(AudioMsgId::Type type) { + switch (type) { + case AudioMsgId::Type::Voice: return &_audioCurrent; + case AudioMsgId::Type::Song: return &_songCurrent; + } + return nullptr; +} + +const int *AudioPlayer::currentIndex(AudioMsgId::Type type) const { + return const_cast(this)->currentIndex(type); +} + +bool AudioPlayer::updateCurrentStarted(AudioMsgId::Type type, int32 pos) { + auto data = dataForType(type); if (!data) return false; if (pos < 0) { @@ -389,10 +389,7 @@ bool AudioPlayer::updateCurrentStarted(MediaOverviewType type, int32 pos) { } if (!_checkALError()) { setStoppedState(data, AudioPlayerStoppedAtError); - switch (type) { - case OverviewVoiceFiles: onError(_audioData[_audioCurrent].audio); break; - case OverviewFiles: onError(_songData[_songCurrent].song); break; - } + onError(data->audio); return false; } } @@ -400,12 +397,8 @@ bool AudioPlayer::updateCurrentStarted(MediaOverviewType type, int32 pos) { return true; } -bool AudioPlayer::fadedStop(MediaOverviewType type, bool *fadedStart) { - Msg *current = 0; - switch (type) { - case OverviewVoiceFiles: current = &_audioData[_audioCurrent]; break; - case OverviewFiles: current = &_songData[_songCurrent]; break; - } +bool AudioPlayer::fadedStop(AudioMsgId::Type type, bool *fadedStart) { + auto current = dataForType(type); if (!current) return false; switch (current->state) { @@ -429,14 +422,18 @@ bool AudioPlayer::fadedStop(MediaOverviewType type, bool *fadedStart) { } void AudioPlayer::play(const AudioMsgId &audio, int64 position) { + bool fadedStart = false; + auto type = audio.type(); AudioMsgId stopped; { QMutexLocker lock(&playerMutex); bool fadedStart = false; - AudioMsg *current = &_audioData[_audioCurrent]; + auto current = dataForType(type); + if (!current) return; + if (current->audio != audio) { - if (fadedStop(OverviewVoiceFiles, &fadedStart)) { + if (fadedStop(type, &fadedStart)) { stopped = current->audio; } if (current->audio) { @@ -444,110 +441,65 @@ void AudioPlayer::play(const AudioMsgId &audio, int64 position) { emit faderOnTimer(); } - int32 index = 0; - for (; index < AudioVoiceMsgSimultaneously; ++index) { - if (_audioData[index].audio == audio) { - _audioCurrent = index; + auto foundCurrent = currentIndex(type); + int index = 0; + for (; index < AudioSimultaneousLimit; ++index) { + if (dataForType(type, index)->audio == audio) { + *foundCurrent = index; break; } } - if (index == AudioVoiceMsgSimultaneously && ++_audioCurrent >= AudioVoiceMsgSimultaneously) { - _audioCurrent -= AudioVoiceMsgSimultaneously; + if (index == AudioSimultaneousLimit && ++*foundCurrent >= AudioSimultaneousLimit) { + *foundCurrent -= AudioSimultaneousLimit; } - current = &_audioData[_audioCurrent]; + current = dataForType(type); } current->audio = audio; - current->file = audio.audio->location(true); - current->data = audio.audio->data(); + current->file = audio.audio()->location(true); + current->data = audio.audio()->data(); if (current->file.isEmpty() && current->data.isEmpty()) { - setStoppedState(current, AudioPlayerStoppedAtError); - onError(audio); + if (audio.type() == AudioMsgId::Type::Song) { + setStoppedState(current); + if (!audio.audio()->loading()) { + DocumentOpenClickHandler::doOpen(audio.audio()); + } + } else { + setStoppedState(current, AudioPlayerStoppedAtError); + onError(audio); + } } else { current->state = fadedStart ? AudioPlayerStarting : AudioPlayerPlaying; current->loading = true; emit loaderOnStart(audio, position); - emit suppressSong(); + if (type == AudioMsgId::Type::Voice) { + emit suppressSong(); + } } } if (stopped) emit updated(stopped); } -void AudioPlayer::play(const SongMsgId &song, int64 position) { - SongMsgId stopped; - { - QMutexLocker lock(&playerMutex); - - bool fadedStart = false; - SongMsg *current = &_songData[_songCurrent]; - if (current->song != song) { - if (fadedStop(OverviewFiles, &fadedStart)) { - stopped = current->song; - } - if (current->song) { - emit loaderOnCancel(current->song); - emit faderOnTimer(); - } - - int32 index = 0; - for (; index < AudioSongSimultaneously; ++index) { - if (_songData[index].song == song) { - _songCurrent = index; - break; - } - } - if (index == AudioSongSimultaneously && ++_songCurrent >= AudioSongSimultaneously) { - _songCurrent -= AudioSongSimultaneously; - } - current = &_songData[_songCurrent]; - } - current->song = song; - current->file = song.song->location(true); - current->data = song.song->data(); - if (current->file.isEmpty() && current->data.isEmpty()) { - setStoppedState(current); - if (!song.song->loading()) { - DocumentOpenClickHandler::doOpen(song.song); - } - } else { - current->state = fadedStart ? AudioPlayerStarting : AudioPlayerPlaying; - current->loading = true; - emit loaderOnStart(song, position); - } - } - if (stopped) emit updated(stopped); -} - -bool AudioPlayer::checkCurrentALError(MediaOverviewType type) { +bool AudioPlayer::checkCurrentALError(AudioMsgId::Type type) { if (_checkALError()) return true; - switch (type) { - case OverviewVoiceFiles: - setStoppedState(&_audioData[_audioCurrent], AudioPlayerStoppedAtError); - onError(_audioData[_audioCurrent].audio); - break; - case OverviewFiles: - setStoppedState(&_songData[_songCurrent], AudioPlayerStoppedAtError); - onError(_songData[_songCurrent].song); - break; + auto data = dataForType(type); + if (!data) { + setStoppedState(data, AudioPlayerStoppedAtError); + onError(data->audio); } return false; } -void AudioPlayer::pauseresume(MediaOverviewType type, bool fast) { +void AudioPlayer::pauseresume(AudioMsgId::Type type, bool fast) { QMutexLocker lock(&playerMutex); - Msg *current = 0; + auto current = dataForType(type); float64 suppressGain = 1.; switch (type) { - case OverviewVoiceFiles: - current = &_audioData[_audioCurrent]; - suppressGain = suppressAllGain; - break; - case OverviewFiles: - current = &_songData[_songCurrent]; - suppressGain = suppressSongGain * cSongVolume(); - break; + case AudioMsgId::Type::Voice: suppressGain = suppressAllGain; break; + case AudioMsgId::Type::Song: suppressGain = suppressSongGain * cSongVolume(); break; } + switch (current->state) { case AudioPlayerPausing: case AudioPlayerPaused: @@ -575,14 +527,14 @@ void AudioPlayer::pauseresume(MediaOverviewType type, bool fast) { alSourcePlay(current->source); if (!checkCurrentALError(type)) return; } - if (type == OverviewVoiceFiles) emit suppressSong(); + if (type == AudioMsgId::Type::Voice) emit suppressSong(); } break; case AudioPlayerStarting: case AudioPlayerResuming: case AudioPlayerPlaying: current->state = AudioPlayerPausing; updateCurrentStarted(type); - if (type == OverviewVoiceFiles) emit unsuppressSong(); + if (type == AudioMsgId::Type::Voice) emit unsuppressSong(); break; case AudioPlayerFinishing: current->state = AudioPlayerPausing; break; } @@ -592,23 +544,14 @@ void AudioPlayer::pauseresume(MediaOverviewType type, bool fast) { void AudioPlayer::seek(int64 position) { QMutexLocker lock(&playerMutex); - MediaOverviewType type = OverviewFiles; - Msg *current = 0; + auto type = AudioMsgId::Type::Song; + auto current = dataForType(type); float64 suppressGain = 1.; - AudioMsgId audio; - SongMsgId song; switch (type) { - case OverviewVoiceFiles: - current = &_audioData[_audioCurrent]; - audio = _audioData[_audioCurrent].audio; - suppressGain = suppressAllGain; - break; - case OverviewFiles: - current = &_songData[_songCurrent]; - song = _songData[_songCurrent].song; - suppressGain = suppressSongGain * cSongVolume(); - break; + case AudioMsgId::Type::Voice: suppressGain = suppressAllGain; break; + case AudioMsgId::Type::Song: suppressGain = suppressSongGain * cSongVolume(); break; } + auto audio = current->audio; bool isSource = alIsSource(current->source); bool fastSeek = (position >= current->skipStart && position < current->duration - current->skipEnd - (current->skipEnd ? AudioVoiceMsgFrequency : 0)); @@ -637,7 +580,7 @@ void AudioPlayer::seek(int64 position) { case AudioPlayerPlaying: current->state = AudioPlayerPausing; updateCurrentStarted(type); - if (type == OverviewVoiceFiles) emit unsuppressSong(); + if (type == AudioMsgId::Type::Voice) emit unsuppressSong(); break; case AudioPlayerFinishing: case AudioPlayerStopped: @@ -645,113 +588,80 @@ void AudioPlayer::seek(int64 position) { case AudioPlayerStoppedAtError: case AudioPlayerStoppedAtStart: lock.unlock(); - switch (type) { - case OverviewVoiceFiles: if (audio) return play(audio, position); - case OverviewFiles: if (song) return play(song, position); - } + return play(audio, position); } emit faderOnTimer(); } -void AudioPlayer::stop(MediaOverviewType type) { - switch (type) { - case OverviewVoiceFiles: { - AudioMsgId current; - { - QMutexLocker lock(&playerMutex); - current = _audioData[_audioCurrent].audio; - fadedStop(type); - } - if (current) emit updated(current); - } break; - - case OverviewFiles: { - SongMsgId current; - { - QMutexLocker lock(&playerMutex); - current = _songData[_songCurrent].song; - fadedStop(type); - } - if (current) emit updated(current); - } break; +void AudioPlayer::stop(AudioMsgId::Type type) { + AudioMsgId current; + { + QMutexLocker lock(&playerMutex); + current = dataForType(type)->audio; + fadedStop(type); } + if (current) emit updated(current); } void AudioPlayer::stopAndClear() { - AudioMsg *current_audio = 0; + AudioMsg *current_audio = nullptr, *current_song = nullptr; { QMutexLocker lock(&playerMutex); - current_audio = &_audioData[_audioCurrent]; - if (current_audio) { + if ((current_audio = dataForType(AudioMsgId::Type::Voice))) { setStoppedState(current_audio); } - } - SongMsg *current_song = 0; - { - QMutexLocker lock(&playerMutex); - current_song = &_songData[_songCurrent]; - if (current_song) { + if ((current_song = dataForType(AudioMsgId::Type::Song))) { setStoppedState(current_song); } } if (current_song) { - emit updated(current_song->song); + emit updated(current_song->audio); } if (current_audio) { emit updated(current_audio->audio); } { QMutexLocker lock(&playerMutex); - for (int32 index = 0; index < AudioVoiceMsgSimultaneously; ++index) { - if (_audioData[index].audio) { - emit loaderOnCancel(_audioData[index].audio); + auto clearAndCancel = [this](AudioMsgId::Type type, int index) { + auto data = dataForType(type, index); + if (data->audio) { + emit loaderOnCancel(data->audio); } - _audioData[index].clear(); - if (_songData[index].song) { - emit loaderOnCancel(_songData[index].song); - } - _songData[index].clear(); + data->clear(); + }; + for (int index = 0; index < AudioSimultaneousLimit; ++index) { + clearAndCancel(AudioMsgId::Type::Voice, index); + clearAndCancel(AudioMsgId::Type::Song, index); } } } -void AudioPlayer::currentState(AudioMsgId *audio, AudioPlayerState *state, int64 *position, int64 *duration, int32 *frequency) { +void AudioPlayer::currentState(AudioMsgId *audio, AudioMsgId::Type type, AudioPlayerState *state, int64 *position, int64 *duration, int32 *frequency) { QMutexLocker lock(&playerMutex); - AudioMsg *current = &_audioData[_audioCurrent]; + auto current = dataForType(type); + if (!current) return; + if (audio) *audio = current->audio; return currentState(current, state, position, duration, frequency); } -void AudioPlayer::currentState(SongMsgId *song, AudioPlayerState *state, int64 *position, int64 *duration, int32 *frequency) { - QMutexLocker lock(&playerMutex); - SongMsg *current = &_songData[_songCurrent]; - if (song) *song = current->song; - return currentState(current, state, position, duration, frequency); -} - -void AudioPlayer::currentState(Msg *current, AudioPlayerState *state, int64 *position, int64 *duration, int32 *frequency) { +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(Msg *current, AudioPlayerState state) { +void AudioPlayer::setStoppedState(AudioMsg *current, AudioPlayerState state) { current->state = state; current->position = 0; } void AudioPlayer::clearStoppedAtStart(const AudioMsgId &audio) { QMutexLocker lock(&playerMutex); - if (_audioData[_audioCurrent].audio == audio && _audioData[_audioCurrent].state == AudioPlayerStoppedAtStart) { - setStoppedState(&_audioData[_audioCurrent]); - } -} - -void AudioPlayer::clearStoppedAtStart(const SongMsgId &song) { - QMutexLocker lock(&playerMutex); - if (_songData[_songCurrent].song == song && _songData[_songCurrent].state == AudioPlayerStoppedAtStart) { - setStoppedState(&_songData[_songCurrent]); + auto data = dataForType(audio.type()); + if (data && data->audio == audio && data->state == AudioPlayerStoppedAtStart) { + setStoppedState(data); } } @@ -860,29 +770,26 @@ void AudioPlayerFader::onTimer() { suppressSongGain = qMin(suppressAllGain, _suppressSongGain.current()); suppressSongChanged = (suppressSongGain != wasSong); } - bool hasFading = (_suppressAll || _suppressSongAnim), hasPlaying = false; + bool hasFading = (_suppressAll || _suppressSongAnim); + bool hasPlaying = false; - for (int32 i = 0; i < AudioVoiceMsgSimultaneously; ++i) { - AudioPlayer::AudioMsg &m(voice->_audioData[i]); - if ((m.state & AudioPlayerStoppedMask) || m.state == AudioPlayerPaused || !m.source) continue; + auto updatePlayback = [this, voice, &hasPlaying, &hasFading](AudioMsgId::Type type, int index, float64 suppressGain, bool suppressGainChanged) { + auto data = voice->dataForType(type, index); + if ((data->state & AudioPlayerStoppedMask) || data->state == AudioPlayerPaused || !data->source) return; - int32 emitSignals = updateOnePlayback(&m, hasPlaying, hasFading, suppressAllGain, suppressAudioChanged); - if (emitSignals & EmitError) emit error(m.audio); - if (emitSignals & EmitStopped) emit audioStopped(m.audio); - if (emitSignals & EmitPositionUpdated) emit playPositionUpdated(m.audio); - if (emitSignals & EmitNeedToPreload) emit needToPreload(m.audio); + int32 emitSignals = updateOnePlayback(data, hasPlaying, hasFading, suppressGain, suppressGainChanged); + if (emitSignals & EmitError) emit error(data->audio); + if (emitSignals & EmitStopped) emit audioStopped(data->audio); + if (emitSignals & EmitPositionUpdated) emit playPositionUpdated(data->audio); + if (emitSignals & EmitNeedToPreload) emit needToPreload(data->audio); + }; + auto suppressGainForMusic = suppressSongGain * cSongVolume(); + auto suppressGainForMusicChanged = suppressSongChanged || _songVolumeChanged; + for (int i = 0; i < AudioSimultaneousLimit; ++i) { + updatePlayback(AudioMsgId::Type::Voice, i, suppressAllGain, suppressAudioChanged); + updatePlayback(AudioMsgId::Type::Song, i, suppressGainForMusic, suppressGainForMusicChanged); } - for (int32 i = 0; i < AudioSongSimultaneously; ++i) { - AudioPlayer::SongMsg &m(voice->_songData[i]); - if ((m.state & AudioPlayerStoppedMask) || m.state == AudioPlayerPaused || !m.source) continue; - - int32 emitSignals = updateOnePlayback(&m, hasPlaying, hasFading, suppressSongGain * cSongVolume(), suppressSongChanged || _songVolumeChanged); - if (emitSignals & EmitError) emit error(m.song); - if (emitSignals & EmitStopped) emit audioStopped(m.song); - if (emitSignals & EmitPositionUpdated) emit playPositionUpdated(m.song); - if (emitSignals & EmitNeedToPreload) emit needToPreload(m.song); - } _songVolumeChanged = false; if (!hasFading) { @@ -907,7 +814,7 @@ void AudioPlayerFader::onTimer() { } } -int32 AudioPlayerFader::updateOnePlayback(AudioPlayer::Msg *m, bool &hasPlaying, bool &hasFading, float64 suppressGain, bool suppressGainChanged) { +int32 AudioPlayerFader::updateOnePlayback(AudioPlayer::AudioMsg *m, bool &hasPlaying, bool &hasFading, float64 suppressGain, bool suppressGainChanged) { bool playing = false, fading = false; ALint pos = 0; @@ -1006,7 +913,7 @@ int32 AudioPlayerFader::updateOnePlayback(AudioPlayer::Msg *m, bool &hasPlaying, return emitSignals; } -void AudioPlayerFader::setStoppedState(AudioPlayer::Msg *m, AudioPlayerState state) { +void AudioPlayerFader::setStoppedState(AudioPlayer::AudioMsg *m, AudioPlayerState state) { m->state = state; m->position = 0; } @@ -1478,53 +1385,38 @@ void AudioPlayerLoaders::onInit() { } void AudioPlayerLoaders::onStart(const AudioMsgId &audio, qint64 position) { - _audio = AudioMsgId(); - delete _audioLoader; - _audioLoader = 0; - + auto type = audio.type(); + clear(type); { QMutexLocker lock(&playerMutex); AudioPlayer *voice = audioPlayer(); if (!voice) return; - voice->_audioData[voice->_audioCurrent].loading = true; + auto data = voice->dataForType(type); + if (!data) return; + + data->loading = true; } - loadData(OverviewVoiceFiles, static_cast(&audio), position); + loadData(audio, position); } -void AudioPlayerLoaders::onStart(const SongMsgId &song, qint64 position) { - _song = SongMsgId(); - delete _songLoader; - _songLoader = 0; - - { - QMutexLocker lock(&playerMutex); - AudioPlayer *voice = audioPlayer(); - if (!voice) return; - - voice->_songData[voice->_songCurrent].loading = true; - } - - loadData(OverviewFiles, static_cast(&song), position); -} - -void AudioPlayerLoaders::clear(MediaOverviewType type) { +void AudioPlayerLoaders::clear(AudioMsgId::Type type) { switch (type) { - case OverviewVoiceFiles: clearAudio(); break; - case OverviewFiles: clearSong(); break; + case AudioMsgId::Type::Voice: clearAudio(); break; + case AudioMsgId::Type::Song: clearSong(); break; } } -void AudioPlayerLoaders::setStoppedState(AudioPlayer::Msg *m, AudioPlayerState state) { +void AudioPlayerLoaders::setStoppedState(AudioPlayer::AudioMsg *m, AudioPlayerState state) { m->state = state; m->position = 0; } -void AudioPlayerLoaders::emitError(MediaOverviewType type) { +void AudioPlayerLoaders::emitError(AudioMsgId::Type type) { switch (type) { - case OverviewVoiceFiles: emit error(clearAudio()); break; - case OverviewFiles: emit error(clearSong()); break; + case AudioMsgId::Type::Voice: emit error(clearAudio()); break; + case AudioMsgId::Type::Song: emit error(clearSong()); break; } } @@ -1532,29 +1424,26 @@ AudioMsgId AudioPlayerLoaders::clearAudio() { AudioMsgId current = _audio; _audio = AudioMsgId(); delete _audioLoader; - _audioLoader = 0; + _audioLoader = nullptr; return current; } -SongMsgId AudioPlayerLoaders::clearSong() { - SongMsgId current = _song; - _song = SongMsgId(); +AudioMsgId AudioPlayerLoaders::clearSong() { + AudioMsgId current = _song; + _song = AudioMsgId(); delete _songLoader; - _songLoader = 0; + _songLoader = nullptr; return current; } void AudioPlayerLoaders::onLoad(const AudioMsgId &audio) { - loadData(OverviewVoiceFiles, static_cast(&audio), 0); + loadData(audio, 0); } -void AudioPlayerLoaders::onLoad(const SongMsgId &song) { - loadData(OverviewFiles, static_cast(&song), 0); -} - -void AudioPlayerLoaders::loadData(MediaOverviewType type, const void *objId, qint64 position) { +void AudioPlayerLoaders::loadData(const AudioMsgId &audio, qint64 position) { SetupError err = SetupNoErrorStarted; - AudioPlayerLoader *l = setupLoader(type, objId, err, position); + auto type = audio.type(); + AudioPlayerLoader *l = setupLoader(audio, err, position); if (!l) { if (err == SetupErrorAtStart) { emitError(type); @@ -1572,7 +1461,7 @@ void AudioPlayerLoaders::loadData(MediaOverviewType type, const void *objId, qin if (errAtStart) { { QMutexLocker lock(&playerMutex); - AudioPlayer::Msg *m = checkLoader(type); + AudioPlayer::AudioMsg *m = checkLoader(type); if (m) m->state = AudioPlayerStoppedAtStart; } emitError(type); @@ -1591,7 +1480,7 @@ void AudioPlayerLoaders::loadData(MediaOverviewType type, const void *objId, qin } QMutexLocker lock(&playerMutex); - AudioPlayer::Msg *m = checkLoader(type); + AudioPlayer::AudioMsg *m = checkLoader(type); if (!m) { clear(type); return; @@ -1662,8 +1551,8 @@ void AudioPlayerLoaders::loadData(MediaOverviewType type, const void *objId, qin audioPlayer()->resumeDevice(); switch (type) { - case OverviewVoiceFiles: alSourcef(m->source, AL_GAIN, suppressAllGain); break; - case OverviewFiles: alSourcef(m->source, AL_GAIN, suppressSongGain * cSongVolume()); break; + case AudioMsgId::Type::Voice: alSourcef(m->source, AL_GAIN, suppressAllGain); break; + case AudioMsgId::Type::Song: alSourcef(m->source, AL_GAIN, suppressSongGain * cSongVolume()); break; } if (!_checkALError()) { setStoppedState(m, AudioPlayerStoppedAtError); @@ -1687,93 +1576,59 @@ void AudioPlayerLoaders::loadData(MediaOverviewType type, const void *objId, qin } } -AudioPlayerLoader *AudioPlayerLoaders::setupLoader(MediaOverviewType type, const void *objId, SetupError &err, qint64 position) { +AudioPlayerLoader *AudioPlayerLoaders::setupLoader(const AudioMsgId &audio, SetupError &err, qint64 position) { err = SetupErrorAtStart; QMutexLocker lock(&playerMutex); AudioPlayer *voice = audioPlayer(); if (!voice) return nullptr; - bool isGoodId = false; - AudioPlayer::Msg *m = 0; - AudioPlayerLoader **l = 0; - switch (type) { - case OverviewVoiceFiles: { - AudioPlayer::AudioMsg &msg(voice->_audioData[voice->_audioCurrent]); - const AudioMsgId &audio(*static_cast(objId)); - if (msg.audio != audio || !msg.loading) { - emit error(audio); - break; - } - m = &msg; - l = &_audioLoader; - isGoodId = (_audio == audio); - } break; - case OverviewFiles: { - AudioPlayer::SongMsg &msg(voice->_songData[voice->_songCurrent]); - const SongMsgId &song(*static_cast(objId)); - if (msg.song != song || !msg.loading) { - emit error(song); - break; - } - m = &msg; - l = &_songLoader; - isGoodId = (_song == song); - } break; - } - if (!l || !m) { + auto data = voice->dataForType(audio.type()); + if (!data || data->audio != audio || !data->loading) { + emit error(audio); LOG(("Audio Error: trying to load part of audio, that is not current at the moment")); err = SetupErrorNotPlaying; return nullptr; } - if (*l && (!isGoodId || !(*l)->check(m->file, m->data))) { + bool isGoodId = false; + AudioPlayerLoader **l = nullptr; + switch (audio.type()) { + case AudioMsgId::Type::Voice: l = &_audioLoader; isGoodId = (_audio == audio); break; + case AudioMsgId::Type::Song: l = &_songLoader; isGoodId = (_song == audio); break; + } + + if (*l && (!isGoodId || !(*l)->check(data->file, data->data))) { delete *l; - *l = 0; - switch (type) { - case OverviewVoiceFiles: _audio = AudioMsgId(); break; - case OverviewFiles: _song = SongMsgId(); break; + *l = nullptr; + switch (audio.type()) { + case AudioMsgId::Type::Voice: _audio = AudioMsgId(); break; + case AudioMsgId::Type::Song: _song = AudioMsgId(); break; } } if (!*l) { - switch (type) { - case OverviewVoiceFiles: _audio = *static_cast(objId); break; - case OverviewFiles: _song = *static_cast(objId); break; + switch (audio.type()) { + case AudioMsgId::Type::Voice: _audio = audio; break; + case AudioMsgId::Type::Song: _song = audio; break; } -// QByteArray header = m->data.mid(0, 8); -// if (header.isEmpty()) { -// QFile f(m->fname); -// if (!f.open(QIODevice::ReadOnly)) { -// LOG(("Audio Error: could not open file '%1'").arg(m->fname)); -// m->state = AudioPlayerStoppedAtStart; -// return nullptr; -// } -// header = f.read(8); -// } -// if (header.size() < 8) { -// LOG(("Audio Error: could not read header from file '%1', data size %2").arg(m->fname).arg(m->data.isEmpty() ? QFileInfo(m->fname).size() : m->data.size())); -// m->state = AudioPlayerStoppedAtStart; -// return nullptr; -// } - - *l = new FFMpegLoader(m->file, m->data); + *l = new FFMpegLoader(data->file, data->data); if (!(*l)->open(position)) { - m->state = AudioPlayerStoppedAtStart; + data->state = AudioPlayerStoppedAtStart; return nullptr; } int64 duration = (*l)->duration(); if (duration <= 0) { - m->state = AudioPlayerStoppedAtStart; + data->state = AudioPlayerStoppedAtStart; return nullptr; } - m->duration = duration; - m->frequency = (*l)->frequency(); - if (!m->frequency) m->frequency = AudioVoiceMsgFrequency; + data->duration = duration; + data->frequency = (*l)->frequency(); + if (!data->frequency) data->frequency = AudioVoiceMsgFrequency; err = SetupNoErrorStarted; } else { - if (!m->skipEnd) { + if (!data->skipEnd) { err = SetupErrorLoadedFull; LOG(("Audio Error: trying to load part of audio, that is already loaded to the end")); return nullptr; @@ -1782,71 +1637,41 @@ AudioPlayerLoader *AudioPlayerLoaders::setupLoader(MediaOverviewType type, const return *l; } -AudioPlayer::Msg *AudioPlayerLoaders::checkLoader(MediaOverviewType type) { +AudioPlayer::AudioMsg *AudioPlayerLoaders::checkLoader(AudioMsgId::Type type) { AudioPlayer *voice = audioPlayer(); if (!voice) return 0; + auto data = voice->dataForType(type); bool isGoodId = false; - AudioPlayer::Msg *m = 0; - AudioPlayerLoader **l = 0; + AudioPlayerLoader **l = nullptr; switch (type) { - case OverviewVoiceFiles: { - AudioPlayer::AudioMsg &msg(voice->_audioData[voice->_audioCurrent]); - isGoodId = (msg.audio == _audio); - l = &_audioLoader; - m = &msg; - } break; - case OverviewFiles: { - AudioPlayer::SongMsg &msg(voice->_songData[voice->_songCurrent]); - isGoodId = (msg.song == _song); - l = &_songLoader; - m = &msg; - } break; + case AudioMsgId::Type::Voice: l = &_audioLoader; isGoodId = (data->audio == _audio); break; + case AudioMsgId::Type::Song: l = &_songLoader; isGoodId = (data->audio == _song); break; } - if (!l || !m) return 0; + if (!l || !data) return nullptr; - if (!isGoodId || !m->loading || !(*l)->check(m->file, m->data)) { + if (!isGoodId || !data->loading || !(*l)->check(data->file, data->data)) { LOG(("Audio Error: playing changed while loading")); - return 0; + return nullptr; } - return m; + return data; } void AudioPlayerLoaders::onCancel(const AudioMsgId &audio) { - if (_audio == audio) { - _audio = AudioMsgId(); - delete _audioLoader; - _audioLoader = 0; + switch (audio.type()) { + case AudioMsgId::Type::Voice: if (_audio == audio) clear(audio.type()); break; + case AudioMsgId::Type::Song: if (_song == audio) clear(audio.type()); break; } QMutexLocker lock(&playerMutex); AudioPlayer *voice = audioPlayer(); if (!voice) return; - for (int32 i = 0; i < AudioVoiceMsgSimultaneously; ++i) { - AudioPlayer::AudioMsg &m(voice->_audioData[i]); - if (m.audio == audio) { - m.loading = false; - } - } -} - -void AudioPlayerLoaders::onCancel(const SongMsgId &song) { - if (_song == song) { - _song = SongMsgId(); - delete _songLoader; - _songLoader = 0; - } - - QMutexLocker lock(&playerMutex); - AudioPlayer *voice = audioPlayer(); - if (!voice) return; - - for (int32 i = 0; i < AudioSongSimultaneously; ++i) { - AudioPlayer::SongMsg &m(voice->_songData[i]); - if (m.song == song) { - m.loading = false; + for (int i = 0; i < AudioSimultaneousLimit; ++i) { + auto data = voice->dataForType(audio.type(), i); + if (data->audio == audio) { + data->loading = false; } } } diff --git a/Telegram/SourceFiles/audio.h b/Telegram/SourceFiles/audio.h index 17bbf8cf0..e0ff14e5a 100644 --- a/Telegram/SourceFiles/audio.h +++ b/Telegram/SourceFiles/audio.h @@ -54,18 +54,15 @@ public: AudioPlayer(); void play(const AudioMsgId &audio, int64 position = 0); - void play(const SongMsgId &song, int64 position = 0); - void pauseresume(MediaOverviewType type, bool fast = false); - void seek(int64 position); // type == OverviewFiles - void stop(MediaOverviewType type); + void pauseresume(AudioMsgId::Type type, bool fast = false); + void seek(int64 position); // type == AudioMsgId::Type::Song + void stop(AudioMsgId::Type type); void stopAndClear(); - void currentState(AudioMsgId *audio, AudioPlayerState *state = 0, int64 *position = 0, int64 *duration = 0, int32 *frequency = 0); - void currentState(SongMsgId *song, AudioPlayerState *state = 0, int64 *position = 0, int64 *duration = 0, int32 *frequency = 0); + void currentState(AudioMsgId *audio, AudioMsgId::Type type, AudioPlayerState *state = 0, int64 *position = 0, int64 *duration = 0, int32 *frequency = 0); void clearStoppedAtStart(const AudioMsgId &audio); - void clearStoppedAtStart(const SongMsgId &song); void resumeDevice(); @@ -74,27 +71,15 @@ public: public slots: void onError(const AudioMsgId &audio); - void onError(const SongMsgId &song); - void onStopped(const AudioMsgId &audio); - void onStopped(const SongMsgId &song); signals: void updated(const AudioMsgId &audio); - void updated(const SongMsgId &song); - void stopped(const AudioMsgId &audio); - void stopped(const SongMsgId &song); - void stoppedOnError(const AudioMsgId &audio); - void stoppedOnError(const SongMsgId &song); - void loaderOnStart(const AudioMsgId &audio, qint64 position); - void loaderOnStart(const SongMsgId &song, qint64 position); - void loaderOnCancel(const AudioMsgId &audio); - void loaderOnCancel(const SongMsgId &song); void faderOnTimer(); @@ -106,68 +91,45 @@ signals: private: - bool fadedStop(MediaOverviewType type, bool *fadedStart = 0); - bool updateCurrentStarted(MediaOverviewType type, int32 pos = -1); - bool checkCurrentALError(MediaOverviewType type); + bool fadedStop(AudioMsgId::Type type, bool *fadedStart = 0); + bool updateCurrentStarted(AudioMsgId::Type type, int32 pos = -1); + bool checkCurrentALError(AudioMsgId::Type type); - struct Msg { - Msg() : position(0) - , duration(0) - , frequency(AudioVoiceMsgFrequency) - , skipStart(0) - , skipEnd(0) - , loading(false) - , started(0) - , state(AudioPlayerStopped) - , source(0) - , nextBuffer(0) { - memset(buffers, 0, sizeof(buffers)); - memset(samplesCount, 0, sizeof(samplesCount)); - } + struct AudioMsg { + void clear(); - void clearData(); + AudioMsgId audio; FileLocation file; QByteArray data; - int64 position, duration; - int32 frequency; - int64 skipStart, skipEnd; - bool loading; - int64 started; - AudioPlayerState state; + int64 position = 0; + int64 duration = 0; + int32 frequency = AudioVoiceMsgFrequency; + int64 skipStart = 0; + int64 skipEnd = 0; + bool loading = false; + int64 started = 0; + AudioPlayerState state = AudioPlayerStopped; - uint32 source; - int32 nextBuffer; - uint32 buffers[3]; - int64 samplesCount[3]; - }; - struct AudioMsg : public Msg { - AudioMsg() { - } - void clear() { - audio = AudioMsgId(); - Msg::clearData(); - } - AudioMsgId audio; - }; - struct SongMsg : public Msg { - SongMsg() { - } - void clear() { - song = SongMsgId(); - Msg::clearData(); - } - SongMsgId song; + uint32 source = 0; + int32 nextBuffer = 0; + uint32 buffers[3] = { 0 }; + int64 samplesCount[3] = { 0 }; }; - void currentState(Msg *current, AudioPlayerState *state, int64 *position, int64 *duration, int32 *frequency); - void setStoppedState(Msg *current, AudioPlayerState state = AudioPlayerStopped); + void currentState(AudioMsg *current, AudioPlayerState *state, int64 *position, int64 *duration, int32 *frequency); + void setStoppedState(AudioMsg *current, AudioPlayerState state = AudioPlayerStopped); - int32 _audioCurrent; - AudioMsg _audioData[AudioVoiceMsgSimultaneously]; + AudioMsg *dataForType(AudioMsgId::Type type, int index = -1); // -1 uses currentIndex(type) + const AudioMsg *dataForType(AudioMsgId::Type type, int index = -1) const; + int *currentIndex(AudioMsgId::Type type); + const int *currentIndex(AudioMsgId::Type type) const; - int32 _songCurrent; - SongMsg _songData[AudioSongSimultaneously]; + int _audioCurrent; + AudioMsg _audioData[AudioSimultaneousLimit]; + + int _songCurrent; + AudioMsg _songData[AudioSimultaneousLimit]; QMutex _mutex; @@ -228,13 +190,9 @@ public: signals: void error(const AudioMsgId &audio); - void error(const SongMsgId &audio); void playPositionUpdated(const AudioMsgId &audio); - void playPositionUpdated(const SongMsgId &audio); void audioStopped(const AudioMsgId &audio); - void audioStopped(const SongMsgId &audio); void needToPreload(const AudioMsgId &audio); - void needToPreload(const SongMsgId &audio); void stopPauseDevice(); @@ -258,8 +216,8 @@ private: EmitPositionUpdated = 0x04, EmitNeedToPreload = 0x08, }; - int32 updateOnePlayback(AudioPlayer::Msg *m, bool &hasPlaying, bool &hasFading, float64 suppressGain, bool suppressGainChanged); - void setStoppedState(AudioPlayer::Msg *m, AudioPlayerState state = AudioPlayerStopped); + int32 updateOnePlayback(AudioPlayer::AudioMsg *m, bool &hasPlaying, bool &hasFading, float64 suppressGain, bool suppressGainChanged); + void setStoppedState(AudioPlayer::AudioMsg *m, AudioPlayerState state = AudioPlayerStopped); QTimer _timer, _pauseTimer; QMutex _pauseMutex; @@ -283,7 +241,6 @@ public: signals: void error(const AudioMsgId &audio); - void error(const SongMsgId &song); void needToCheck(); public slots: @@ -291,27 +248,22 @@ public slots: void onInit(); void onStart(const AudioMsgId &audio, qint64 position); - void onStart(const SongMsgId &audio, qint64 position); - void onLoad(const AudioMsgId &audio); - void onLoad(const SongMsgId &audio); - void onCancel(const AudioMsgId &audio); - void onCancel(const SongMsgId &audio); private: AudioMsgId _audio; AudioPlayerLoader *_audioLoader; - SongMsgId _song; + AudioMsgId _song; AudioPlayerLoader *_songLoader; - void emitError(MediaOverviewType type); - void clear(MediaOverviewType type); - void setStoppedState(AudioPlayer::Msg *m, AudioPlayerState state = AudioPlayerStopped); + void emitError(AudioMsgId::Type type); + void clear(AudioMsgId::Type type); + void setStoppedState(AudioPlayer::AudioMsg *m, AudioPlayerState state = AudioPlayerStopped); AudioMsgId clearAudio(); - SongMsgId clearSong(); + AudioMsgId clearSong(); enum SetupError { SetupErrorAtStart = 0, @@ -319,9 +271,9 @@ private: SetupErrorLoadedFull = 2, SetupNoErrorStarted = 3, }; - void loadData(MediaOverviewType type, const void *objId, qint64 position); - AudioPlayerLoader *setupLoader(MediaOverviewType type, const void *objId, SetupError &err, qint64 position); - AudioPlayer::Msg *checkLoader(MediaOverviewType type); + void loadData(const AudioMsgId &audio, qint64 position); + AudioPlayerLoader *setupLoader(const AudioMsgId &audio, SetupError &err, qint64 position); + AudioPlayer::AudioMsg *checkLoader(AudioMsgId::Type type); }; diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index 93119734f..c62b700b1 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -100,8 +100,7 @@ enum { // a new message from the same sender is attached to previous within 15 minutes AttachMessageToPreviousSecondsDelta = 900, - AudioVoiceMsgSimultaneously = 4, - AudioSongSimultaneously = 4, + AudioSimultaneousLimit = 4, AudioCheckPositionTimeout = 100, // 100ms per check audio pos AudioCheckPositionDelta = 2400, // update position called each 2400 samples AudioFadeTimeout = 7, // 7ms diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index ded75552a..1d0791bc0 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -4391,7 +4391,7 @@ bool HistoryDocument::updateStatusText() const { int64 playingPosition = 0, playingDuration = 0; int32 playingFrequency = 0; if (audioPlayer()) { - audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Voice, &playingState, &playingPosition, &playingDuration, &playingFrequency); } if (playing == AudioMsgId(_data, _parent->fullId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { @@ -4420,22 +4420,22 @@ bool HistoryDocument::updateStatusText() const { } } } else if (_data->song()) { - SongMsgId playing; + AudioMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; int64 playingPosition = 0, playingDuration = 0; int32 playingFrequency = 0; if (audioPlayer()) { - audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState, &playingPosition, &playingDuration, &playingFrequency); } - if (playing == SongMsgId(_data, _parent->fullId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { + 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 == SongMsgId(_data, _parent->fullId())) && App::main() && App::main()->player()->seekingSong(playing)) { + if (!showPause && (playing == AudioMsgId(_data, _parent->fullId())) && App::main() && App::main()->player()->seekingSong(playing)) { showPause = true; } } else { diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp index 5b9f7d89b..4f1285e90 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp @@ -859,7 +859,7 @@ bool File::updateStatusText() const { int64 playingPosition = 0, playingDuration = 0; int32 playingFrequency = 0; if (audioPlayer()) { - audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Voice, &playingState, &playingPosition, &playingDuration, &playingFrequency); } if (playing == AudioMsgId(document, FullMsgId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { @@ -870,22 +870,22 @@ bool File::updateStatusText() const { statusSize = FileStatusSizeLoaded; } } else if (document->song()) { - SongMsgId playing; + AudioMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; int64 playingPosition = 0, playingDuration = 0; int32 playingFrequency = 0; if (audioPlayer()) { - audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState, &playingPosition, &playingDuration, &playingFrequency); } - if (playing == SongMsgId(document, FullMsgId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { + if (playing == AudioMsgId(document, FullMsgId()) && !(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 == SongMsgId(document, FullMsgId())) && App::main() && App::main()->player()->seekingSong(playing)) { + if (!showPause && (playing == AudioMsgId(document, FullMsgId())) && App::main() && App::main()->player()->seekingSong(playing)) { showPause = true; } } else { diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index fab677930..45846a9be 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -92,8 +92,6 @@ MainWidget::MainWidget(MainWindow *window) : TWidget(window) if (audioPlayer()) { connect(audioPlayer(), SIGNAL(updated(const AudioMsgId&)), this, SLOT(audioPlayProgress(const AudioMsgId&))); connect(audioPlayer(), SIGNAL(stopped(const AudioMsgId&)), this, SLOT(audioPlayProgress(const AudioMsgId&))); - connect(audioPlayer(), SIGNAL(updated(const SongMsgId&)), this, SLOT(documentPlayProgress(const SongMsgId&))); - connect(audioPlayer(), SIGNAL(stopped(const SongMsgId&)), this, SLOT(documentPlayProgress(const SongMsgId&))); } connect(&_updateMutedTimer, SIGNAL(timeout()), this, SLOT(onUpdateMuted())); connect(&_viewsIncrementTimer, SIGNAL(timeout()), this, SLOT(onViewsIncrement())); @@ -1533,46 +1531,22 @@ void MainWidget::ui_autoplayMediaInlineAsync(qint32 channelId, qint32 msgId) { void MainWidget::audioPlayProgress(const AudioMsgId &audioId) { AudioMsgId playing; - AudioPlayerState state = AudioPlayerStopped; - audioPlayer()->currentState(&playing, &state); - if (playing == audioId && state == AudioPlayerStoppedAtStart) { + AudioPlayerState playingState = AudioPlayerStopped; + int64 playingPosition = 0, playingDuration = 0; + int32 playingFrequency = 0; + audioPlayer()->currentState(&playing, audioId.type(), &playingState, &playingPosition, &playingDuration, &playingFrequency); + if (playing == audioId && playingState == AudioPlayerStoppedAtStart) { + playingState = AudioPlayerStopped; audioPlayer()->clearStoppedAtStart(audioId); - DocumentData *audio = audioId.audio; + DocumentData *audio = audioId.audio(); QString filepath = audio->filepath(DocumentData::FilePathResolveSaveFromData); if (!filepath.isEmpty()) { psOpenFile(filepath); } } - if (HistoryItem *item = App::histItemById(audioId.contextId)) { - Ui::repaintHistoryItem(item); - } - if (auto items = InlineBots::Layout::documentItems()) { - for (auto item : items->value(audioId.audio)) { - Ui::repaintInlineItem(item); - } - } -} - -void MainWidget::documentPlayProgress(const SongMsgId &songId) { - SongMsgId playing; - AudioPlayerState playingState = AudioPlayerStopped; - int64 playingPosition = 0, playingDuration = 0; - int32 playingFrequency = 0; - audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); - if (playing == songId && playingState == AudioPlayerStoppedAtStart) { - playingState = AudioPlayerStopped; - audioPlayer()->clearStoppedAtStart(songId); - - DocumentData *document = songId.song; - QString filepath = document->filepath(DocumentData::FilePathResolveSaveFromData); - if (!filepath.isEmpty()) { - psOpenFile(filepath); - } - } - - if (playing == songId) { + if (playing == audioId && audioId.type() == AudioMsgId::Type::Song) { _player->updateState(playing, playingState, playingPosition, playingDuration, playingFrequency); if (!(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { @@ -1587,11 +1561,11 @@ void MainWidget::documentPlayProgress(const SongMsgId &songId) { } } - if (HistoryItem *item = App::histItemById(songId.contextId)) { + if (HistoryItem *item = App::histItemById(audioId.contextId())) { Ui::repaintHistoryItem(item); } if (auto items = InlineBots::Layout::documentItems()) { - for (auto item : items->value(songId.song)) { + for (auto item : items->value(audioId.audio())) { Ui::repaintInlineItem(item); } } @@ -1628,12 +1602,12 @@ void MainWidget::documentLoadProgress(FileLoader *loader) { App::wnd()->documentUpdated(document); if (!document->loaded() && document->loading() && document->song() && audioPlayer()) { - SongMsgId playing; + AudioMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; int64 playingPosition = 0, playingDuration = 0; int32 playingFrequency = 0; - audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); - if (playing.song == document && !_player->isHidden()) { + audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState, &playingPosition, &playingDuration, &playingFrequency); + if (playing.audio() == document && !_player->isHidden()) { _player->updateState(playing, playingState, playingPosition, playingDuration, playingFrequency); } } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index c6e937e42..63349cdc7 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -445,7 +445,6 @@ public slots: void documentLoadProgress(FileLoader *loader); void documentLoadFailed(FileLoader *loader, bool started); void documentLoadRetry(); - void documentPlayProgress(const SongMsgId &songId); void inlineResultLoadProgress(FileLoader *loader); void inlineResultLoadFailed(FileLoader *loader, bool started); diff --git a/Telegram/SourceFiles/overview/overview_layout.cpp b/Telegram/SourceFiles/overview/overview_layout.cpp index 59faa38b1..6c05b881f 100644 --- a/Telegram/SourceFiles/overview/overview_layout.cpp +++ b/Telegram/SourceFiles/overview/overview_layout.cpp @@ -561,7 +561,7 @@ bool Voice::updateStatusText() const { int64 playingPosition = 0, playingDuration = 0; int32 playingFrequency = 0; if (audioPlayer()) { - audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Voice, &playingState, &playingPosition, &playingDuration, &playingFrequency); } if (playing == AudioMsgId(_data, _parent->fullId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { @@ -865,22 +865,22 @@ bool Document::updateStatusText() const { statusSize = _data->loadOffset(); } else if (_data->loaded()) { if (_data->song()) { - SongMsgId playing; + AudioMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; int64 playingPosition = 0, playingDuration = 0; int32 playingFrequency = 0; if (audioPlayer()) { - audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState, &playingPosition, &playingDuration, &playingFrequency); } - if (playing == SongMsgId(_data, _parent->fullId()) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { + 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 == SongMsgId(_data, _parent->fullId())) && App::main() && App::main()->player()->seekingSong(playing)) { + if (!showPause && (playing == AudioMsgId(_data, _parent->fullId())) && App::main() && App::main()->player()->seekingSong(playing)) { showPause = true; } } else { diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index 6bda8abf7..19b80726a 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -2091,11 +2091,11 @@ int32 OverviewWidget::lastScrollTop() const { int32 OverviewWidget::countBestScroll() const { if (type() == OverviewMusicFiles && audioPlayer()) { - SongMsgId playing; + AudioMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; - audioPlayer()->currentState(&playing, &playingState); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState); if (playing) { - int32 top = _inner.itemTop(playing.contextId); + int32 top = _inner.itemTop(playing.contextId()); if (top >= 0) { return snap(top - int(_scroll.height() - (st::msgPadding.top() + st::mediaThumbSize + st::msgPadding.bottom())) / 2, 0, _scroll.scrollTopMax()); } diff --git a/Telegram/SourceFiles/playerwidget.cpp b/Telegram/SourceFiles/playerwidget.cpp index ca697b771..29f7941ce 100644 --- a/Telegram/SourceFiles/playerwidget.cpp +++ b/Telegram/SourceFiles/playerwidget.cpp @@ -168,14 +168,14 @@ void PlayerWidget::mousePressEvent(QMouseEvent *e) { emit audioPlayer()->songVolumeChanged(); rtlupdate(_volumeRect); } else if (_over == OverPlayback) { - SongMsgId playing; + AudioMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; int64 playingPosition = 0, playingDuration = 0; int32 playingFrequency = 0; - audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState, &playingPosition, &playingDuration, &playingFrequency); if (playing == _song && playingDuration) { if (playingState == AudioPlayerPlaying || playingState == AudioPlayerStarting || playingState == AudioPlayerResuming) { - audioPlayer()->pauseresume(OverviewFiles); + audioPlayer()->pauseresume(AudioMsgId::Type::Song); } _down = OverPlayback; _downProgress = snap((pos.x() - _playbackRect.x()) / float64(_playbackRect.width()), 0., 1.); @@ -186,7 +186,7 @@ void PlayerWidget::mousePressEvent(QMouseEvent *e) { updateDownTime(); } } else if (_over == OverFull && _song) { - if (HistoryItem *item = App::histItemById(_song.contextId)) { + if (HistoryItem *item = App::histItemById(_song.contextId())) { App::main()->showMediaOverview(item->history()->peer, OverviewMusicFiles); } } else if (_over == OverRepeat) { @@ -271,12 +271,12 @@ void PlayerWidget::updateControls() { void PlayerWidget::findCurrent() { _index = -1; - if (!_history || !_song.contextId.msg) return; + if (!_history || !_song.contextId().msg) return; const History::MediaOverview *o = &(_msgmigrated ? _migrated : _history)->overview[OverviewMusicFiles]; - if ((_msgmigrated ? _migrated : _history)->channelId() == _song.contextId.channel) { + if ((_msgmigrated ? _migrated : _history)->channelId() == _song.contextId().channel) { for (int i = 0, l = o->size(); i < l; ++i) { - if (o->at(i) == _song.contextId.msg) { + if (o->at(i) == _song.contextId().msg) { _index = i; break; } @@ -311,7 +311,7 @@ void PlayerWidget::preloadNext() { void PlayerWidget::startPlay(const FullMsgId &msgId) { if (HistoryItem *item = App::histItemById(msgId)) { if (HistoryDocument *doc = static_cast(item->getMedia())) { - audioPlayer()->play(SongMsgId(doc->getDocument(), item->fullId())); + audioPlayer()->play(AudioMsgId(doc->getDocument(), item->fullId())); updateState(); } } @@ -328,9 +328,9 @@ void PlayerWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) if (_history && (_history->peer == peer || (_migrated && _migrated->peer == peer)) && type == OverviewMusicFiles) { _index = -1; History *history = _msgmigrated ? _migrated : _history; - if (history->channelId() == _song.contextId.channel && _song.contextId.msg) { + if (history->channelId() == _song.contextId().channel && _song.contextId().msg) { for (int i = 0, l = history->overview[OverviewMusicFiles].size(); i < l; ++i) { - if (history->overview[OverviewMusicFiles].at(i) == _song.contextId.msg) { + if (history->overview[OverviewMusicFiles].at(i) == _song.contextId().msg) { _index = i; preloadNext(); break; @@ -341,7 +341,7 @@ void PlayerWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) } } -bool PlayerWidget::seekingSong(const SongMsgId &song) const { +bool PlayerWidget::seekingSong(const AudioMsgId &song) const { return (_down == OverPlayback) && (song == _song); } @@ -443,11 +443,11 @@ void PlayerWidget::mouseReleaseEvent(QMouseEvent *e) { Local::writeUserSettings(); } else if (_down == OverPlayback) { mouseMoveEvent(e); - SongMsgId playing; + AudioMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; int64 playingPosition = 0, playingDuration = 0; int32 playingFrequency = 0; - audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState, &playingPosition, &playingDuration, &playingFrequency); if (playing == _song && playingDuration) { _downDuration = playingDuration; audioPlayer()->seek(qRound(_downProgress * _downDuration)); @@ -467,28 +467,28 @@ void PlayerWidget::mouseReleaseEvent(QMouseEvent *e) { void PlayerWidget::playPressed() { if (!_song || isHidden()) return; - SongMsgId playing; + AudioMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; - audioPlayer()->currentState(&playing, &playingState); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState); if (playing == _song && !(playingState & AudioPlayerStoppedMask)) { if (playingState == AudioPlayerPausing || playingState == AudioPlayerPaused || playingState == AudioPlayerPausedAtEnd) { - audioPlayer()->pauseresume(OverviewFiles); + audioPlayer()->pauseresume(AudioMsgId::Type::Song); } } else { audioPlayer()->play(_song); - if (App::main()) App::main()->documentPlayProgress(_song); + if (App::main()) App::main()->audioPlayProgress(_song); } } void PlayerWidget::pausePressed() { if (!_song || isHidden()) return; - SongMsgId playing; + AudioMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; - audioPlayer()->currentState(&playing, &playingState); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState); if (playing == _song && !(playingState & AudioPlayerStoppedMask)) { if (playingState == AudioPlayerStarting || playingState == AudioPlayerResuming || playingState == AudioPlayerPlaying || playingState == AudioPlayerFinishing) { - audioPlayer()->pauseresume(OverviewFiles); + audioPlayer()->pauseresume(AudioMsgId::Type::Song); } } } @@ -496,14 +496,14 @@ void PlayerWidget::pausePressed() { void PlayerWidget::playPausePressed() { if (!_song || isHidden()) return; - SongMsgId playing; + AudioMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; - audioPlayer()->currentState(&playing, &playingState); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState); if (playing == _song && !(playingState & AudioPlayerStoppedMask)) { - audioPlayer()->pauseresume(OverviewFiles); + audioPlayer()->pauseresume(AudioMsgId::Type::Song); } else { audioPlayer()->play(_song); - if (App::main()) App::main()->documentPlayProgress(_song); + if (App::main()) App::main()->audioPlayProgress(_song); } } @@ -540,7 +540,7 @@ void PlayerWidget::nextPressed() { void PlayerWidget::stopPressed() { if (!_song || isHidden()) return; - audioPlayer()->stop(OverviewFiles); + audioPlayer()->stop(AudioMsgId::Type::Song); } void PlayerWidget::closePressed() { @@ -581,19 +581,19 @@ void PlayerWidget::step_progress(float64 ms, bool timer) { } void PlayerWidget::updateState() { - updateState(SongMsgId(), AudioPlayerStopped, 0, 0, 0); + updateState(AudioMsgId(), AudioPlayerStopped, 0, 0, 0); } -void PlayerWidget::updateState(SongMsgId playing, AudioPlayerState playingState, int64 playingPosition, int64 playingDuration, int32 playingFrequency) { +void PlayerWidget::updateState(AudioMsgId playing, AudioPlayerState playingState, int64 playingPosition, int64 playingDuration, int32 playingFrequency) { if (!playing) { - audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState, &playingPosition, &playingDuration, &playingFrequency); } bool songChanged = false; if (playing && _song != playing) { songChanged = true; _song = playing; - if (HistoryItem *item = App::histItemById(_song.contextId)) { + if (HistoryItem *item = App::histItemById(_song.contextId())) { _history = item->history(); if (_history->peer->migrateFrom()) { _migrated = App::history(_history->peer->migrateFrom()->id); @@ -609,9 +609,9 @@ void PlayerWidget::updateState(SongMsgId playing, AudioPlayerState playingState, _msgmigrated = false; _index = -1; } - SongData *song = _song.song->song(); + auto song = _song.audio()->song(); if (song->performer.isEmpty()) { - _name.setText(st::linkFont, song->title.isEmpty() ? (_song.song->name.isEmpty() ? qsl("Unknown Track") : _song.song->name) : song->title, _textNameOptions); + _name.setText(st::linkFont, song->title.isEmpty() ? (_song.audio()->name.isEmpty() ? qsl("Unknown Track") : _song.audio()->name) : song->title, _textNameOptions); } else { TextCustomTagsMap custom; custom.insert(QChar('c'), qMakePair(textcmdStartLink(1), textcmdStopLink())); @@ -630,7 +630,7 @@ void PlayerWidget::updateState(SongMsgId playing, AudioPlayerState playingState, } display = display / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency); } else if (_song) { - display = _song.song->song()->duration; + display = _song.audio()->song()->duration; } bool showPause = false, stopped = ((playingState & AudioPlayerStoppedMask) || playingState == AudioPlayerFinishing); bool wasPlaying = (_duration != 0); @@ -641,14 +641,14 @@ void PlayerWidget::updateState(SongMsgId playing, AudioPlayerState playingState, float64 progress = 0.; int32 loaded; float64 loadProgress = 1.; - if (duration || !_song || !_song.song || !_song.song->loading()) { + if (duration || !_song || !_song.audio() || !_song.audio()->loading()) { time = (_down == OverPlayback) ? _time : formatDurationText(display); progress = duration ? snap(float64(position) / duration, 0., 1.) : 0.; - loaded = duration ? _song.song->size : 0; + loaded = duration ? _song.audio()->size : 0; } else { - loaded = _song.song->loading() ? _song.song->loadOffset() : 0; - time = formatDownloadText(loaded, _song.song->size); - loadProgress = snap(float64(loaded) / qMax(_song.song->size, 1), 0., 1.); + loaded = _song.audio()->loading() ? _song.audio()->loadOffset() : 0; + time = formatDownloadText(loaded, _song.audio()->size); + loadProgress = snap(float64(loaded) / qMax(_song.audio()->size, 1), 0., 1.); } if (time != _time || showPause != _showPause) { if (_time != time) { @@ -688,8 +688,8 @@ void PlayerWidget::updateState(SongMsgId playing, AudioPlayerState playingState, if (wasPlaying && playingState == AudioPlayerStoppedAtEnd) { if (_repeat) { - if (_song.song) { - audioPlayer()->play(_song); + if (_song.audio()) { + audioPlayer()->play(_song, OverviewMusicFiles); updateState(); } } else { @@ -698,6 +698,6 @@ void PlayerWidget::updateState(SongMsgId playing, AudioPlayerState playingState, } if (songChanged) { - emit playerSongChanged(_song.contextId); + emit playerSongChanged(_song.contextId()); } } diff --git a/Telegram/SourceFiles/playerwidget.h b/Telegram/SourceFiles/playerwidget.h index 4eda5b0d7..72aa9ba98 100644 --- a/Telegram/SourceFiles/playerwidget.h +++ b/Telegram/SourceFiles/playerwidget.h @@ -47,13 +47,13 @@ public: void step_progress(float64 ms, bool timer); void step_state(uint64 ms, bool timer); - void updateState(SongMsgId playing, AudioPlayerState playingState, int64 playingPosition, int64 playingDuration, int32 playingFrequency); + void updateState(AudioMsgId playing, AudioPlayerState playingState, int64 playingPosition, int64 playingDuration, int32 playingFrequency); void updateState(); void clearSelection(); void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type); - bool seekingSong(const SongMsgId &song) const; + bool seekingSong(const AudioMsgId &song) const; void openPlayer(); bool isOpened() const; @@ -115,7 +115,7 @@ private: StateAnimations _stateAnimations; Animation _a_state; - SongMsgId _song; + AudioMsgId _song; bool _msgmigrated = false; int32 _index = -1; History *_migrated = nullptr; diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index b5c7eb34f..6736da8ff 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -954,9 +954,9 @@ void DocumentOpenClickHandler::doOpen(DocumentData *data, ActionOnLoad action) { if (playVoice) { AudioMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; - audioPlayer()->currentState(&playing, &playingState); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Voice, &playingState); if (playing == AudioMsgId(data, msgId) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { - audioPlayer()->pauseresume(OverviewVoiceFiles); + audioPlayer()->pauseresume(AudioMsgId::Type::Voice); } else { AudioMsgId audio(data, msgId); audioPlayer()->play(audio); @@ -966,15 +966,15 @@ void DocumentOpenClickHandler::doOpen(DocumentData *data, ActionOnLoad action) { } } } else if (playMusic) { - SongMsgId playing; + AudioMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; - audioPlayer()->currentState(&playing, &playingState); - if (playing == SongMsgId(data, msgId) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { - audioPlayer()->pauseresume(OverviewFiles); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState); + if (playing == AudioMsgId(data, msgId) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { + audioPlayer()->pauseresume(AudioMsgId::Type::Song); } else { - SongMsgId song(data, msgId); + AudioMsgId song(data, msgId); audioPlayer()->play(song); - if (App::main()) App::main()->documentPlayProgress(song); + if (App::main()) App::main()->audioPlayProgress(song); } } else if (playVideo) { if (!data->data().isEmpty()) { @@ -1243,9 +1243,9 @@ void DocumentData::performActionOnLoad() { if (loaded()) { AudioMsgId playing; AudioPlayerState state = AudioPlayerStopped; - audioPlayer()->currentState(&playing, &state); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Voice, &state); if (playing == AudioMsgId(this, _actionOnLoadMsgId) && !(state & AudioPlayerStoppedMask) && state != AudioPlayerFinishing) { - audioPlayer()->pauseresume(OverviewVoiceFiles); + audioPlayer()->pauseresume(AudioMsgId::Type::Voice); } else { audioPlayer()->play(AudioMsgId(this, _actionOnLoadMsgId)); if (App::main()) App::main()->mediaMarkRead(this); @@ -1253,15 +1253,15 @@ void DocumentData::performActionOnLoad() { } } else if (playMusic) { if (loaded()) { - SongMsgId playing; + AudioMsgId playing; AudioPlayerState playingState = AudioPlayerStopped; - audioPlayer()->currentState(&playing, &playingState); - if (playing == SongMsgId(this, _actionOnLoadMsgId) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { - audioPlayer()->pauseresume(OverviewFiles); + audioPlayer()->currentState(&playing, AudioMsgId::Type::Song, &playingState); + if (playing == AudioMsgId(this, _actionOnLoadMsgId) && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { + audioPlayer()->pauseresume(AudioMsgId::Type::Song); } else { - SongMsgId song(this, _actionOnLoadMsgId); + AudioMsgId song(this, _actionOnLoadMsgId); audioPlayer()->play(song); - if (App::main()) App::main()->documentPlayProgress(song); + if (App::main()) App::main()->audioPlayProgress(song); } } } else if (playAnimation) { diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 1a948de46..379fd0c18 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -1229,51 +1229,62 @@ private: VoiceWaveform documentWaveformDecode(const QByteArray &encoded5bit); QByteArray documentWaveformEncode5bit(const VoiceWaveform &waveform); -struct SongMsgId { - SongMsgId() : song(nullptr) { - } - SongMsgId(DocumentData *song, const FullMsgId &msgId) : song(song), contextId(msgId) { - } - SongMsgId(DocumentData *song, ChannelId channelId, MsgId msgId) : song(song), contextId(channelId, msgId) { - } - explicit operator bool() const { - return song; - } - DocumentData *song; - FullMsgId contextId; +class AudioMsgId { +public: + enum class Type { + Unknown, + Voice, + Song, + Video, + }; -}; -inline bool operator<(const SongMsgId &a, const SongMsgId &b) { - return quintptr(a.song) < quintptr(b.song) || (quintptr(a.song) == quintptr(b.song) && a.contextId < b.contextId); -} -inline bool operator==(const SongMsgId &a, const SongMsgId &b) { - return a.song == b.song && a.contextId == b.contextId; -} -inline bool operator!=(const SongMsgId &a, const SongMsgId &b) { - return !(a == b); -} + AudioMsgId() { + } + AudioMsgId(DocumentData *audio, const FullMsgId &msgId) : _audio(audio), _contextId(msgId) { + setType(); + } + AudioMsgId(DocumentData *audio, ChannelId channelId, MsgId msgId) : _audio(audio), _contextId(channelId, msgId) { + setType(); + } -struct AudioMsgId { - AudioMsgId() : audio(nullptr) { + Type type() const { + return _type; } - AudioMsgId(DocumentData *audio, const FullMsgId &msgId) : audio(audio), contextId(msgId) { + DocumentData *audio() const { + return _audio; } - AudioMsgId(DocumentData *audio, ChannelId channelId, MsgId msgId) : audio(audio), contextId(channelId, msgId) { + FullMsgId contextId() const { + return _contextId; } explicit operator bool() const { - return audio; + return _audio; } - DocumentData *audio; - FullMsgId contextId; + +private: + void setType() { + if (_audio->voice()) { + _type = Type::Voice; + } else if (_audio->song()) { + _type = Type::Song; + } else if (_audio->isVideo()) { + _type = Type::Video; + } else { + _type = Type::Unknown; + } + } + + DocumentData *_audio = nullptr; + Type _type = Type::Unknown; + FullMsgId _contextId; }; inline bool operator<(const AudioMsgId &a, const AudioMsgId &b) { - return quintptr(a.audio) < quintptr(b.audio) || (quintptr(a.audio) == quintptr(b.audio) && a.contextId < b.contextId); + return quintptr(a.audio()) < quintptr(b.audio()) || (quintptr(a.audio()) == quintptr(b.audio()) && a.contextId() < b.contextId()); } inline bool operator==(const AudioMsgId &a, const AudioMsgId &b) { - return a.audio == b.audio && a.contextId == b.contextId; + return a.audio() == b.audio() && a.contextId() == b.contextId(); } inline bool operator!=(const AudioMsgId &a, const AudioMsgId &b) { return !(a == b);