mirror of https://github.com/procxx/kepka.git
Implement double playback speed
This adds double playback speed for both voice messages and round video messages. The 2x playback speed setting is global and is saved in local storage. Fixes #4907
This commit is contained in:
parent
8ef67c393b
commit
de8518a112
Binary file not shown.
After Width: | Height: | Size: 479 B |
Binary file not shown.
After Width: | Height: | Size: 1015 B |
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
|
@ -649,6 +649,7 @@ struct Data {
|
||||||
bool SuggestEmoji = true;
|
bool SuggestEmoji = true;
|
||||||
bool SuggestStickersByEmoji = true;
|
bool SuggestStickersByEmoji = true;
|
||||||
base::Observable<void> ReplaceEmojiChanged;
|
base::Observable<void> ReplaceEmojiChanged;
|
||||||
|
float VoiceMsgPlaybackSpeed = 1.f;
|
||||||
bool SoundNotify = true;
|
bool SoundNotify = true;
|
||||||
bool DesktopNotify = true;
|
bool DesktopNotify = true;
|
||||||
bool RestoreSoundNotifyFromTray = false;
|
bool RestoreSoundNotifyFromTray = false;
|
||||||
|
@ -778,6 +779,7 @@ DefineVar(Global, bool, ReplaceEmoji);
|
||||||
DefineVar(Global, bool, SuggestEmoji);
|
DefineVar(Global, bool, SuggestEmoji);
|
||||||
DefineVar(Global, bool, SuggestStickersByEmoji);
|
DefineVar(Global, bool, SuggestStickersByEmoji);
|
||||||
DefineRefVar(Global, base::Observable<void>, ReplaceEmojiChanged);
|
DefineRefVar(Global, base::Observable<void>, ReplaceEmojiChanged);
|
||||||
|
DefineVar(Global, float, VoiceMsgPlaybackSpeed);
|
||||||
DefineVar(Global, bool, SoundNotify);
|
DefineVar(Global, bool, SoundNotify);
|
||||||
DefineVar(Global, bool, DesktopNotify);
|
DefineVar(Global, bool, DesktopNotify);
|
||||||
DefineVar(Global, bool, RestoreSoundNotifyFromTray);
|
DefineVar(Global, bool, RestoreSoundNotifyFromTray);
|
||||||
|
|
|
@ -304,6 +304,7 @@ DeclareVar(bool, ReplaceEmoji);
|
||||||
DeclareVar(bool, SuggestEmoji);
|
DeclareVar(bool, SuggestEmoji);
|
||||||
DeclareVar(bool, SuggestStickersByEmoji);
|
DeclareVar(bool, SuggestStickersByEmoji);
|
||||||
DeclareRefVar(base::Observable<void>, ReplaceEmojiChanged);
|
DeclareRefVar(base::Observable<void>, ReplaceEmojiChanged);
|
||||||
|
DeclareVar(float, VoiceMsgPlaybackSpeed);
|
||||||
DeclareVar(bool, SoundNotify);
|
DeclareVar(bool, SoundNotify);
|
||||||
DeclareVar(bool, DesktopNotify);
|
DeclareVar(bool, DesktopNotify);
|
||||||
DeclareVar(bool, RestoreSoundNotifyFromTray);
|
DeclareVar(bool, RestoreSoundNotifyFromTray);
|
||||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "media/media_audio_track.h"
|
#include "media/media_audio_track.h"
|
||||||
#include "platform/platform_audio.h"
|
#include "platform/platform_audio.h"
|
||||||
#include "messenger.h"
|
#include "messenger.h"
|
||||||
|
#include "facades.h"
|
||||||
|
|
||||||
#include <AL/al.h>
|
#include <AL/al.h>
|
||||||
#include <AL/alc.h>
|
#include <AL/alc.h>
|
||||||
|
@ -44,6 +45,13 @@ namespace {
|
||||||
|
|
||||||
Player::Mixer *MixerInstance = nullptr;
|
Player::Mixer *MixerInstance = nullptr;
|
||||||
|
|
||||||
|
struct PlaybackSpeedData {
|
||||||
|
ALuint uiEffectSlot = 0;
|
||||||
|
ALuint uiEffect = 0;
|
||||||
|
ALuint uiFilter = 0;
|
||||||
|
};
|
||||||
|
PlaybackSpeedData _playbackSpeedData;
|
||||||
|
|
||||||
// Thread: Any.
|
// Thread: Any.
|
||||||
bool ContextErrorHappened() {
|
bool ContextErrorHappened() {
|
||||||
ALenum errCode;
|
ALenum errCode;
|
||||||
|
@ -144,6 +152,24 @@ bool CreatePlaybackDevice() {
|
||||||
alListener3f(AL_VELOCITY, 0.f, 0.f, 0.f);
|
alListener3f(AL_VELOCITY, 0.f, 0.f, 0.f);
|
||||||
alListenerfv(AL_ORIENTATION, v);
|
alListenerfv(AL_ORIENTATION, v);
|
||||||
|
|
||||||
|
// playback speed related init
|
||||||
|
// generate an effect slot and an effect
|
||||||
|
alGenAuxiliaryEffectSlots(1, &_playbackSpeedData.uiEffectSlot);
|
||||||
|
alGenEffects(1, &_playbackSpeedData.uiEffect);
|
||||||
|
// initialize the pitch shifter effect
|
||||||
|
alEffecti(_playbackSpeedData.uiEffect, AL_EFFECT_TYPE, AL_EFFECT_PITCH_SHIFTER);
|
||||||
|
// 12 semitones = 1 octave
|
||||||
|
alEffecti(_playbackSpeedData.uiEffect, AL_PITCH_SHIFTER_COARSE_TUNE, -12);
|
||||||
|
// connect the effect with the effect slot
|
||||||
|
alAuxiliaryEffectSloti(_playbackSpeedData.uiEffectSlot, AL_EFFECTSLOT_EFFECT, _playbackSpeedData.uiEffect);
|
||||||
|
// initialize a filter to disable the direct (dry) path
|
||||||
|
alGenFilters(1, &_playbackSpeedData.uiFilter);
|
||||||
|
alFilteri(_playbackSpeedData.uiFilter, AL_FILTER_TYPE, AL_FILTER_LOWPASS);
|
||||||
|
// disable all frequencies
|
||||||
|
alFilterf(_playbackSpeedData.uiFilter, AL_LOWPASS_GAIN, 0.f);
|
||||||
|
// to use the modified playback speed:
|
||||||
|
// connect both the effect slot and filter with the stream source and set AL_PITCH
|
||||||
|
|
||||||
alDistanceModel(AL_NONE);
|
alDistanceModel(AL_NONE);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -154,6 +180,15 @@ void ClosePlaybackDevice() {
|
||||||
if (!AudioDevice) return;
|
if (!AudioDevice) return;
|
||||||
|
|
||||||
LOG(("Audio Info: Closing audio playback device."));
|
LOG(("Audio Info: Closing audio playback device."));
|
||||||
|
|
||||||
|
// playback speed related
|
||||||
|
alDeleteFilters(1, &_playbackSpeedData.uiFilter);
|
||||||
|
alDeleteEffects(1, &_playbackSpeedData.uiEffect);
|
||||||
|
alDeleteAuxiliaryEffectSlots(1, &_playbackSpeedData.uiEffectSlot);
|
||||||
|
_playbackSpeedData.uiFilter = 0;
|
||||||
|
_playbackSpeedData.uiEffect = 0;
|
||||||
|
_playbackSpeedData.uiEffectSlot = 0;
|
||||||
|
|
||||||
if (Player::mixer()) {
|
if (Player::mixer()) {
|
||||||
Player::mixer()->detachTracks();
|
Player::mixer()->detachTracks();
|
||||||
}
|
}
|
||||||
|
@ -290,6 +325,7 @@ void Mixer::Track::createStream() {
|
||||||
alSource3f(stream.source, AL_VELOCITY, 0, 0, 0);
|
alSource3f(stream.source, AL_VELOCITY, 0, 0, 0);
|
||||||
alSourcei(stream.source, AL_LOOPING, 0);
|
alSourcei(stream.source, AL_LOOPING, 0);
|
||||||
alGenBuffers(3, stream.buffers);
|
alGenBuffers(3, stream.buffers);
|
||||||
|
mixer()->updatePlaybackSpeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mixer::Track::destroyStream() {
|
void Mixer::Track::destroyStream() {
|
||||||
|
@ -983,6 +1019,29 @@ void Mixer::stop(const AudioMsgId &audio, State state) {
|
||||||
if (current) emit updated(current);
|
if (current) emit updated(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mixer::updatePlaybackSpeed()
|
||||||
|
{
|
||||||
|
const auto track = trackForType(AudioMsgId::Type::Voice);
|
||||||
|
if (!track || track->state.id.type() != AudioMsgId::Type::Voice || !track->isStreamCreated()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto src = track->stream.source;
|
||||||
|
// Note: This alters the playback speed AND the pitch
|
||||||
|
alSourcef(src, AL_PITCH, Global::VoiceMsgPlaybackSpeed());
|
||||||
|
// fix the pitch using effects and filters
|
||||||
|
if (Global::VoiceMsgPlaybackSpeed() > 1.f) {
|
||||||
|
// connect the effect slot with the stream
|
||||||
|
alSource3i(src, AL_AUXILIARY_SEND_FILTER, Media::Audio::_playbackSpeedData.uiEffectSlot, 0, 0);
|
||||||
|
// connect the filter with the stream
|
||||||
|
alSourcei(src, AL_DIRECT_FILTER, Media::Audio::_playbackSpeedData.uiFilter);
|
||||||
|
} else {
|
||||||
|
// disconnect the effect slot
|
||||||
|
alSource3i(src, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, 0);
|
||||||
|
// disconnect the filter
|
||||||
|
alSourcei(src, AL_DIRECT_FILTER, AL_FILTER_NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Mixer::stopAndClear() {
|
void Mixer::stopAndClear() {
|
||||||
Track *current_audio = nullptr, *current_song = nullptr;
|
Track *current_audio = nullptr, *current_song = nullptr;
|
||||||
{
|
{
|
||||||
|
|
|
@ -117,6 +117,8 @@ public:
|
||||||
void stop(const AudioMsgId &audio);
|
void stop(const AudioMsgId &audio);
|
||||||
void stop(const AudioMsgId &audio, State state);
|
void stop(const AudioMsgId &audio, State state);
|
||||||
|
|
||||||
|
void updatePlaybackSpeed();
|
||||||
|
|
||||||
// Video player audio stream interface.
|
// Video player audio stream interface.
|
||||||
void feedFromVideo(VideoSoundPart &&part);
|
void feedFromVideo(VideoSoundPart &&part);
|
||||||
int64 getVideoCorrectedTime(const AudioMsgId &id, TimeMs frameMs, TimeMs systemMs);
|
int64 getVideoCorrectedTime(const AudioMsgId &id, TimeMs frameMs, TimeMs systemMs);
|
||||||
|
|
|
@ -72,6 +72,32 @@ mediaPlayerRepeatInactiveIcon: icon {
|
||||||
{ "player_repeat", mediaPlayerInactiveFg, point(9px, 11px)}
|
{ "player_repeat", mediaPlayerInactiveFg, point(9px, 11px)}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mediaPlayerSpeedButton: IconButton {
|
||||||
|
width: 31px;
|
||||||
|
height: 30px;
|
||||||
|
|
||||||
|
icon: icon {
|
||||||
|
{ "voice2x", mediaPlayerActiveFg, point(8px, 11px) }
|
||||||
|
};
|
||||||
|
iconPosition: point(0px, 0px);
|
||||||
|
|
||||||
|
rippleAreaPosition: point(3px, 5px);
|
||||||
|
rippleAreaSize: 25px;
|
||||||
|
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||||
|
color: lightButtonBgOver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mediaPlayerSpeedDisabledIcon: icon {
|
||||||
|
{ "voice2x", menuIconFg, point(8px, 11px)}
|
||||||
|
};
|
||||||
|
mediaPlayerSpeedDisabledIconOver: icon {
|
||||||
|
{ "voice2x", menuIconFgOver, point(8px, 11px)}
|
||||||
|
};
|
||||||
|
mediaPlayerSpeedDisabledRippleBg: windowBgOver;
|
||||||
|
mediaPlayerSpeedInactiveIcon: icon {
|
||||||
|
{ "voice2x", mediaPlayerInactiveFg, point(8px, 11px)}
|
||||||
|
};
|
||||||
|
|
||||||
mediaPlayerVolumeIcon0: icon {
|
mediaPlayerVolumeIcon0: icon {
|
||||||
{ "player_volume0", mediaPlayerActiveFg },
|
{ "player_volume0", mediaPlayerActiveFg },
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,7 +22,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/style_media_player.h"
|
#include "styles/style_media_player.h"
|
||||||
#include "styles/style_mediaview.h"
|
#include "styles/style_mediaview.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
|
#include "storage/localstorage.h"
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
|
#include "facades.h"
|
||||||
|
|
||||||
namespace Media {
|
namespace Media {
|
||||||
namespace Player {
|
namespace Player {
|
||||||
|
@ -80,6 +82,7 @@ Widget::Widget(QWidget *parent) : RpWidget(parent)
|
||||||
, _playPause(this)
|
, _playPause(this)
|
||||||
, _volumeToggle(this, st::mediaPlayerVolumeToggle)
|
, _volumeToggle(this, st::mediaPlayerVolumeToggle)
|
||||||
, _repeatTrack(this, st::mediaPlayerRepeatButton)
|
, _repeatTrack(this, st::mediaPlayerRepeatButton)
|
||||||
|
, _playbackSpeed(this, st::mediaPlayerSpeedButton)
|
||||||
, _close(this, st::mediaPlayerClose)
|
, _close(this, st::mediaPlayerClose)
|
||||||
, _shadow(this)
|
, _shadow(this)
|
||||||
, _playbackSlider(this, st::mediaPlayerPlayback)
|
, _playbackSlider(this, st::mediaPlayerPlayback)
|
||||||
|
@ -128,6 +131,14 @@ Widget::Widget(QWidget *parent) : RpWidget(parent)
|
||||||
instance()->toggleRepeat(AudioMsgId::Type::Song);
|
instance()->toggleRepeat(AudioMsgId::Type::Song);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
updatePlaybackSpeedIcon();
|
||||||
|
_playbackSpeed->setClickedCallback([=] {
|
||||||
|
Global::SetVoiceMsgPlaybackSpeed(Global::VoiceMsgPlaybackSpeed() == 1.f ? 2.f : 1.f);
|
||||||
|
mixer()->updatePlaybackSpeed();
|
||||||
|
updatePlaybackSpeedIcon();
|
||||||
|
Local::writeSettings();
|
||||||
|
});
|
||||||
|
|
||||||
subscribe(instance()->repeatChangedNotifier(), [this](AudioMsgId::Type type) {
|
subscribe(instance()->repeatChangedNotifier(), [this](AudioMsgId::Type type) {
|
||||||
if (type == _type) {
|
if (type == _type) {
|
||||||
updateRepeatTrackIcon();
|
updateRepeatTrackIcon();
|
||||||
|
@ -247,6 +258,9 @@ void Widget::handleSeekFinished(float64 progress) {
|
||||||
void Widget::resizeEvent(QResizeEvent *e) {
|
void Widget::resizeEvent(QResizeEvent *e) {
|
||||||
auto right = st::mediaPlayerCloseRight;
|
auto right = st::mediaPlayerCloseRight;
|
||||||
_close->moveToRight(right, st::mediaPlayerPlayTop); right += _close->width();
|
_close->moveToRight(right, st::mediaPlayerPlayTop); right += _close->width();
|
||||||
|
if (_type == AudioMsgId::Type::Voice) {
|
||||||
|
_playbackSpeed->moveToRight(right, st::mediaPlayerPlayTop); right += _playbackSpeed->width();
|
||||||
|
}
|
||||||
_repeatTrack->moveToRight(right, st::mediaPlayerPlayTop); right += _repeatTrack->width();
|
_repeatTrack->moveToRight(right, st::mediaPlayerPlayTop); right += _repeatTrack->width();
|
||||||
_volumeToggle->moveToRight(right, st::mediaPlayerPlayTop); right += _volumeToggle->width();
|
_volumeToggle->moveToRight(right, st::mediaPlayerPlayTop); right += _volumeToggle->width();
|
||||||
|
|
||||||
|
@ -330,6 +344,8 @@ int Widget::getLabelsRight() const {
|
||||||
auto result = st::mediaPlayerCloseRight + _close->width();
|
auto result = st::mediaPlayerCloseRight + _close->width();
|
||||||
if (_type == AudioMsgId::Type::Song) {
|
if (_type == AudioMsgId::Type::Song) {
|
||||||
result += _repeatTrack->width() + _volumeToggle->width();
|
result += _repeatTrack->width() + _volumeToggle->width();
|
||||||
|
} else if (_type == AudioMsgId::Type::Voice) {
|
||||||
|
result += _playbackSpeed->width();
|
||||||
}
|
}
|
||||||
result += st::mediaPlayerPadding;
|
result += st::mediaPlayerPadding;
|
||||||
return result;
|
return result;
|
||||||
|
@ -353,6 +369,14 @@ void Widget::updateRepeatTrackIcon() {
|
||||||
_repeatTrack->setRippleColorOverride(repeating ? nullptr : &st::mediaPlayerRepeatDisabledRippleBg);
|
_repeatTrack->setRippleColorOverride(repeating ? nullptr : &st::mediaPlayerRepeatDisabledRippleBg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Widget::updatePlaybackSpeedIcon()
|
||||||
|
{
|
||||||
|
const auto playbackSpeed = Global::VoiceMsgPlaybackSpeed();
|
||||||
|
const auto isDefaultSpeed = playbackSpeed == 1.f;
|
||||||
|
_playbackSpeed->setIconOverride(isDefaultSpeed ? &st::mediaPlayerSpeedDisabledIcon : nullptr, isDefaultSpeed ? &st::mediaPlayerSpeedDisabledIconOver : nullptr);
|
||||||
|
_playbackSpeed->setRippleColorOverride(isDefaultSpeed ? &st::mediaPlayerSpeedDisabledRippleBg : nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void Widget::checkForTypeChange() {
|
void Widget::checkForTypeChange() {
|
||||||
auto hasActiveType = [](AudioMsgId::Type type) {
|
auto hasActiveType = [](AudioMsgId::Type type) {
|
||||||
auto current = instance()->current(type);
|
auto current = instance()->current(type);
|
||||||
|
@ -372,6 +396,7 @@ void Widget::setType(AudioMsgId::Type type) {
|
||||||
_type = type;
|
_type = type;
|
||||||
_repeatTrack->setVisible(_type == AudioMsgId::Type::Song);
|
_repeatTrack->setVisible(_type == AudioMsgId::Type::Song);
|
||||||
_volumeToggle->setVisible(_type == AudioMsgId::Type::Song);
|
_volumeToggle->setVisible(_type == AudioMsgId::Type::Song);
|
||||||
|
_playbackSpeed->setVisible(_type == AudioMsgId::Type::Voice);
|
||||||
if (!_shadow->isHidden()) {
|
if (!_shadow->isHidden()) {
|
||||||
_playbackSlider->setVisible(_type == AudioMsgId::Type::Song);
|
_playbackSlider->setVisible(_type == AudioMsgId::Type::Song);
|
||||||
}
|
}
|
||||||
|
@ -384,6 +409,9 @@ void Widget::setType(AudioMsgId::Type type) {
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
handlePlaylistUpdate();
|
handlePlaylistUpdate();
|
||||||
});
|
});
|
||||||
|
// maybe the type change causes a change of the button layout
|
||||||
|
QResizeEvent event = { size(), size() };
|
||||||
|
resizeEvent(&event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ private:
|
||||||
void updatePlayPrevNextPositions();
|
void updatePlayPrevNextPositions();
|
||||||
void updateLabelsGeometry();
|
void updateLabelsGeometry();
|
||||||
void updateRepeatTrackIcon();
|
void updateRepeatTrackIcon();
|
||||||
|
void updatePlaybackSpeedIcon();
|
||||||
void createPrevNextButtons();
|
void createPrevNextButtons();
|
||||||
void destroyPrevNextButtons();
|
void destroyPrevNextButtons();
|
||||||
|
|
||||||
|
@ -103,6 +104,7 @@ private:
|
||||||
object_ptr<Ui::IconButton> _nextTrack = { nullptr };
|
object_ptr<Ui::IconButton> _nextTrack = { nullptr };
|
||||||
object_ptr<Ui::IconButton> _volumeToggle;
|
object_ptr<Ui::IconButton> _volumeToggle;
|
||||||
object_ptr<Ui::IconButton> _repeatTrack;
|
object_ptr<Ui::IconButton> _repeatTrack;
|
||||||
|
object_ptr<Ui::IconButton> _playbackSpeed;
|
||||||
object_ptr<Ui::IconButton> _close;
|
object_ptr<Ui::IconButton> _close;
|
||||||
object_ptr<Ui::PlainShadow> _shadow = { nullptr };
|
object_ptr<Ui::PlainShadow> _shadow = { nullptr };
|
||||||
object_ptr<Ui::FilledSlider> _playbackSlider;
|
object_ptr<Ui::FilledSlider> _playbackSlider;
|
||||||
|
|
|
@ -598,6 +598,7 @@ enum {
|
||||||
dbiCacheSettings = 0x56,
|
dbiCacheSettings = 0x56,
|
||||||
dbiAnimationsDisabled = 0x57,
|
dbiAnimationsDisabled = 0x57,
|
||||||
dbiScalePercent = 0x58,
|
dbiScalePercent = 0x58,
|
||||||
|
dbiPlaybackSpeed = 0x59,
|
||||||
|
|
||||||
dbiEncryptedWithSalt = 333,
|
dbiEncryptedWithSalt = 333,
|
||||||
dbiEncrypted = 444,
|
dbiEncrypted = 444,
|
||||||
|
@ -1749,6 +1750,14 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting
|
||||||
Global::SetVideoVolume(snap(v / 1e6, 0., 1.));
|
Global::SetVideoVolume(snap(v / 1e6, 0., 1.));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case dbiPlaybackSpeed: {
|
||||||
|
quint32 v;
|
||||||
|
stream >> v;
|
||||||
|
if (!_checkStreamStatus(stream)) return false;
|
||||||
|
|
||||||
|
Global::SetVoiceMsgPlaybackSpeed(v);
|
||||||
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG(("App Error: unknown blockId in _readSetting: %1").arg(blockId));
|
LOG(("App Error: unknown blockId in _readSetting: %1").arg(blockId));
|
||||||
return false;
|
return false;
|
||||||
|
@ -2596,6 +2605,7 @@ void writeSettings() {
|
||||||
data.stream << quint32(dbiLoggedPhoneNumber) << cLoggedPhoneNumber();
|
data.stream << quint32(dbiLoggedPhoneNumber) << cLoggedPhoneNumber();
|
||||||
data.stream << quint32(dbiTxtDomainString) << Global::TxtDomainString();
|
data.stream << quint32(dbiTxtDomainString) << Global::TxtDomainString();
|
||||||
data.stream << quint32(dbiAnimationsDisabled) << qint32(anim::Disabled() ? 1 : 0);
|
data.stream << quint32(dbiAnimationsDisabled) << qint32(anim::Disabled() ? 1 : 0);
|
||||||
|
data.stream << quint32(dbiPlaybackSpeed) << quint32(Global::VoiceMsgPlaybackSpeed());
|
||||||
|
|
||||||
data.stream << quint32(dbiConnectionType) << qint32(dbictProxiesList);
|
data.stream << quint32(dbiConnectionType) << qint32(dbictProxiesList);
|
||||||
data.stream << qint32(proxies.size());
|
data.stream << qint32(proxies.size());
|
||||||
|
|
Loading…
Reference in New Issue