<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: Озвучка текста Text to Speech UWP api Win10]]></title>
	<link rel="self" href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=17651&amp;type=atom" />
	<updated>2023-03-12T01:41:55Z</updated>
	<generator>PunBB</generator>
	<id>http://forum.script-coding.com/viewtopic.php?id=17651</id>
		<entry>
			<title type="html"><![CDATA[AHK: Озвучка текста Text to Speech UWP api Win10]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=157088#p157088" />
			<content type="html"><![CDATA[<p><a href="https://docs.microsoft.com/en-us/uwp/api/windows.media.speechsynthesis?view=winrt-22000">https://docs.microsoft.com/en-us/uwp/ap … inrt-22000</a><br />Список голосов (необходимо установить в windows):<br /><a href="https://support.microsoft.com/en-us/windows/appendix-a-supported-languages-and-voices-4486e345-7730-53da-fcfe-55cc64300f01#WindowsVersion=Windows_10">https://support.microsoft.com/en-us/win … Windows_10</a><br />Можно изменить скорость, тональность, сохранить в файл (файл будет заменен, если он существует) и использовать SSML версии 1.1.<br />Пример ssml:<br /></p><div class="codebox"><pre><code>text=
(%
&lt;speak version=&#039;1.0&#039;
xmlns=&#039;http://www.w3.org/2001/10/synthesis&#039; xml:lang=&#039;en-US&#039;&gt;
Hello &lt;prosody contour=&#039;(0%,+80Hz) (10%,+80%) (40%,+80Hz)&#039;&gt;World&lt;/prosody&gt;
&lt;break time=&#039;500ms&#039; /&gt;
Goodbye &lt;prosody rate=&#039;slow&#039; contour=&#039;(0%,+20Hz) (10%,+30%) (40%,+10Hz)&#039;&gt;World&lt;/prosody&gt;
&lt;/speak&gt;
)</code></pre></div><p>Чтобы получить названия всех доступных голосов, задайте переменную voice как &quot;ShowAvailableVoices&quot;.<br /></p><div class="codebox"><pre><code>#Persistent
#SingleInstance, Force
setbatchlines -1

text := &quot;AutoHotkey Powerful. Easy to learn. The ultimate automation scripting language for Windows.&quot;
voice := &quot;Microsoft Mark&quot;
; voice := &quot;ShowAvailableVoices&quot;   ; uncomment to get names of all available voices
file := A_ScriptDir &quot;\test.wav&quot;   ; file will be replaced if exist! comment if not needed save to file
speed := 1   ; float from 0 till 2
pitch := 1   ; float from 0 till 2
TextToSpeech(text, voice, file, speed, pitch)
return

TextToSpeech(text, voice, file := &quot;&quot;, speed := 1, pitch := 1)
{
   static init, CurrentVoice, Currentspeed, Currentpitch, SpeechSynthesizerActive, SpeechSynthesizer, SpeechSynthesizer2, SpeechSynthesizerOptions, SpeechSynthesizerOptions2, VoicesCount, VoiceInformationList, DataReaderFactory, StorageFileStatics, FileIOStatics, RandomAccessStream, DataReader, pByteStream, pObject, SourceNode, OutputNode, IMFTopology, pISourceResolver, pDescriptor, pPresentationDescriptor, IMFActivate, IMFMediaSource, pMediaSession
   if RandomAccessStream
   {
      ObjReleaseClose(RandomAccessStream)
      ObjReleaseClose(DataReader)
   }
   if pMediaSession
   {
      ObjRelease(pByteStream)
      ObjRelease(pObject)
      ObjRelease(SourceNode)
      ObjRelease(OutputNode)
      ObjRelease(IMFTopology)
      ObjRelease(pISourceResolver)
      ObjRelease(pDescriptor)
      ObjRelease(pPresentationDescriptor)
      DllCall(NumGet(NumGet(IMFActivate+0)+34*A_PtrSize), &quot;ptr&quot;, IMFActivate)   ; IMFActivate::ShutdownObject
      ObjRelease(IMFActivate)
      DllCall(NumGet(NumGet(IMFMediaSource+0)+12*A_PtrSize), &quot;ptr&quot;, IMFMediaSource)   ; IMFMediaSource::Shutdown
      ObjRelease(IMFMediaSource)
      DllCall(NumGet(NumGet(pMediaSession+0)+13*A_PtrSize), &quot;ptr&quot;, pMediaSession)   ; IMFMediaSession::Shutdown
      ObjRelease(pMediaSession)
      pMediaSession := &quot;&quot;
   }
   if !init
   {
      CreateClass(&quot;Windows.Media.SpeechSynthesis.SpeechSynthesizer&quot;,, SpeechSynthesizerActive)
      SpeechSynthesizer := ComObjQuery(SpeechSynthesizerActive, ISpeechSynthesizer := &quot;{CE9F7C76-97F4-4CED-AD68-D51C458E45C6}&quot;)
      SpeechSynthesizer2 := ComObjQuery(SpeechSynthesizerActive, ISpeechSynthesizer2 := &quot;{a7c5ecb2-4339-4d6a-bbf8-c7a4f1544c2e}&quot;)
      DllCall(NumGet(NumGet(SpeechSynthesizer2+0)+6*A_PtrSize), &quot;ptr&quot;, SpeechSynthesizer2, &quot;ptr*&quot;, SpeechSynthesizerOptions)   ; SpeechSynthesizer.get_Options
      SpeechSynthesizerOptions2 := ComObjQuery(SpeechSynthesizerOptions, ISpeechSynthesizerOptions2 := &quot;{1cbef60e-119c-4bed-b118-d250c3a25793}&quot;)
      CreateClass(&quot;Windows.Media.SpeechSynthesis.SpeechSynthesizer&quot;, IInspectable := &quot;{AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90}&quot;, SpeechSynthesizerFactory)
      InstalledVoicesStatic := ComObjQuery(SpeechSynthesizerFactory, IInstalledVoicesStatic := &quot;{7D526ECC-7533-4C3F-85BE-888C2BAEEBDC}&quot;)
      DllCall(NumGet(NumGet(InstalledVoicesStatic+0)+6*A_PtrSize), &quot;ptr&quot;, InstalledVoicesStatic, &quot;ptr*&quot;, VoiceInformationList)   ; InstalledVoicesStatic.get_AllVoices
      DllCall(NumGet(NumGet(VoiceInformationList+0)+7*A_PtrSize), &quot;ptr&quot;, VoiceInformationList, &quot;int*&quot;, VoicesCount)   ; IVectorView.GetSize
      ObjReleaseClose(SpeechSynthesizerFactory)
      ObjReleaseClose(InstalledVoicesStatic)      
      DllCall(&quot;LoadLibrary&quot;, &quot;str&quot;, &quot;Mf.dll&quot;)
      DllCall(&quot;LoadLibrary&quot;, &quot;str&quot;, &quot;Mfplat.dll&quot;)
      DllCall(&quot;Mfplat.dll\MFStartup&quot;, &quot;uint&quot;, 2, &quot;uint&quot;, MFSTARTUP_NOSOCKET := 1)
      init := 1
   }
   if (Currentspeed != speed)
   {
      DllCall(NumGet(NumGet(SpeechSynthesizerOptions2+0)+9*A_PtrSize), &quot;ptr&quot;, SpeechSynthesizerOptions2, &quot;double&quot;, speed)   ; SpeechSynthesizerOptions2.put_SpeakingRate
      Currentspeed := speed
   }
   if (Currentpitch != pitch)
   {
      DllCall(NumGet(NumGet(SpeechSynthesizerOptions2+0)+11*A_PtrSize), &quot;ptr&quot;, SpeechSynthesizerOptions2, &quot;double&quot;, pitch)   ; SpeechSynthesizerOptions2.put_AudioPitch
      Currentpitch := pitch
   }
   if (CurrentVoice != voice)
   {  
      loop % VoicesCount
      {
         DllCall(NumGet(NumGet(VoiceInformationList+0)+6*A_PtrSize), &quot;ptr&quot;, VoiceInformationList, &quot;int&quot;, A_Index - 1, &quot;ptr*&quot;, VoiceInformation)   ; IVectorView.GetAt
         DllCall(NumGet(NumGet(VoiceInformation+0)+6*A_PtrSize), &quot;ptr&quot;, VoiceInformation, &quot;ptr*&quot;, hText)   ; VoiceInformation.get_DisplayName
         buffer := DllCall(&quot;Combase.dll\WindowsGetStringRawBuffer&quot;, &quot;ptr&quot;, hText, &quot;uint*&quot;, length, &quot;ptr&quot;)
         if (voice = &quot;ShowAvailableVoices&quot;)
            AvailableVoices .= StrGet(buffer, &quot;UTF-16&quot;) &quot;`n&quot;
         else if (StrGet(buffer, &quot;UTF-16&quot;) = voice)
         {
            CurrentVoice := voice
            DllCall(NumGet(NumGet(SpeechSynthesizer+0)+8*A_PtrSize), &quot;ptr&quot;, SpeechSynthesizer, &quot;ptr&quot;, VoiceInformation)   ; SpeechSynthesizer.put_Voice
            ObjReleaseClose(VoiceInformation)
            break
         }
         ObjReleaseClose(VoiceInformation)
         if (A_Index = VoicesCount)
         {
            if (voice = &quot;ShowAvailableVoices&quot;)
               msgbox % AvailableVoices
            else
               msgbox No such voice installed
            exitapp
         }
      }
   }
   CreateHString(text, hString)
   if RegexMatch(text, &quot;i)^(&lt;speak|&lt;\?xml)&quot;)
      DllCall(NumGet(NumGet(SpeechSynthesizer+0)+7*A_PtrSize), &quot;ptr&quot;, SpeechSynthesizer, &quot;ptr&quot;, hString, &quot;ptr*&quot;, SpeechSynthesisStream)   ; SpeechSynthesizer.SynthesizeSsmlToStreamAsync
   else
      DllCall(NumGet(NumGet(SpeechSynthesizer+0)+6*A_PtrSize), &quot;ptr&quot;, SpeechSynthesizer, &quot;ptr&quot;, hString, &quot;ptr*&quot;, SpeechSynthesisStream)   ; SpeechSynthesizer.SynthesizeTextToStreamAsync
   WaitForAsync(SpeechSynthesisStream)
   DeleteHString(hString)
   if (file != &quot;&quot;)
   {
      FileDelete, %file%
      FileAppend,, %file%
      RandomAccessStream := ComObjQuery(SpeechSynthesisStream, IRandomAccessStream := &quot;{905A0FE1-BC53-11DF-8C49-001E4FC686DA}&quot;)
      DllCall(NumGet(NumGet(RandomAccessStream+0)+6*A_PtrSize), &quot;ptr&quot;, RandomAccessStream, &quot;uint64*&quot;, size)   ; IRandomAccessStream.get_size
      if !DataReaderFactory
         CreateClass(&quot;Windows.Storage.Streams.DataReader&quot;, IDataReaderFactory := &quot;{D7527847-57DA-4E15-914C-06806699A098}&quot;, DataReaderFactory)
      DllCall(NumGet(NumGet(DataReaderFactory+0)+6*A_PtrSize), &quot;ptr&quot;, DataReaderFactory, &quot;ptr&quot;, SpeechSynthesisStream, &quot;ptr*&quot;, DataReader)   ; DataReaderFactory.CreateDataReader
      DllCall(NumGet(NumGet(DataReader+0)+29*A_PtrSize), &quot;ptr&quot;, DataReader, &quot;uint&quot;, size, &quot;ptr*&quot;, DataReaderLoadOperation)   ; DataReader.LoadAsync
      WaitForAsync(DataReaderLoadOperation)
      DllCall(NumGet(NumGet(DataReader+0)+15*A_PtrSize), &quot;ptr&quot;, DataReader, &quot;uint&quot;, size, &quot;ptr*&quot;, buffer)   ; DataReader.ReadBuffer
      if !StorageFileStatics
         CreateClass(&quot;Windows.Storage.StorageFile&quot;, IStorageFileStatics := &quot;{5984C710-DAF2-43C8-8BB4-A4D3EACFD03F}&quot;, StorageFileStatics)
      CreateHString(file, hString)
      DllCall(NumGet(NumGet(StorageFileStatics+0)+6*A_PtrSize), &quot;ptr&quot;, StorageFileStatics, &quot;ptr&quot;, hString, &quot;ptr*&quot;, StorageFile)   ; StorageFile.GetFileFromPathAsync
      WaitForAsync(StorageFile)
      DeleteHString(hString)
      if !FileIOStatics
         CreateClass(&quot;Windows.Storage.FileIO&quot;, IFileIOStatics := &quot;{887411EB-7F54-4732-A5F0-5E43E3B8C2F5}&quot;, FileIOStatics)
      DllCall(NumGet(NumGet(FileIOStatics+0)+19*A_PtrSize), &quot;ptr&quot;, FileIOStatics, &quot;ptr&quot;, StorageFile, &quot;ptr&quot;, buffer, &quot;ptr*&quot;, AsyncAction)   ; FileIOStatics.WriteBufferAsync
      WaitForAsync(AsyncAction)
      ObjReleaseClose(buffer)
      ObjReleaseClose(StorageFile)
   }
   DllCall(&quot;Mf.dll\MFCreateMediaSession&quot;, &quot;ptr&quot;, 0, &quot;ptr*&quot;, pMediaSession)
   DllCall(&quot;Mfplat.dll\MFCreateSourceResolver&quot;, &quot;ptr*&quot;, pISourceResolver)
   DllCall(&quot;Mfplat.dll\MFCreateMFByteStreamOnStreamEx&quot;, &quot;ptr&quot;, SpeechSynthesisStream, &quot;ptr*&quot;, pByteStream)
   DllCall(NumGet(NumGet(pISourceResolver+0)+4*A_PtrSize), &quot;ptr&quot;, pISourceResolver, &quot;ptr&quot;, pByteStream, &quot;ptr&quot;, 0, &quot;uint&quot;, MF_RESOLUTION_MEDIASOURCE := 1, &quot;ptr&quot;, 0, &quot;uint*&quot;, pObjectType, &quot;ptr*&quot;, pObject)   ; IMFSourceResolver::CreateObjectFromByteStream
   IMFMediaSource := ComObjQuery(pObject, IID_IMFMediaSource := &quot;{279A808D-AEC7-40C8-9C6B-A6B492C78A66}&quot;)
   DllCall(NumGet(NumGet(IMFMediaSource+0)+8*A_PtrSize), &quot;ptr&quot;, IMFMediaSource, &quot;ptr*&quot;, pPresentationDescriptor)   ; IMFMediaSource::CreatePresentationDescriptor
   DllCall(NumGet(NumGet(pPresentationDescriptor+0)+34*A_PtrSize), &quot;ptr&quot;, pPresentationDescriptor, &quot;uint&quot;, 0, &quot;uint*&quot;, fSelected, &quot;ptr*&quot;, pDescriptor)   ; IMFPresentationDescriptor::GetStreamDescriptorByIndex
   DllCall(&quot;Mf.dll\MFCreateTopologyNode&quot;, &quot;uint&quot;, MF_TOPOLOGY_SOURCESTREAM_NODE := 1, &quot;ptr*&quot;, SourceNode)
   VarSetCapacity(GUID, 16)
   DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;wstr&quot;, MF_TOPONODE_SOURCE := &quot;{835C58EC-E075-4BC7-BCBA-4DE000DF9AE6}&quot;, &quot;ptr&quot;, &amp;GUID)
   DllCall(NumGet(NumGet(SourceNode+0)+27*A_PtrSize), &quot;ptr&quot;, SourceNode, &quot;ptr&quot;, &amp;GUID, &quot;ptr&quot;, IMFMediaSource)   ; IMFAttributes::SetUnknown
   VarSetCapacity(GUID, 16)
   DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;wstr&quot;, MF_TOPONODE_PRESENTATION_DESCRIPTOR := &quot;{835C58ED-E075-4BC7-BCBA-4DE000DF9AE6}&quot;, &quot;ptr&quot;, &amp;GUID)
   DllCall(NumGet(NumGet(SourceNode+0)+27*A_PtrSize), &quot;ptr&quot;, SourceNode, &quot;ptr&quot;, &amp;GUID, &quot;ptr&quot;, pPresentationDescriptor)   ; IMFAttributes::SetUnknown
   VarSetCapacity(GUID, 16)
   DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;wstr&quot;, MF_TOPONODE_STREAM_DESCRIPTOR := &quot;{835C58EE-E075-4BC7-BCBA-4DE000DF9AE6}&quot;, &quot;ptr&quot;, &amp;GUID)
   DllCall(NumGet(NumGet(SourceNode+0)+27*A_PtrSize), &quot;ptr&quot;, SourceNode, &quot;ptr&quot;, &amp;GUID, &quot;ptr&quot;, pDescriptor)   ; IMFAttributes::SetUnknown
   DllCall(&quot;Mf.dll\MFCreateAudioRendererActivate&quot;, &quot;ptr*&quot;, IMFActivate)
   DllCall(&quot;Mf.dll\MFCreateTopologyNode&quot;, &quot;uint&quot;, MF_TOPOLOGY_OUTPUT_NODE := 0, &quot;ptr*&quot;, OutputNode)
   DllCall(NumGet(NumGet(OutputNode+0)+33*A_PtrSize), &quot;ptr&quot;, OutputNode, &quot;ptr&quot;, IMFActivate)   ; IMFTopologyNode::SetObject
   DllCall(NumGet(NumGet(SourceNode+0)+40*A_PtrSize), &quot;ptr&quot;, SourceNode, &quot;uint&quot;, 0, &quot;ptr&quot;, OutputNode, &quot;uint&quot;, 0)   ; IMFTopologyNode::ConnectOutput
   DllCall(&quot;Mf.dll\MFCreateTopology&quot;, &quot;ptr*&quot;, IMFTopology)
   DllCall(NumGet(NumGet(IMFTopology+0)+34*A_PtrSize), &quot;ptr&quot;, IMFTopology, &quot;ptr&quot;, SourceNode)   ; IMFTopology::AddNode
   DllCall(NumGet(NumGet(IMFTopology+0)+34*A_PtrSize), &quot;ptr&quot;, IMFTopology, &quot;ptr&quot;, OutputNode)   ; IMFTopology::AddNode
   DllCall(NumGet(NumGet(pMediaSession+0)+7*A_PtrSize), &quot;ptr&quot;, pMediaSession, &quot;uint&quot;, 0, &quot;ptr&quot;, IMFTopology)   ; IMFMediaSession::SetTopology
   DllCall(NumGet(NumGet(pMediaSession+0)+9*A_PtrSize), &quot;ptr&quot;, pMediaSession, &quot;ptr&quot;, 0, &quot;ptr&quot;, &amp;(PROPVARIANT:=0))   ; IMFMediaSession::Start
   return
}

CreateClass(string, interface := &quot;&quot;, ByRef Class := &quot;&quot;)
{
   CreateHString(string, hString)
   if (interface = &quot;&quot;)
      result := DllCall(&quot;Combase.dll\RoActivateInstance&quot;, &quot;ptr&quot;, hString, &quot;ptr*&quot;, Class, &quot;uint&quot;)
   else
   {
      VarSetCapacity(GUID, 16)
      DllCall(&quot;ole32\CLSIDFromString&quot;, &quot;wstr&quot;, interface, &quot;ptr&quot;, &amp;GUID)
      result := DllCall(&quot;Combase.dll\RoGetActivationFactory&quot;, &quot;ptr&quot;, hString, &quot;ptr&quot;, &amp;GUID, &quot;ptr*&quot;, Class, &quot;uint&quot;)
   }
   if (result != 0)
   {
      if (result = 0x80004002)
         msgbox No such interface supported
      else if (result = 0x80040154)
         msgbox Class not registered
      else
         msgbox error: %result%
      ExitApp
   }
   DeleteHString(hString)
}

CreateHString(string, ByRef hString)
{
    DllCall(&quot;Combase.dll\WindowsCreateString&quot;, &quot;wstr&quot;, string, &quot;uint&quot;, StrLen(string), &quot;ptr*&quot;, hString)
}

DeleteHString(hString)
{
   DllCall(&quot;Combase.dll\WindowsDeleteString&quot;, &quot;ptr&quot;, hString)
}

WaitForAsync(ByRef Object)
{
   AsyncInfo := ComObjQuery(Object, IAsyncInfo := &quot;{00000036-0000-0000-C000-000000000046}&quot;)
   loop
   {
      DllCall(NumGet(NumGet(AsyncInfo+0)+7*A_PtrSize), &quot;ptr&quot;, AsyncInfo, &quot;uint*&quot;, status)   ; IAsyncInfo.Status
      if (status != 0)
      {
         if (status != 1)
         {
            DllCall(NumGet(NumGet(AsyncInfo+0)+8*A_PtrSize), &quot;ptr&quot;, AsyncInfo, &quot;uint*&quot;, ErrorCode)   ; IAsyncInfo.ErrorCode
            msgbox AsyncInfo status error: %ErrorCode%
            ExitApp
         }
         ObjRelease(AsyncInfo)
         break
      }
      sleep 10
   }
   DllCall(NumGet(NumGet(Object+0)+8*A_PtrSize), &quot;ptr&quot;, Object, &quot;ptr*&quot;, ObjectResult)   ; GetResults
   ObjReleaseClose(Object)
   Object := ObjectResult
}

ObjReleaseClose(ByRef Object)
{
   if Object
   {
      if (Close := ComObjQuery(Object, IClosable := &quot;{30D5A829-7FA4-4026-83BB-D75BAE4EA99E}&quot;))
      {
         DllCall(NumGet(NumGet(Close+0)+6*A_PtrSize), &quot;ptr&quot;, Close)   ; Close
         ObjRelease(Close)
      }
      ObjRelease(Object)
   }
   Object := &quot;&quot;
}</code></pre></div><p><a href="http://forum.script-coding.com/viewtopic.php?id=16796">Тема для обсуждения</a></p>]]></content>
			<author>
				<name><![CDATA[Malcev]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=26930</uri>
			</author>
			<updated>2023-03-12T01:41:55Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=157088#p157088</id>
		</entry>
</feed>
