Создание UWP DLL с использованием Windows :: Media :: SpeechSynthesis - PullRequest
0 голосов
/ 11 июня 2019

В настоящее время я пытаюсь разработать UWP DLL для синтеза речи, используя пространство имен Windows :: Media :: SpeechSynthesis.Я прочитал эту документацию и страницу Microsoft , посвященную пространству имен.Я пытался реализовать пространство имен в коде.

Заголовочный файл

#pragma once

#include <stdio.h>
#include <string>
#include <iostream>
#include <ppltasks.h>

using namespace Windows::Media::SpeechSynthesis;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::Media::Playback;

namespace SDKTemplate
{
    class TextToSpeechDll
    {
        public:
           __declspec( dllexport ) void ttsInitialize();

        private:
           MediaElement ^media;
    };
}

Cpp файл

#include "stdafx.h"
#include "Dll2.h"

using namespace SDKTemplate;
using namespace Platform;
using namespace Concurrency;

void TextToSpeechDll::ttsInitialize()
{
    SpeechSynthesizer ^synth = ref new SpeechSynthesizer();
    // The object for controlling the speech synthesis engine (voice).
    synth = ref new SpeechSynthesizer();
    // The string to speak.
    String^ text = "Hello World";

    // Generate the audio stream from plain text.
    task<SpeechSynthesisStream ^> speakTask = create_task( synth->SynthesizeTextToStreamAsync( text ) );
    speakTask.then( [this, text]( task<SpeechSynthesisStream^> synthesisStreamTask )
    {
        SpeechSynthesisStream ^speechStream = synthesisStreamTask.get();
        // Send the stream to the media object.
        // media === MediaElement XAML object.
        media->AutoPlay = true;
        media->SetSource( speechStream, speechStream->ContentType );
        media->Play();
    } );
}

Я могу загрузить файл DLL и функцию Iэкспорт.Однако, когда я пытаюсь вызвать функцию, я получаю следующую ошибку

Error message

Я попробовал пример на странице Microsoft , ноЭто как-то не работает, и я не могу понять, почему.Я также протестировал универсальные образцы Windows, доступные на Github , который представляет собой приложение UWP, перегруппировывающее распознавание текста в речь и распознавание речи.

Кто-то испытывал подобную проблему?Разве я не должен использовать элемент XAML, когда у меня нет интерфейса?


Редактировать 1

Я изменил файл заголовка относительноэкспорт функции в соответствии с предложением @ Peter Torr - MSFT

#pragma once

#include <stdio.h>
#include <string>
#include <iostream>
#include <ppltasks.h>

using namespace Windows::Media::SpeechSynthesis;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::Media::Playback;

namespace SDKTemplate
{
   public ref class TextToSpeechDll sealed
   {
      public:
         void ttsInitialize();

      private:
         MediaElement ^media = ref new MediaElement();
   };
}

Однако при компиляции я получаю новую ошибку в этой строке

speakTask.then( [this]( task<SpeechSynthesisStream^> synthesisStreamTask )

Error Message

Я исследовал эту ошибку, и если я правильно ее понял, то это связано с импортом функции DLL.

Кроме того, я вызываю функциюкак это

_ttsUwpDll->ttsInitialize();

Что приводит нас сюда

void NxWindowsTtsUwpDll::ttsInitialize()
{
   int retVal = 0;
   try
   {
      retVal = _ttsInitialize();
   }
   catch( ... )
   {
      printf( "Exception in ttsInitialize\n" );
   }
   //return retVal;
}

Ответы [ 2 ]

0 голосов
/ 09 июля 2019

Я нашел ответ на свой вопрос.Вместо использования MediaElement я использовал MediaPlayer.Сейчас это работает, но мне все еще нужно понять, как заставить двигатель говорить, не ограничивая его во времени.Sleep( 3000 ) означает, что голос будет говорить в течение 3 секунд.Однако, если предложение длиннее 3 секунд, оно будет обрезано.Вот код программы.

int TextToSpeechUwpDll::ttsSpeak( const char* text )
{
   SpeechSynthesizer ^speak = ref new SpeechSynthesizer();
   MediaPlayer ^player = ref new MediaPlayer;

   int wchars_num = MultiByteToWideChar( CP_ACP, 0, text, -1, NULL, 0 );
   wchar_t* texts = new wchar_t[wchars_num];
   MultiByteToWideChar( CP_ACP, 0, text, -1, texts, wchars_num );
   String ^sentence = ref new String( texts );

   task<SpeechSynthesisStream ^> speakTask = create_task( speak->SynthesizeTextToStreamAsync( sentence ) );
   speakTask.then( [player, sentence]( SpeechSynthesisStream ^speechStream )
   {
      player->Source = MediaSource::CreateFromStream( speechStream, speechStream->ContentType );
      player->AutoPlay = false;
      player->Play();
      Sleep( 3000 );
   } );

   return true;
}
0 голосов
/ 13 июня 2019

В MainPage я инициализирую файл dll и вызываю функцию "ttsInitialize", как показано ниже:

MainPage::MainPage()
{
 InitializeComponent();
 TextToSpeechDll* gf = new TextToSpeechDll();
 gf->ttsInitialize();
}

И в файле Dll.h я инициализирую MediaElement, как показано ниже, и другой код, такой же, какyou.

MediaElement^ media = ref new MediaElement();

Когда я запускаю проект, он работает.Вы можете попробовать это, и если у вас все еще есть проблемы, пожалуйста, покажите детали, которые вы инициализируете файл DLL.

...