Audio book bugfixing

This commit is contained in:
Jakub Melka 2020-10-22 18:49:56 +02:00
parent fab94505d1
commit 93a1ce76da
2 changed files with 54 additions and 24 deletions

View File

@ -31,18 +31,34 @@ namespace pdftool
static PDFToolAudioBook s_audioBookApplication; static PDFToolAudioBook s_audioBookApplication;
static PDFToolAudioBookVoices s_audioBookVoicesApplication; static PDFToolAudioBookVoices s_audioBookVoicesApplication;
PDFVoiceInfo::PDFVoiceInfo(std::map<QString, QString> properties, ISpVoice* voice) : PDFVoiceInfo::PDFVoiceInfo(std::map<QString, QString> properties, ISpObjectToken* voiceToken) :
m_properties(qMove(properties)), m_properties(qMove(properties)),
m_voice(voice) m_voiceToken(voiceToken)
{ {
if (m_voiceToken)
{
m_voiceToken->AddRef();
}
}
PDFVoiceInfo::PDFVoiceInfo(PDFVoiceInfo&& other)
{
std::swap(m_properties, other.m_properties);
std::swap(m_voiceToken, other.m_voiceToken);
}
PDFVoiceInfo& PDFVoiceInfo::operator=(PDFVoiceInfo&& other)
{
std::swap(m_properties, other.m_properties);
std::swap(m_voiceToken, other.m_voiceToken);
return *this;
} }
PDFVoiceInfo::~PDFVoiceInfo() PDFVoiceInfo::~PDFVoiceInfo()
{ {
if (m_voice) if (m_voiceToken)
{ {
m_voice->Release(); m_voiceToken->Release();
} }
} }
@ -82,7 +98,7 @@ QString PDFVoiceInfo::getStringValue(QString key) const
return QString(); return QString();
} }
int PDFToolAudioBookBase::fillVoices(const PDFToolOptions& options, PDFVoiceInfoList& list, bool fillVoicePointers) int PDFToolAudioBookBase::fillVoices(const PDFToolOptions& options, PDFVoiceInfoList& list, bool fillVoiceTokenPointers)
{ {
int result = ExitSuccess; int result = ExitSuccess;
@ -167,13 +183,14 @@ int PDFToolAudioBookBase::fillVoices(const PDFToolOptions& options, PDFVoiceInfo
attributes->Release(); attributes->Release();
} }
ISpVoice* voice = nullptr; if (fillVoiceTokenPointers)
if (fillVoicePointers)
{ {
token->QueryInterface(__uuidof(ISpVoice), (void**)&voice); list.emplace_back(qMove(properties), token);
}
else
{
list.emplace_back(qMove(properties), nullptr);
} }
list.emplace_back(qMove(properties), voice);
token->Release(); token->Release();
} }
@ -370,18 +387,18 @@ int PDFToolAudioBook::createAudioBook(const PDFToolOptions& options, pdf::PDFDoc
// Do we have any voice? // Do we have any voice?
if (voices.empty()) if (voices.empty())
{ {
PDFConsole::writeError(PDFToolTranslationContext::tr("Invalid voice."), options.outputCodec); PDFConsole::writeError(PDFToolTranslationContext::tr("No suitable voice found."), options.outputCodec);
return ErrorSAPI; return ErrorSAPI;
} }
if (!voices.front().getVoice()) if (!voices.front().getVoiceToken())
{ {
PDFConsole::writeError(PDFToolTranslationContext::tr("Invalid voice."), options.outputCodec); PDFConsole::writeError(PDFToolTranslationContext::tr("Invalid voice."), options.outputCodec);
return ErrorSAPI; return ErrorSAPI;
} }
QFileInfo info(options.document); QFileInfo info(options.document);
QString outputFile = QString("%1/%2.mp3").arg(info.path(), info.completeBaseName()); QString outputFile = QString("%1/%2.wav").arg(info.path(), info.completeBaseName());
BSTR outputFileName = (BSTR)outputFile.utf16(); BSTR outputFileName = (BSTR)outputFile.utf16();
ISpeechFileStream* stream = nullptr; ISpeechFileStream* stream = nullptr;
@ -390,15 +407,28 @@ int PDFToolAudioBook::createAudioBook(const PDFToolOptions& options, pdf::PDFDoc
PDFConsole::writeError(PDFToolTranslationContext::tr("Cannot create output stream '%1'.").arg(outputFile), options.outputCodec); PDFConsole::writeError(PDFToolTranslationContext::tr("Cannot create output stream '%1'.").arg(outputFile), options.outputCodec);
return ErrorSAPI; return ErrorSAPI;
} }
if (!SUCCEEDED(stream->Open(outputFileName, SSFMCreateForWrite)))
ISpVoice* voice = nullptr;
if (!SUCCEEDED(::CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, __uuidof(ISpVoice), (LPVOID*)&voice)))
{ {
PDFConsole::writeError(PDFToolTranslationContext::tr("Cannot create output stream '%1'.").arg(outputFile), options.outputCodec); PDFConsole::writeError(PDFToolTranslationContext::tr("Cannot create voice."), options.outputCodec);
stream->Release(); stream->Release();
return ErrorSAPI; return ErrorSAPI;
} }
ISpVoice* voice = voices.front().getVoice(); if (!SUCCEEDED(stream->Open(outputFileName, SSFMCreateForWrite)))
voice->AddRef(); {
PDFConsole::writeError(PDFToolTranslationContext::tr("Cannot create output stream '%1'.").arg(outputFile), options.outputCodec);
voice->Release();
stream->Release();
return ErrorSAPI;
}
ISpObjectToken* voiceToken = voices.front().getVoiceToken();
if (!SUCCEEDED(voice->SetVoice(voiceToken)))
{
PDFConsole::writeError(PDFToolTranslationContext::tr("Failed to set requested voice. Default voice will be used."), options.outputCodec);
}
voices.clear(); voices.clear();
LPCWSTR stringToSpeak = (LPCWSTR)audioString.utf16(); LPCWSTR stringToSpeak = (LPCWSTR)audioString.utf16();

