Update TTS audio API use

This commit is contained in:
Atlante45 2018-11-13 12:12:48 -08:00
parent 7f910a38e3
commit 31033ad685
3 changed files with 53 additions and 1 deletions

View file

@ -147,7 +147,11 @@ void TTSScriptingInterface::speakText(const QString& textToSpeak) {
_lastSoundAudioInjectorUpdateTimer.stop();
}
_lastSoundAudioInjector = AudioInjector::playSoundAndDelete(_lastSoundByteArray, options);
uint32_t numChannels = 1;
uint32_t numSamples = (uint32_t)_lastSoundByteArray.size() / sizeof(AudioData::AudioSample);
auto samples = reinterpret_cast<AudioData::AudioSample*>(_lastSoundByteArray.data());
auto newAudioData = AudioData::make(numSamples, numChannels, samples);
_lastSoundAudioInjector = AudioInjector::playSoundAndDelete(newAudioData, options);
_lastSoundAudioInjectorUpdateTimer.start(INJECTOR_INTERVAL_MS);
#else

View file

@ -476,3 +476,49 @@ AudioInjectorPointer AudioInjector::playSound(SharedSoundPointer sound, const A
return injector;
}
}
AudioInjectorPointer AudioInjector::playSoundAndDelete(AudioDataPointer audioData, const AudioInjectorOptions& options) {
AudioInjectorPointer injector = playSound(audioData, options);
if (injector) {
injector->_state |= AudioInjectorState::PendingDelete;
}
return injector;
}
AudioInjectorPointer AudioInjector::playSound(AudioDataPointer audioData, const AudioInjectorOptions& options) {
if (options.pitch == 1.0f) {
AudioInjectorPointer injector = AudioInjectorPointer::create(audioData, options);
if (!injector->inject(&AudioInjectorManager::threadInjector)) {
qWarning() << "AudioInjector::playSound failed to thread pitch-shifted injector";
}
return injector;
} else {
using AudioConstants::AudioSample;
using AudioConstants::SAMPLE_RATE;
const int standardRate = SAMPLE_RATE;
// limit to 4 octaves
const int pitch = glm::clamp(options.pitch, 1 / 16.0f, 16.0f);
const int resampledRate = SAMPLE_RATE / pitch;
auto numChannels = audioData->getNumChannels();
auto numFrames = audioData->getNumFrames();
AudioSRC resampler(standardRate, resampledRate, numChannels);
// create a resampled buffer that is guaranteed to be large enough
const int maxOutputFrames = resampler.getMaxOutput(numFrames);
const int maxOutputSize = maxOutputFrames * numChannels * sizeof(AudioSample);
QByteArray resampledBuffer(maxOutputSize, '\0');
auto bufferPtr = reinterpret_cast<AudioSample*>(resampledBuffer.data());
resampler.render(audioData->data(), bufferPtr, numFrames);
int numSamples = maxOutputFrames * numChannels;
auto newAudioData = AudioData::make(numSamples, numChannels, bufferPtr);
return AudioInjector::playSound(newAudioData, options);
}
}

View file

@ -77,6 +77,8 @@ public:
static AudioInjectorPointer playSoundAndDelete(SharedSoundPointer sound, const AudioInjectorOptions& options);
static AudioInjectorPointer playSound(SharedSoundPointer sound, const AudioInjectorOptions& options);
static AudioInjectorPointer playSoundAndDelete(AudioDataPointer audioData, const AudioInjectorOptions& options);
static AudioInjectorPointer playSound(AudioDataPointer audioData, const AudioInjectorOptions& options);
public slots:
void restart();