Use streaming player speed in 2x playback.

This commit is contained in:
John Preston 2019-03-26 16:50:00 +04:00
parent e87084715d
commit bf182697b9
6 changed files with 23 additions and 96 deletions

View File

@ -521,9 +521,6 @@ void Application::startMtp() {
if (_authSession) {
// Skip all pending self updates so that we won't Local::writeSelf.
Notify::peerUpdatedSendDelayed();
Media::Player::mixer()->setVoicePlaybackDoubled(
Global::VoiceMsgPlaybackDoubled());
}
}
@ -987,7 +984,6 @@ void Application::loggedOut() {
clearPasscodeLock();
Media::Player::mixer()->stopAndClear();
Global::SetVoiceMsgPlaybackDoubled(false);
Media::Player::mixer()->setVoicePlaybackDoubled(false);
if (const auto window = getActiveWindow()) {
window->tempDirDelete(Local::ClearManagerAll);
window->setupIntro();

View File

@ -31,7 +31,6 @@ namespace {
constexpr auto kSuppressRatioAll = 0.2;
constexpr auto kSuppressRatioSong = 0.05;
constexpr auto kPlaybackSpeedMultiplier = 1.7;
constexpr auto kWaveformCounterBufferSize = 256 * 1024;
QMutex AudioMutex;
@ -58,15 +57,6 @@ namespace {
Player::Mixer *MixerInstance = nullptr;
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
struct PlaybackSpeedData {
ALuint uiEffectSlot = 0;
ALuint uiEffect = 0;
ALuint uiFilter = 0;
};
PlaybackSpeedData _playbackSpeedData;
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
// Thread: Any.
bool ContextErrorHappened() {
ALenum errCode;
@ -167,26 +157,6 @@ bool CreatePlaybackDevice() {
alListener3f(AL_VELOCITY, 0.f, 0.f, 0.f);
alListenerfv(AL_ORIENTATION, v);
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
// 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, CoarseTuneForSpeed(kPlaybackSpeedMultiplier));
// 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
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
alDistanceModel(AL_NONE);
return true;
@ -198,16 +168,6 @@ void ClosePlaybackDevice(not_null<Instance*> instance) {
LOG(("Audio Info: Closing audio playback device."));
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
// playback speed related
alDeleteFilters(1, &_playbackSpeedData.uiFilter);
alDeleteEffects(1, &_playbackSpeedData.uiEffect);
alDeleteAuxiliaryEffectSlots(1, &_playbackSpeedData.uiEffectSlot);
_playbackSpeedData.uiFilter = 0;
_playbackSpeedData.uiEffect = 0;
_playbackSpeedData.uiEffectSlot = 0;
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
if (Player::mixer()) {
Player::mixer()->detachTracks();
}
@ -353,21 +313,20 @@ void Mixer::Track::createStream(AudioMsgId::Type type) {
alSourcei(stream.source, AL_LOOPING, 0);
alSourcei(stream.source, AL_DIRECT_CHANNELS_SOFT, 1);
alGenBuffers(3, stream.buffers);
if (type == AudioMsgId::Type::Voice) {
mixer()->updatePlaybackSpeed(this);
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
} else if (speedEffect) {
if (speedEffect) {
applySourceSpeedEffect();
} else {
removeSourceSpeedEffect();
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
}
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
}
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
void Mixer::Track::removeSourceSpeedEffect() {
alSource3i(stream.source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, 0);
alSourcei(stream.source, AL_DIRECT_FILTER, AL_FILTER_NULL);
alSourcef(stream.source, AL_PITCH, 1.f);
}
void Mixer::Track::applySourceSpeedEffect() {
@ -411,11 +370,9 @@ void Mixer::Track::resetSpeedEffect() {
if (isStreamCreated()) {
removeSourceSpeedEffect();
}
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
alDeleteEffects(1, &speedEffect->effect);
alDeleteAuxiliaryEffectSlots(1, &speedEffect->effectSlot);
alDeleteFilters(1, &speedEffect->filter);
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
}
speedEffect->effect = speedEffect->effectSlot = speedEffect->filter = 0;
}
@ -1157,35 +1114,6 @@ void Mixer::stop(const AudioMsgId &audio, State state) {
if (current) emit updated(current);
}
// Thread: Any. Must be locked: AudioMutex.
void Mixer::updatePlaybackSpeed(Track *track) {
const auto doubled = (_voicePlaybackDoubled.loadAcquire() == 1);
updatePlaybackSpeed(track, doubled);
}
void Mixer::updatePlaybackSpeed(Track *track, bool doubled) {
if (!track->isStreamCreated()) {
return;
}
#ifndef TDESKTOP_DISABLE_OPENAL_EFFECTS
const auto source = track->stream.source;
// Note: This alters the playback speed AND the pitch
alSourcef(source, AL_PITCH, doubled ? kPlaybackSpeedMultiplier : 1.);
// fix the pitch using effects and filters
if (doubled) {
// connect the effect slot with the stream
alSource3i(source, AL_AUXILIARY_SEND_FILTER, Media::Audio::_playbackSpeedData.uiEffectSlot, 0, 0);
// connect the filter with the stream
alSourcei(source, AL_DIRECT_FILTER, Media::Audio::_playbackSpeedData.uiFilter);
} else {
// disconnect the effect slot
alSource3i(source, AL_AUXILIARY_SEND_FILTER, AL_EFFECTSLOT_NULL, 0, 0);
// disconnect the filter
alSourcei(source, AL_DIRECT_FILTER, AL_FILTER_NULL);
}
#endif // TDESKTOP_DISABLE_OPENAL_EFFECTS
}
void Mixer::stopAndClear() {
Track *current_audio = nullptr, *current_song = nullptr;
{
@ -1282,16 +1210,6 @@ void Mixer::reattachTracks() {
_videoTrack.reattach(AudioMsgId::Type::Video);
}
// Thread: Any. Locks AudioMutex.
void Mixer::setVoicePlaybackDoubled(bool doubled) {
_voicePlaybackDoubled.storeRelease(doubled ? 1 : 0);
QMutexLocker lock(&AudioMutex);
for (auto &track : _audioTracks) {
updatePlaybackSpeed(&track, doubled);
}
}
void Mixer::setSongVolume(float64 volume) {
_volumeSong.storeRelease(qRound(volume * kVolumeRound));
}

View File

@ -167,9 +167,6 @@ public:
void setVideoVolume(float64 volume);
float64 getVideoVolume() const;
// Thread: Any. Locks AudioMutex.
void setVoicePlaybackDoubled(bool doubled);
~Mixer();
private slots:
@ -269,8 +266,6 @@ private:
// Thread: Any. Must be locked: AudioMutex.
void setStoppedState(Track *current, State state = State::Stopped);
void updatePlaybackSpeed(Track *track);
void updatePlaybackSpeed(Track *track, bool doubled);
Track *trackForType(AudioMsgId::Type type, int index = -1); // -1 uses currentIndex(type)
const Track *trackForType(AudioMsgId::Type type, int index = -1) const;
@ -289,7 +284,6 @@ private:
QAtomicInt _volumeVideo;
QAtomicInt _volumeSong;
QAtomicInt _voicePlaybackDoubled = { 0 };
friend class Fader;
friend class Loaders;

View File

@ -31,6 +31,8 @@ namespace {
Instance *SingleInstance = nullptr;
constexpr auto kVoicePlaybackSpeedMultiplier = 1.7;
// Preload X message ids before and after current.
constexpr auto kIdsLimit = 32;
@ -408,6 +410,11 @@ Streaming::PlaybackOptions Instance::streamingOptions(
result.mode = (document && document->isVideoMessage())
? Streaming::Mode::Both
: Streaming::Mode::Audio;
result.speed = (document
&& (document->isVoiceMessage() || document->isVideoMessage())
&& Global::VoiceMsgPlaybackDoubled())
? kVoicePlaybackSpeedMultiplier
: 1.;
result.audioId = audioId;
result.position = position;
return result;
@ -543,6 +550,16 @@ void Instance::cancelSeeking(AudioMsgId::Type type) {
emitUpdate(type);
}
void Instance::updateVoicePlaybackSpeed() {
if (const auto data = getData(AudioMsgId::Type::Voice)) {
if (const auto streamed = data->streamed.get()) {
streamed->player.setSpeed(Global::VoiceMsgPlaybackDoubled()
? kVoicePlaybackSpeedMultiplier
: 1.);
}
}
}
void Instance::documentLoadProgress(DocumentData *document) {
const auto type = document->isAudioFile()
? AudioMsgId::Type::Song

View File

@ -115,6 +115,8 @@ public:
void finishSeeking(AudioMsgId::Type type, float64 progress);
void cancelSeeking(AudioMsgId::Type type);
void updateVoicePlaybackSpeed();
[[nodiscard]] bool nextAvailable(AudioMsgId::Type type) const;
[[nodiscard]] bool previousAvailable(AudioMsgId::Type type) const;

View File

@ -135,7 +135,7 @@ Widget::Widget(QWidget *parent) : RpWidget(parent)
_playbackSpeed->setClickedCallback([=] {
const auto doubled = !Global::VoiceMsgPlaybackDoubled();
Global::SetVoiceMsgPlaybackDoubled(doubled);
mixer()->setVoicePlaybackDoubled(doubled);
instance()->updateVoicePlaybackSpeed();
updatePlaybackSpeedIcon();
Local::writeUserSettings();
});