View File

@ -22,7 +22,7 @@
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
struct ISpVoice; struct ISpObjectToken;
namespace pdf namespace pdf
{ {
@ -36,12 +36,12 @@ class PDFVoiceInfo
{ {
public: public:
PDFVoiceInfo() = default; PDFVoiceInfo() = default;
PDFVoiceInfo(std::map<QString, QString> properties, ISpVoice* voice); PDFVoiceInfo(std::map<QString, QString> properties, ISpObjectToken* voiceToken);
PDFVoiceInfo(const PDFVoiceInfo&) = delete; PDFVoiceInfo(const PDFVoiceInfo&) = delete;
PDFVoiceInfo(PDFVoiceInfo&&) = default; PDFVoiceInfo(PDFVoiceInfo&& other);
PDFVoiceInfo& operator=(const PDFVoiceInfo&) = delete; PDFVoiceInfo& operator=(const PDFVoiceInfo&) = delete;
PDFVoiceInfo& operator=(PDFVoiceInfo&&) = default; PDFVoiceInfo& operator=(PDFVoiceInfo&&other);
~PDFVoiceInfo(); ~PDFVoiceInfo();
@ -54,11 +54,11 @@ public:
QLocale getLocale() const; QLocale getLocale() const;
QString getStringValue(QString key) const; QString getStringValue(QString key) const;
ISpVoice* getVoice() const { return m_voice; } ISpObjectToken* getVoiceToken() const { return m_voiceToken; }
private: private:
std::map<QString, QString> m_properties; std::map<QString, QString> m_properties;
ISpVoice* m_voice = nullptr; ISpObjectToken* m_voiceToken = nullptr;
}; };
using PDFVoiceInfoList = std::vector<PDFVoiceInfo>; using PDFVoiceInfoList = std::vector<PDFVoiceInfo>;
@ -69,7 +69,7 @@ public:
PDFToolAudioBookBase() = default; PDFToolAudioBookBase() = default;
protected: protected:
int fillVoices(const PDFToolOptions& options, PDFVoiceInfoList& list, bool fillVoicePointers); int fillVoices(const PDFToolOptions& options, PDFVoiceInfoList& list, bool fillVoiceTokenPointers);
int showVoiceList(const PDFToolOptions& options); int showVoiceList(const PDFToolOptions& options);
}; };