mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 13:18:38 +02:00
Merge pull request #8652 from zzmp/fix/audio-injector
fix injector restart fail on lack of local interface
This commit is contained in:
commit
ee6719f94a
3 changed files with 41 additions and 75 deletions
|
@ -96,26 +96,6 @@ void AudioInjector::finish() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioInjector::setupInjection() {
|
|
||||||
if (!_hasSetup) {
|
|
||||||
_hasSetup = true;
|
|
||||||
|
|
||||||
// check if we need to offset the sound by some number of seconds
|
|
||||||
if (_options.secondOffset > 0.0f) {
|
|
||||||
|
|
||||||
// convert the offset into a number of bytes
|
|
||||||
int byteOffset = (int) floorf(AudioConstants::SAMPLE_RATE * _options.secondOffset * (_options.stereo ? 2.0f : 1.0f));
|
|
||||||
byteOffset *= sizeof(int16_t);
|
|
||||||
|
|
||||||
_currentSendOffset = byteOffset;
|
|
||||||
} else {
|
|
||||||
_currentSendOffset = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qCDebug(audio) << "AudioInjector::setupInjection called but already setup.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioInjector::restart() {
|
void AudioInjector::restart() {
|
||||||
// grab the AudioInjectorManager
|
// grab the AudioInjectorManager
|
||||||
auto injectorManager = DependencyManager::get<AudioInjectorManager>();
|
auto injectorManager = DependencyManager::get<AudioInjectorManager>();
|
||||||
|
@ -143,30 +123,37 @@ void AudioInjector::restart() {
|
||||||
|
|
||||||
// check our state to decide if we need extra handling for the restart request
|
// check our state to decide if we need extra handling for the restart request
|
||||||
if (stateHas(AudioInjectorState::Finished)) {
|
if (stateHas(AudioInjectorState::Finished)) {
|
||||||
// we finished playing, need to reset state so we can get going again
|
if (!inject(&AudioInjectorManager::restartFinishedInjector)) {
|
||||||
_hasSetup = false;
|
qWarning() << "AudioInjector::restart failed to thread injector";
|
||||||
_shouldStop = false;
|
|
||||||
_state = AudioInjectorState::NotFinished;
|
|
||||||
|
|
||||||
// call inject audio to start injection over again
|
|
||||||
setupInjection();
|
|
||||||
|
|
||||||
// inject locally
|
|
||||||
if(injectLocally()) {
|
|
||||||
|
|
||||||
// if not localOnly, wake the AudioInjectorManager back up if it is stuck waiting
|
|
||||||
if (!_options.localOnly) {
|
|
||||||
|
|
||||||
if (!injectorManager->restartFinishedInjector(this)) {
|
|
||||||
_state = AudioInjectorState::Finished; // we're not playing, so reset the state used by isPlaying.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_state = AudioInjectorState::Finished; // we failed to play, so we are finished again
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AudioInjector::inject(bool(AudioInjectorManager::*injection)(AudioInjector*)) {
|
||||||
|
_state = AudioInjectorState::NotFinished;
|
||||||
|
|
||||||
|
int byteOffset = 0;
|
||||||
|
if (_options.secondOffset > 0.0f) {
|
||||||
|
byteOffset = (int)floorf(AudioConstants::SAMPLE_RATE * _options.secondOffset * (_options.stereo ? 2.0f : 1.0f));
|
||||||
|
byteOffset *= sizeof(AudioConstants::SAMPLE_SIZE);
|
||||||
|
}
|
||||||
|
_currentSendOffset = byteOffset;
|
||||||
|
|
||||||
|
if (!injectLocally()) {
|
||||||
|
finishLocalInjection();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = true;
|
||||||
|
if (!_options.localOnly) {
|
||||||
|
auto injectorManager = DependencyManager::get<AudioInjectorManager>();
|
||||||
|
if (!(*injectorManager.*injection)(this)) {
|
||||||
|
success = false;
|
||||||
|
finishNetworkInjection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
bool AudioInjector::injectLocally() {
|
bool AudioInjector::injectLocally() {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (_localAudioInterface) {
|
if (_localAudioInterface) {
|
||||||
|
@ -195,11 +182,6 @@ bool AudioInjector::injectLocally() {
|
||||||
qCDebug(audio) << "AudioInjector::injectLocally cannot inject locally with no local audio interface present.";
|
qCDebug(audio) << "AudioInjector::injectLocally cannot inject locally with no local audio interface present.";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
// we never started so we are finished with local injection
|
|
||||||
finishLocalInjection();
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,24 +456,8 @@ AudioInjector* AudioInjector::playSoundAndDelete(const QByteArray& buffer, const
|
||||||
|
|
||||||
AudioInjector* AudioInjector::playSound(const QByteArray& buffer, const AudioInjectorOptions options) {
|
AudioInjector* AudioInjector::playSound(const QByteArray& buffer, const AudioInjectorOptions options) {
|
||||||
AudioInjector* injector = new AudioInjector(buffer, options);
|
AudioInjector* injector = new AudioInjector(buffer, options);
|
||||||
|
if (!injector->inject(&AudioInjectorManager::threadInjector)) {
|
||||||
// grab the AudioInjectorManager
|
qWarning() << "AudioInjector::playSound failed to thread injector";
|
||||||
auto injectorManager = DependencyManager::get<AudioInjectorManager>();
|
|
||||||
|
|
||||||
// setup parameters required for injection
|
|
||||||
injector->setupInjection();
|
|
||||||
|
|
||||||
// we always inject locally, except when there is no localInterface
|
|
||||||
injector->injectLocally();
|
|
||||||
|
|
||||||
// if localOnly, we are done, just return injector.
|
|
||||||
if (!options.localOnly) {
|
|
||||||
|
|
||||||
// send off to server for everyone else
|
|
||||||
if (!injectorManager->threadInjector(injector)) {
|
|
||||||
// we failed to thread the new injector (we are at the max number of injector threads)
|
|
||||||
qDebug() << "AudioInjector::playSound failed to thread injector";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return injector;
|
return injector;
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,8 +92,8 @@ signals:
|
||||||
void restarting();
|
void restarting();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupInjection();
|
|
||||||
int64_t injectNextFrame();
|
int64_t injectNextFrame();
|
||||||
|
bool inject(bool(AudioInjectorManager::*injection)(AudioInjector*));
|
||||||
bool injectLocally();
|
bool injectLocally();
|
||||||
|
|
||||||
static AbstractAudioInterface* _localAudioInterface;
|
static AbstractAudioInterface* _localAudioInterface;
|
||||||
|
@ -102,8 +102,6 @@ private:
|
||||||
AudioInjectorOptions _options;
|
AudioInjectorOptions _options;
|
||||||
AudioInjectorState _state { AudioInjectorState::NotFinished };
|
AudioInjectorState _state { AudioInjectorState::NotFinished };
|
||||||
bool _hasSentFirstFrame { false };
|
bool _hasSentFirstFrame { false };
|
||||||
bool _hasSetup { false };
|
|
||||||
bool _shouldStop { false };
|
|
||||||
float _loudness { 0.0f };
|
float _loudness { 0.0f };
|
||||||
int _currentSendOffset { 0 };
|
int _currentSendOffset { 0 };
|
||||||
std::unique_ptr<NLPacket> _currentPacket { nullptr };
|
std::unique_ptr<NLPacket> _currentPacket { nullptr };
|
||||||
|
|
|
@ -157,8 +157,6 @@ bool AudioInjectorManager::threadInjector(AudioInjector* injector) {
|
||||||
// move the injector to the QThread
|
// move the injector to the QThread
|
||||||
injector->moveToThread(_thread);
|
injector->moveToThread(_thread);
|
||||||
|
|
||||||
// handle a restart once the injector has finished
|
|
||||||
|
|
||||||
// add the injector to the queue with a send timestamp of now
|
// add the injector to the queue with a send timestamp of now
|
||||||
_injectors.emplace(usecTimestampNow(), InjectorQPointer { injector });
|
_injectors.emplace(usecTimestampNow(), InjectorQPointer { injector });
|
||||||
|
|
||||||
|
@ -170,13 +168,17 @@ bool AudioInjectorManager::threadInjector(AudioInjector* injector) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioInjectorManager::restartFinishedInjector(AudioInjector* injector) {
|
bool AudioInjectorManager::restartFinishedInjector(AudioInjector* injector) {
|
||||||
if (!_shouldStop) {
|
if (_shouldStop) {
|
||||||
// guard the injectors vector with a mutex
|
qDebug() << "AudioInjectorManager::threadInjector asked to thread injector but is shutting down.";
|
||||||
Lock lock(_injectorsMutex);
|
return false;
|
||||||
|
}
|
||||||
if (wouldExceedLimits()) {
|
|
||||||
return false;
|
// guard the injectors vector with a mutex
|
||||||
}
|
Lock lock(_injectorsMutex);
|
||||||
|
|
||||||
|
if (wouldExceedLimits()) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
// add the injector to the queue with a send timestamp of now
|
// add the injector to the queue with a send timestamp of now
|
||||||
_injectors.emplace(usecTimestampNow(), InjectorQPointer { injector });
|
_injectors.emplace(usecTimestampNow(), InjectorQPointer { injector });
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue