Раздели PCM-сессии и исправь частоту и перемотку звука
This commit is contained in:
1 parent
40b974b29c
commit
217e5795bf
13 files changed
+226
-134
No files matched your search
@@ -29,6 +29,7 @@ MessageDelegate::MessageDelegate(QObject *parent)
|
||||
: QStyledItemDelegate(parent) {}
|
||||
|
||||
struct VoicePlayState {
|
||||
uint64_t playbackId = 0;
|
||||
bool loading = false;
|
||||
bool playing = false;
|
||||
bool paused = false;
|
||||
@@ -56,7 +57,7 @@ static void ensureVoiceTimer() {
|
||||
continue;
|
||||
}
|
||||
if (it->paused) { anyActive = true; continue; }
|
||||
if (!sm->isCurrentPcmPlaying()) {
|
||||
if (!sm->isPcmPlaying(it->playbackId)) {
|
||||
it->playing = false;
|
||||
it->paused = false;
|
||||
anyActive = true;
|
||||
@@ -177,16 +178,16 @@ bool MessageDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
|
||||
/* Start playback then seek */
|
||||
st.loading = true;
|
||||
QPersistentModelIndex persistent(index);
|
||||
VoicePlayer::playOpusFile(filePath, this, [filePath, clickFrac, persistent](float actualDur) {
|
||||
VoicePlayer::playOpusFile(filePath, this, [filePath, clickFrac, persistent](float actualDur, uint64_t playbackId) {
|
||||
s_voiceStates[filePath].loading = false;
|
||||
if (actualDur <= 0) return;
|
||||
MessageDelegate::startAutoPlay(filePath, actualDur);
|
||||
MessageDelegate::startAutoPlay(filePath, actualDur, playbackId);
|
||||
float position = clickFrac * actualDur;
|
||||
auto& state = s_voiceStates[filePath];
|
||||
state.startMs -= (qint64)(position * 1000); state.pausedPosSec = position;
|
||||
state.displayFrac = clickFrac; state.displayElapsed = position;
|
||||
int rate = SoundManager::instance()->currentPcmSampleRate();
|
||||
if (rate > 0) SoundManager::instance()->seekCurrentPcm((unsigned long long)(position * rate));
|
||||
int rate = SoundManager::instance()->pcmSampleRate(playbackId);
|
||||
if (rate > 0) SoundManager::instance()->seekPcm(playbackId, (unsigned long long)(position * rate));
|
||||
if (persistent.isValid()) const_cast<QAbstractItemModel*>(persistent.model())->setData(persistent, 1, MsgVoicePlayStateRole);
|
||||
});
|
||||
s_voiceTimer->start();
|
||||
@@ -199,9 +200,9 @@ bool MessageDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
|
||||
{ st.playing = true; s_voiceTimer->start(); }
|
||||
st.displayFrac = (targetSec > 0 && dur > 0) ? (targetSec / dur) : 0;
|
||||
st.displayElapsed = targetSec;
|
||||
int sr = SoundManager::instance()->currentPcmSampleRate();
|
||||
int sr = SoundManager::instance()->pcmSampleRate(st.playbackId);
|
||||
if (sr > 0)
|
||||
SoundManager::instance()->seekCurrentPcm((unsigned long long)(targetSec * sr));
|
||||
SoundManager::instance()->seekPcm(st.playbackId, (unsigned long long)(targetSec * sr));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -219,7 +220,7 @@ bool MessageDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
|
||||
st.pausedPosSec = (now - st.startMs) / 1000.0f;
|
||||
st.playing = false;
|
||||
st.paused = true;
|
||||
SoundManager::instance()->pauseCurrentPcm();
|
||||
SoundManager::instance()->pausePcm(st.playbackId);
|
||||
model->setData(index, 2, MsgVoicePlayStateRole);
|
||||
return true;
|
||||
}
|
||||
@@ -232,7 +233,7 @@ bool MessageDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
|
||||
st.startMs = now - (qint64)(st.pausedPosSec * 1000.0);
|
||||
st.displayFrac = (dur > 0) ? (st.pausedPosSec / dur) : 0;
|
||||
st.displayElapsed = st.pausedPosSec;
|
||||
SoundManager::instance()->resumeCurrentPcm();
|
||||
SoundManager::instance()->resumePcm(st.playbackId);
|
||||
s_voiceTimer->start();
|
||||
model->setData(index, 1, MsgVoicePlayStateRole);
|
||||
return true;
|
||||
@@ -243,15 +244,15 @@ bool MessageDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
|
||||
for (auto it = s_voiceStates.begin(); it != s_voiceStates.end(); ++it) {
|
||||
it->playing = false; it->paused = false;
|
||||
}
|
||||
SoundManager::instance()->stopCurrentPcm();
|
||||
VoicePlayer::stop();
|
||||
}
|
||||
|
||||
st.loading = true;
|
||||
QPersistentModelIndex persistent(index);
|
||||
VoicePlayer::playOpusFile(filePath, this, [filePath, persistent](float actualDur) {
|
||||
VoicePlayer::playOpusFile(filePath, this, [filePath, persistent](float actualDur, uint64_t playbackId) {
|
||||
s_voiceStates[filePath].loading = false;
|
||||
if (actualDur <= 0) return;
|
||||
MessageDelegate::startAutoPlay(filePath, actualDur);
|
||||
MessageDelegate::startAutoPlay(filePath, actualDur, playbackId);
|
||||
if (persistent.isValid()) const_cast<QAbstractItemModel*>(persistent.model())->setData(persistent, 1, MsgVoicePlayStateRole);
|
||||
});
|
||||
s_voiceTimer->start();
|
||||
@@ -913,9 +914,9 @@ void MessageDelegate::paint(QPainter *painter, const QStyleOptionViewItem &optio
|
||||
elapsed = st->pausedPosSec;
|
||||
} else if (isPlaying) {
|
||||
SoundManager* sm = SoundManager::instance();
|
||||
if (sm->isCurrentPcmPlaying()) {
|
||||
int sr = sm->currentPcmSampleRate();
|
||||
if (sr > 0) elapsed = (float)((double)sm->currentPcmCursor() / sr);
|
||||
if (sm->isPcmPlaying(st->playbackId)) {
|
||||
int sr = sm->pcmSampleRate(st->playbackId);
|
||||
if (sr > 0) elapsed = (float)((double)sm->pcmCursor(st->playbackId) / sr);
|
||||
}
|
||||
if (elapsed <= 0) {
|
||||
qint64 now = QDateTime::currentMSecsSinceEpoch();
|
||||
@@ -1504,10 +1505,11 @@ void MessageDelegate::drawAvatar(QPainter *p, const Layout &L,
|
||||
p->restore();
|
||||
}
|
||||
|
||||
void MessageDelegate::startAutoPlay(const QString& filePath, float actualDurationSec) {
|
||||
void MessageDelegate::startAutoPlay(const QString& filePath, float actualDurationSec, uint64_t playbackId) {
|
||||
if (actualDurationSec <= 0) return;
|
||||
ensureVoiceTimer();
|
||||
VoicePlayState& st = s_voiceStates[filePath];
|
||||
st.playbackId = playbackId;
|
||||
st.playing = true;
|
||||
st.paused = false;
|
||||
st.durationSec = (actualDurationSec > 0) ? actualDurationSec : 1.0f;
|
||||
@@ -1520,7 +1522,7 @@ void MessageDelegate::startAutoPlay(const QString& filePath, float actualDuratio
|
||||
}
|
||||
|
||||
void MessageDelegate::stopAllAutoPlay() {
|
||||
VoicePlayer::cancelPending();
|
||||
VoicePlayer::stop();
|
||||
for (auto it = s_voiceStates.begin(); it != s_voiceStates.end(); ++it) {
|
||||
it->playing = false; it->paused = false; it->loading = false;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user