add speech2 stuff
This commit is contained in:
parent
fe9a8af8c2
commit
20f59c5663
51 changed files with 55999 additions and 436 deletions
44
.clang-format
Executable file
44
.clang-format
Executable file
|
@ -0,0 +1,44 @@
|
|||
BasedOnStyle: Google
|
||||
|
||||
# force T* or T&
|
||||
DerivePointerAlignment: false
|
||||
PointerAlignment: Left
|
||||
|
||||
TabWidth: 4
|
||||
IndentWidth: 4
|
||||
UseTab: Always
|
||||
IndentPPDirectives: BeforeHash
|
||||
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: InlineOnly
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: true
|
||||
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakStringLiterals: false
|
||||
|
||||
ColumnLimit: 150
|
||||
CompactNamespaces: false
|
||||
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ContinuationIndentWidth: 0
|
||||
|
||||
# turning this on causes major issues with initializer lists
|
||||
Cpp11BracedListStyle: false
|
||||
SpaceBeforeCpp11BracedList: true
|
||||
|
||||
FixNamespaceComments: true
|
||||
|
||||
NamespaceIndentation: All
|
||||
ReflowComments: true
|
||||
|
||||
SortIncludes: CaseInsensitive
|
||||
SortUsingDeclarations: true
|
||||
|
||||
SpacesInSquareBrackets: false
|
||||
SpaceBeforeParens: Never
|
||||
SpacesBeforeTrailingComments: 1
|
11
.editorconfig
Normal file
11
.editorconfig
Normal file
|
@ -0,0 +1,11 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
# specifically for YAML
|
||||
[{yml, yaml}]
|
||||
indent_style = space
|
368
.gitignore
vendored
368
.gitignore
vendored
|
@ -1,363 +1,7 @@
|
|||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
# ccls/clangd
|
||||
.cache/
|
||||
**/bin/
|
||||
**/obj/
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
# on your own machine, please.
|
||||
/speech2/compile_commands.json
|
||||
|
|
7
Justfile
Normal file
7
Justfile
Normal file
|
@ -0,0 +1,7 @@
|
|||
build:
|
||||
dotnet build
|
||||
make -C speech2 -j$(nproc)
|
||||
|
||||
clean:
|
||||
rm -rf SAPIServer/bin SAPIServer/obj
|
||||
make -C speech2 clean
|
10
README.md
10
README.md
|
@ -2,6 +2,14 @@
|
|||
|
||||
Simple HTTP frontend API for Microsoft Speech API
|
||||
|
||||
## Building
|
||||
|
||||
Requirements
|
||||
- .NET SDK
|
||||
- mingw-w64 toolchain built with `win32` thread model (`pthread` won't work)
|
||||
|
||||
`just` should do the trick.
|
||||
|
||||
## Running
|
||||
|
||||
```
|
||||
|
@ -27,4 +35,4 @@ Content-Type: application/json
|
|||
{"text":"Lorem ipsum doler sit amet...","voice":"Microsoft Sam"}
|
||||
```
|
||||
|
||||
Returns synthesized TTS audio as a wave-form file.
|
||||
Returns synthesized TTS audio as a wave-form file.
|
||||
|
|
|
@ -1,58 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{BF824074-4C4E-4DE1-8DCA-F022682B00E1}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>SAPIServer</RootNamespace>
|
||||
<AssemblyName>SAPIServer</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<!-- Older VS generated one for us; we're just using that one.
|
||||
Unless we wanna use the generated one?? -->
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net40</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Speech" />
|
||||
|
@ -62,23 +19,5 @@
|
|||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="HTTPServer.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SynthesizePayload.cs" />
|
||||
<Compile Include="VoicesResponse.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.manifest" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
|
||||
</Project>
|
||||
|
|
84
SAPIServer/SAPIServer.vs.csproj
Normal file
84
SAPIServer/SAPIServer.vs.csproj
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{BF824074-4C4E-4DE1-8DCA-F022682B00E1}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>SAPIServer</RootNamespace>
|
||||
<AssemblyName>SAPIServer</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Speech" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="HTTPServer.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SynthesizePayload.cs" />
|
||||
<Compile Include="VoicesResponse.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.manifest" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
36
speech2/Makefile
Normal file
36
speech2/Makefile
Normal file
|
@ -0,0 +1,36 @@
|
|||
include build/arch.mk
|
||||
include build/configs.mk
|
||||
|
||||
NAME = sapiserver
|
||||
|
||||
BINDIR = bin/$(ARCH)/$(CONFIG)
|
||||
OBJDIR = obj/$(ARCH)/$(CONFIG)
|
||||
|
||||
# Any C++ file in src/ is automatically picked up.
|
||||
CXXSRCS = $(wildcard src/*.cpp) $(wildcard src/*/*.cpp)
|
||||
VPATH = $(dir $(CXXSRCS))
|
||||
OBJS = $(addprefix $(OBJDIR)/,$(notdir $(CXXSRCS:.cpp=.o)))
|
||||
|
||||
.PHONY: all dumpinfo clean matrix
|
||||
|
||||
all: $(BINDIR)/$(NAME).exe
|
||||
|
||||
# dir rules
|
||||
$(BINDIR)/:
|
||||
echo -e "\e[95mMKDIR $@\e[0m"
|
||||
mkdir -p $(BINDIR)
|
||||
|
||||
$(OBJDIR)/:
|
||||
echo -e "\e[95mMKDIR $@\e[0m"
|
||||
mkdir -p $(OBJDIR)
|
||||
|
||||
include build/rules.mk
|
||||
|
||||
clean:
|
||||
echo -e "\e[91mCleaning... \e[0m"
|
||||
rm -rf $(BINDIR)/ $(OBJS)
|
||||
|
||||
$V.SILENT:
|
||||
|
||||
# Include dependency files.
|
||||
-include $(OBJS:.o=.d)
|
3
speech2/README.md
Normal file
3
speech2/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# speech2
|
||||
|
||||
speech dll thing
|
19
speech2/build/arch.mk
Normal file
19
speech2/build/arch.mk
Normal file
|
@ -0,0 +1,19 @@
|
|||
x86_Valid=yes
|
||||
x86_TRIPLET=i686-w64-mingw32
|
||||
|
||||
#x64_Valid=yes
|
||||
#x64_TRIPLET=x86_64-w64-mingw32
|
||||
|
||||
|
||||
ifeq ($(ARCH),)
|
||||
ARCH = x86
|
||||
endif
|
||||
|
||||
ifneq ($($(ARCH)_Valid),yes)
|
||||
$(error Please select a valid target)
|
||||
endif
|
||||
|
||||
# if we really need C
|
||||
CC = $($(ARCH)_TRIPLET)-gcc
|
||||
CXX = $($(ARCH)_TRIPLET)-g++
|
||||
WINDRES = $($(ARCH)_TRIPLET)-windres
|
23
speech2/build/configs.mk
Normal file
23
speech2/build/configs.mk
Normal file
|
@ -0,0 +1,23 @@
|
|||
# Base compiler flags. Only change if you *explicitly* know what you're doing.
|
||||
BASE_CCFLAGS = -MMD -std=gnu17 -fpermissive -fno-pic -fno-pie -msse -Iinclude -Isrc -D_UCRT -D_WIN32_WINNT=0x0501
|
||||
BASE_CXXFLAGS = -MMD -std=c++20 -fpermissive -fno-pic -fno-pie -fno-rtti -msse -Iinclude -Isrc -Ithird_party -D_UCRT -D_WIN32_WINNT=0x0501
|
||||
BASE_LDFLAGS = -mwindows -static -static-libgcc -lkernel32 -lshell32 -luser32 -luuid -lole32
|
||||
|
||||
Release_Valid = yes
|
||||
Release_CCFLAGS = -O3 -ffast-math -fomit-frame-pointer -DNDEBUG
|
||||
Release_CXXFLAGS = -O3 -ffast-math -fomit-frame-pointer -DNDEBUG
|
||||
Release_LDFLAGS = -s
|
||||
|
||||
Debug_Valid = yes
|
||||
Debug_CCFLAGS = -O0 -g -DDEBUG
|
||||
Debug_CXXFLAGS = -O0 -g -DDEBUG
|
||||
Debug_LDFLAGS =
|
||||
|
||||
# select a default configuration or validate configuration
|
||||
ifeq ($(CONFIG),)
|
||||
CONFIG = Release
|
||||
endif
|
||||
|
||||
ifneq ($($(CONFIG)_Valid),yes)
|
||||
$(error Please select a valid configuration)
|
||||
endif
|
20
speech2/build/rules.mk
Normal file
20
speech2/build/rules.mk
Normal file
|
@ -0,0 +1,20 @@
|
|||
# TODO: Link DLL
|
||||
$(BINDIR)/$(NAME).exe: $(BINDIR)/ $(OBJDIR)/ $(OBJS)
|
||||
echo -e "\e[92mLinking binary $@\e[0m"
|
||||
$(CXX) $(OBJS) $(BASE_LDFLAGS) $($(CONFIG)_LDFLAGS) -o $@
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
echo -e "\e[94mCompiling C source file $< ($@)\e[0m"
|
||||
$(CC) -c $(BASE_CCFLAGS) $($(CONFIG)_CCFLAGS) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o: %.cpp
|
||||
echo -e "\e[94mCompiling C++ source file $< ($@)\e[0m"
|
||||
$(CC) -c $(BASE_CXXFLAGS) $($(CONFIG)_CXXFLAGS) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o: %.S
|
||||
echo -e "\e[94mAssembling $< ($@)\e[0m"
|
||||
$(CC) -xassembler-with-cpp -c $(BASE_CCFLAGS) $($(CONFIG)_CCFLAGS) $< -o $@
|
||||
|
||||
$(OBJDIR)/%.o: %.rc
|
||||
echo -e "\e[94mCompiling Windows resource script $<\e[0m"
|
||||
$(WINDRES) -Iinclude $< -o $@
|
2
speech2/compdb.sh
Executable file
2
speech2/compdb.sh
Executable file
|
@ -0,0 +1,2 @@
|
|||
make clean
|
||||
bear -- make
|
156
speech2/src/base/BCondVar.cpp
Normal file
156
speech2/src/base/BCondVar.cpp
Normal file
|
@ -0,0 +1,156 @@
|
|||
#include <handleapi.h>
|
||||
#include <synchapi.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <base/BThread.hpp>
|
||||
|
||||
namespace base::osdep {
|
||||
|
||||
enum class MemoryOrder {
|
||||
Relaxed = __ATOMIC_RELAXED,
|
||||
Consume = __ATOMIC_CONSUME,
|
||||
Acquire = __ATOMIC_ACQUIRE,
|
||||
Release = __ATOMIC_RELEASE,
|
||||
AcqRel = __ATOMIC_ACQ_REL,
|
||||
SeqCst = __ATOMIC_SEQ_CST
|
||||
};
|
||||
|
||||
// TODO: public!
|
||||
template<class T, MemoryOrder DefaultOrder = MemoryOrder::SeqCst>
|
||||
struct BAtomic {
|
||||
BAtomic() = default;
|
||||
BAtomic(const T value) :
|
||||
value(value) {
|
||||
|
||||
}
|
||||
|
||||
inline T fetch_add(T val, MemoryOrder order = DefaultOrder) volatile noexcept {
|
||||
return __atomic_fetch_add(&value, val, static_cast<int>(order));
|
||||
}
|
||||
|
||||
inline T fetch_sub(T val, MemoryOrder order = DefaultOrder) volatile noexcept {
|
||||
volatile T* ptr = &value;
|
||||
return __atomic_fetch_sub(ptr, val, static_cast<int>(order));
|
||||
}
|
||||
|
||||
void store(T desiredValue, MemoryOrder order = DefaultOrder) volatile noexcept {
|
||||
__atomic_store_n(&value, desiredValue, order);
|
||||
}
|
||||
|
||||
T operator++() volatile noexcept {
|
||||
return fetch_add(1) + 1;
|
||||
}
|
||||
|
||||
T operator++(int) volatile noexcept {
|
||||
return fetch_add(1);
|
||||
}
|
||||
|
||||
T operator--() volatile noexcept {
|
||||
return fetch_sub(1) - 1;
|
||||
}
|
||||
|
||||
T operator--(int) volatile noexcept {
|
||||
return fetch_sub(1);
|
||||
}
|
||||
|
||||
T operator-=(T val) volatile noexcept {
|
||||
return fetch_sub(val) - val;
|
||||
}
|
||||
|
||||
T operator+=(T val) volatile noexcept{
|
||||
return fetch_add(val) + val;
|
||||
}
|
||||
private:
|
||||
T value;
|
||||
};
|
||||
|
||||
struct BCondVar {
|
||||
BCondVar() {
|
||||
hNotifyAllEvent = CreateEventA(nullptr, TRUE, FALSE, nullptr);
|
||||
hNotifyOneEvent = CreateEventA(nullptr, FALSE, FALSE, nullptr);
|
||||
|
||||
waiterMutex = BMutex_Create(true);
|
||||
}
|
||||
|
||||
~BCondVar() {
|
||||
if(hNotifyAllEvent != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(hNotifyAllEvent);
|
||||
if(hNotifyOneEvent != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(hNotifyOneEvent);
|
||||
|
||||
BMutex_Destroy(waiterMutex);
|
||||
}
|
||||
|
||||
void SignalOne() {
|
||||
SetEvent(hNotifyOneEvent);
|
||||
}
|
||||
|
||||
void SignalAll() {
|
||||
SetEvent(hNotifyAllEvent);
|
||||
}
|
||||
|
||||
void Wait(bool(*predicate)(void* ctx), void* ctx) {
|
||||
HANDLE handles[2] = { hNotifyAllEvent, hNotifyOneEvent };
|
||||
|
||||
BMutex_Lock(waiterMutex);
|
||||
waiterSemaphore++;
|
||||
BMutex_Unlock(waiterMutex);
|
||||
|
||||
while(!predicate(ctx)) {
|
||||
switch(WaitForMultipleObjects(2, &handles[0], FALSE, INFINITE)) {
|
||||
|
||||
case WAIT_OBJECT_0: // hNotifyAllEvent
|
||||
BMutex_Lock(waiterMutex);
|
||||
if(waiterSemaphore-- == 0) {
|
||||
ResetEvent(hNotifyAllEvent);
|
||||
}
|
||||
BMutex_Unlock(waiterMutex);
|
||||
break;
|
||||
|
||||
case WAIT_OBJECT_0 + 1: // hNotifyOneEvent
|
||||
continue;
|
||||
break;
|
||||
|
||||
case WAIT_FAILED:
|
||||
return;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE hNotifyAllEvent{};
|
||||
HANDLE hNotifyOneEvent{};
|
||||
|
||||
// Semaphore for SignalAll().
|
||||
BMutex* waiterMutex;
|
||||
BAtomic<int> waiterSemaphore{0};
|
||||
};
|
||||
|
||||
BCondVar* BCondVar_Create() {
|
||||
return new BCondVar();
|
||||
}
|
||||
|
||||
/// Signals one thread.
|
||||
void BCondVar_SignalOne(BCondVar* cond) {
|
||||
cond->SignalOne();
|
||||
}
|
||||
|
||||
// Signals all threads.
|
||||
void BCondVar_SignalAll(BCondVar* cond) {
|
||||
cond->SignalAll();
|
||||
}
|
||||
|
||||
|
||||
// Waits. Call this on all threads.
|
||||
void BCondVar_Wait(BCondVar* condvar, bool(*predicate)(void* ctx), void* ctx) {
|
||||
condvar->Wait(predicate, ctx);
|
||||
}
|
||||
|
||||
void BCondVar_Destroy(BCondVar* condvar) {
|
||||
delete condvar;
|
||||
}
|
||||
}
|
53
speech2/src/base/BMutex.cpp
Normal file
53
speech2/src/base/BMutex.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
#include <base/BThread.hpp>
|
||||
#include <cassert>
|
||||
|
||||
namespace base::osdep {
|
||||
|
||||
struct BMutex {
|
||||
CRITICAL_SECTION critSec {};
|
||||
bool recursive{};
|
||||
|
||||
BMutex(bool recursive = false) : recursive(recursive) { InitializeCriticalSection(&critSec); }
|
||||
|
||||
~BMutex() {
|
||||
if(critSec.LockCount != 0)
|
||||
Unlock();
|
||||
|
||||
DeleteCriticalSection(&critSec);
|
||||
}
|
||||
|
||||
inline void Lock() {
|
||||
|
||||
// recursive lock check
|
||||
if(!recursive) {
|
||||
if(critSec.LockCount + 1 > 1) {
|
||||
ExitProcess(0x69420);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
EnterCriticalSection(&critSec);
|
||||
}
|
||||
|
||||
inline void Unlock() { LeaveCriticalSection(&critSec); }
|
||||
};
|
||||
|
||||
BMutex* BMutex_Create(bool recursive) {
|
||||
return new BMutex(recursive);
|
||||
}
|
||||
|
||||
void BMutex_Destroy(BMutex* mutex) {
|
||||
delete mutex;
|
||||
}
|
||||
|
||||
void BMutex_Lock(BMutex* mutex) {
|
||||
if(mutex)
|
||||
mutex->Lock();
|
||||
}
|
||||
|
||||
void BMutex_Unlock(BMutex* mutex) {
|
||||
if(mutex)
|
||||
mutex->Unlock();
|
||||
}
|
||||
|
||||
} // namespace base::osdep
|
38
speech2/src/base/BThread.cpp
Normal file
38
speech2/src/base/BThread.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include <process.h>
|
||||
#include <base/BThread.hpp>
|
||||
|
||||
namespace base::osdep {
|
||||
|
||||
struct BThread {
|
||||
HANDLE hThread;
|
||||
unsigned dwId;
|
||||
};
|
||||
|
||||
BThreadHandle BThread_Spawn(BThreadFunc ep, void* arg, unsigned stackSize) {
|
||||
unsigned dwID{};
|
||||
auto res = _beginthreadex(nullptr, stackSize, static_cast<_beginthreadex_proc_type>(ep), arg, 0, &dwID);
|
||||
|
||||
if(res == -1)
|
||||
return nullptr;
|
||||
|
||||
auto handle = new BThread();
|
||||
handle->hThread = reinterpret_cast<HANDLE>(res);
|
||||
handle->dwId = dwID;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
unsigned BThread_GetID(BThreadHandle handle) {
|
||||
if(handle)
|
||||
return handle->dwId;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void BThread_Join(BThreadHandle handle) {
|
||||
if(handle) {
|
||||
auto res = WaitForSingleObject(handle->hThread, INFINITE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} // namespace base::osdep
|
64
speech2/src/base/BThread.hpp
Normal file
64
speech2/src/base/BThread.hpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
// BThread - it's like GThread, but mentally sane!
|
||||
// (and without __, pthreads, and other smells.)
|
||||
#pragma once
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <base/SaneWin.hpp>
|
||||
#else
|
||||
#error BThread only supports Windows.
|
||||
#endif
|
||||
|
||||
namespace base::osdep {
|
||||
|
||||
// Threads
|
||||
|
||||
struct BThread;
|
||||
|
||||
using BThreadHandle = BThread*;
|
||||
|
||||
#ifdef _WIN32
|
||||
using BThreadNativeHandle = HANDLE;
|
||||
#endif
|
||||
|
||||
using BThreadFunc =
|
||||
unsigned WINAPI (*)(void* argp);
|
||||
|
||||
// Spawns a new thread, with the given entry point, argument, and stack size.
|
||||
BThreadHandle BThread_Spawn(BThreadFunc ep, void* arg = nullptr, unsigned stackSize = 0);
|
||||
|
||||
// TODO BThread_Native(BThreadHandle handle)
|
||||
|
||||
unsigned BThread_GetID(BThreadHandle handle);
|
||||
|
||||
// Joins (waits for this thread to terminate) this thread.
|
||||
void BThread_Join(BThreadHandle handle);
|
||||
|
||||
// Mutexes
|
||||
|
||||
struct BMutex;
|
||||
|
||||
// if recursive is true, this BMutex will be a recursive mutex,
|
||||
// and multiple threads are allowed to lock it.
|
||||
BMutex* BMutex_Create(bool recursive);
|
||||
|
||||
void BMutex_Lock(BMutex* mutex);
|
||||
void BMutex_Unlock(BMutex* mutex);
|
||||
|
||||
void BMutex_Destroy(BMutex* mutex);
|
||||
|
||||
struct BCondVar;
|
||||
|
||||
BCondVar* BCondVar_Create();
|
||||
|
||||
/// Signals one thread.
|
||||
void BCondVar_SignalOne(BCondVar* cond);
|
||||
|
||||
// Signals all threads.
|
||||
void BCondVar_SignalAll(BCondVar* cond);
|
||||
|
||||
|
||||
// Waits. Call this on all threads.
|
||||
void BCondVar_Wait(BCondVar* condvar, bool(*predicate)(void* ctx), void* ctx);
|
||||
|
||||
void BCondVar_Destroy(BCondVar* condvar);
|
||||
}
|
21
speech2/src/base/Mutex.cpp
Normal file
21
speech2/src/base/Mutex.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include <base/Mutex.hpp>
|
||||
|
||||
namespace base {
|
||||
|
||||
Mutex::Mutex() {
|
||||
mutex = osdep::BMutex_Create(false);
|
||||
}
|
||||
|
||||
Mutex::~Mutex() {
|
||||
osdep::BMutex_Destroy(mutex);
|
||||
}
|
||||
|
||||
void Mutex::Lock() {
|
||||
osdep::BMutex_Lock(mutex);
|
||||
}
|
||||
|
||||
void Mutex::Unlock() {
|
||||
osdep::BMutex_Unlock(mutex);
|
||||
}
|
||||
|
||||
} // namespace base
|
47
speech2/src/base/Mutex.hpp
Normal file
47
speech2/src/base/Mutex.hpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
#pragma once
|
||||
#include <base/BThread.hpp>
|
||||
|
||||
namespace base {
|
||||
|
||||
/**
|
||||
* A mutex.
|
||||
*/
|
||||
struct Mutex {
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
Mutex(const Mutex&) = delete;
|
||||
Mutex(Mutex&&) = default;
|
||||
|
||||
void Lock();
|
||||
void Unlock();
|
||||
|
||||
// impl data.
|
||||
private:
|
||||
osdep::BMutex* mutex;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
concept Lockable = requires(T t) {
|
||||
{ t.Lock() };
|
||||
{ t.Unlock() };
|
||||
};
|
||||
|
||||
/**
|
||||
* Scoped lock guard.
|
||||
*/
|
||||
template<Lockable Mut>
|
||||
struct LockGuard {
|
||||
LockGuard(Mut& mtx)
|
||||
: mutex(mtx) {
|
||||
mutex.Lock();
|
||||
}
|
||||
|
||||
~LockGuard() {
|
||||
mutex.Unlock();
|
||||
}
|
||||
private:
|
||||
Mut& mutex;
|
||||
};
|
||||
|
||||
}
|
10
speech2/src/base/README.md
Normal file
10
speech2/src/base/README.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
# base/
|
||||
|
||||
This basically contains replacements of stuff from the standard library that we can't use on Windows XP because mingw sucks:
|
||||
|
||||
- Mutex
|
||||
- Thread
|
||||
- ManualResetEvent
|
||||
- AutoResetEvent
|
||||
|
||||
Oh and some stuff for dealing with COM
|
6
speech2/src/base/SaneWin.hpp
Normal file
6
speech2/src/base/SaneWin.hpp
Normal file
|
@ -0,0 +1,6 @@
|
|||
// Sane windows.h
|
||||
#pragma once
|
||||
#define _WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#undef _WIN32_LEAN_AND_MEAN
|
53
speech2/src/base/Thread.cpp
Normal file
53
speech2/src/base/Thread.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
#include <base/Thread.hpp>
|
||||
|
||||
namespace base {
|
||||
|
||||
/*static*/ unsigned Thread::EntryFunc(void* argp) {
|
||||
auto invocable = static_cast<ThreadInvocable*>(argp);
|
||||
(*invocable)();
|
||||
|
||||
// Usually cross thread frees are a no-no, but the thread effectively
|
||||
// owns the invocable once it has been passed to it, so /shrug.
|
||||
delete invocable;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Thread::~Thread() {
|
||||
// Join thread on destruction, unless
|
||||
// it has already been detached.
|
||||
if(Joinable())
|
||||
Join();
|
||||
}
|
||||
|
||||
unsigned Thread::Id() const {
|
||||
return osdep::BThread_GetID(threadHandle);
|
||||
}
|
||||
|
||||
bool Thread::Joinable() const {
|
||||
if(!threadHandle)
|
||||
return false;
|
||||
|
||||
return joinable;
|
||||
}
|
||||
|
||||
void Thread::Detach() {
|
||||
threadHandle = nullptr;
|
||||
joinable = false;
|
||||
}
|
||||
|
||||
void Thread::Join() {
|
||||
if(Joinable())
|
||||
osdep::BThread_Join(threadHandle);
|
||||
}
|
||||
|
||||
|
||||
void Thread::SpawnImpl(ThreadInvocable* pInvocable) {
|
||||
threadHandle = osdep::BThread_Spawn(&Thread::EntryFunc, static_cast<void*>(pInvocable), 0);
|
||||
if(threadHandle != nullptr)
|
||||
joinable = true;
|
||||
else {
|
||||
// Thread failed to create, delete the invocable so we don't leak memory.
|
||||
delete pInvocable;
|
||||
}
|
||||
}
|
||||
}
|
70
speech2/src/base/Thread.hpp
Normal file
70
speech2/src/base/Thread.hpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#pragma once
|
||||
#include <base/BThread.hpp>
|
||||
#include <base/SaneWin.hpp>
|
||||
#include <tuple>
|
||||
|
||||
namespace base {
|
||||
|
||||
// TODO: Put this in a bits header.
|
||||
#define __BASE_FWD(T) static_cast<T&&>
|
||||
|
||||
/// A thread.
|
||||
struct Thread {
|
||||
using NativeHandle = osdep::BThreadHandle;
|
||||
|
||||
Thread() = default;
|
||||
|
||||
template <class Func, class... Args>
|
||||
explicit Thread(Func&& func, Args&&... args) {
|
||||
struct FuncInvocable final : ThreadInvocable {
|
||||
Func&& func;
|
||||
std::tuple<Args&&...> args;
|
||||
|
||||
constexpr FuncInvocable(Func&& func, Args&&... args) : func(__BASE_FWD(Func)(func)), args({ __BASE_FWD(Args)(args)... }) {}
|
||||
|
||||
constexpr void operator()() override {
|
||||
std::apply([&](auto&&... argt) { func(__BASE_FWD(Args)(argt)...); }, args);
|
||||
}
|
||||
};
|
||||
|
||||
SpawnImpl(new FuncInvocable(__BASE_FWD(Func)(func), __BASE_FWD(Args)(args)...));
|
||||
}
|
||||
|
||||
Thread(const Thread&) = delete;
|
||||
Thread(Thread&&) = default;
|
||||
|
||||
~Thread();
|
||||
|
||||
// TODO: Actually return a OS native thread handle, instead of a BThreads handle.
|
||||
NativeHandle Native() const { return threadHandle; }
|
||||
|
||||
unsigned Id() const;
|
||||
|
||||
bool Joinable() const;
|
||||
|
||||
// Detaches the native thread.
|
||||
// Once this function is called the thread
|
||||
// will no longer be joinable.
|
||||
void Detach();
|
||||
|
||||
void Join();
|
||||
|
||||
private:
|
||||
// For type erasure. I know it's bad or whatever, but generally,
|
||||
// it shouldn't be a big enough deal.
|
||||
struct ThreadInvocable {
|
||||
virtual ~ThreadInvocable() = default;
|
||||
virtual void operator()() = 0;
|
||||
};
|
||||
|
||||
// Takes the invocable and spawns le epic heckin thread.
|
||||
void SpawnImpl(ThreadInvocable* pInvocable);
|
||||
|
||||
// Actually recieves a pointer to a [ThreadInvocable] on the heap,
|
||||
// synthesized from a given function.
|
||||
static unsigned WINAPI EntryFunc(void* args);
|
||||
|
||||
NativeHandle threadHandle {};
|
||||
bool joinable { false }; // implicitly false if there's no thread.
|
||||
};
|
||||
} // namespace base
|
71
speech2/src/base/comptr.hpp
Normal file
71
speech2/src/base/comptr.hpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
#pragma once
|
||||
#include <base/SaneWin.hpp>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace base {
|
||||
|
||||
// A relatively sane (non-intrinsic) COM smart pointer
|
||||
// TODO: Allow downcasting to ComPtr<IUnknown, IID_IUnknown> (all COM objects implement this anyways)
|
||||
//
|
||||
template <class T = IUnknown, const IID* iid = &IID_IUnknown>
|
||||
struct ComPtr {
|
||||
//constexpr ComPtr() = default;
|
||||
|
||||
//explicit ComPtr(T* t) : interface_ptr(t) {}
|
||||
constexpr ComPtr() : interface_ptr(nullptr) {}
|
||||
|
||||
// Assignment won't require AddRef() because most COM interfaces
|
||||
// will automatically AddRef() upon querying them.
|
||||
ComPtr& operator=(T* interface_) {
|
||||
// Release an existing interface.
|
||||
if(interface_ptr) {
|
||||
printf("ComPtr<T>::operator= releasing %p (guid %08x)\n", interface_ptr, *iid);
|
||||
interface_ptr->Release();
|
||||
}
|
||||
|
||||
interface_ptr = interface_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ComPtr(const ComPtr& copy) {
|
||||
if(interface_ptr) {
|
||||
interface_ptr->AddRef();
|
||||
interface_ptr = copy.interface_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
~ComPtr() {
|
||||
if(interface_ptr) {
|
||||
printf("ComPtr<T>::~ComPtr releasing %p (guid %08x)\n", interface_ptr, *iid);
|
||||
interface_ptr->Release();
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to CoCreateInstance() on this pointer
|
||||
HRESULT CreateInstance(REFCLSID clsid, DWORD ctx) {
|
||||
return CoCreateInstance(clsid, nullptr, CLSCTX_ALL, *iid, reinterpret_cast<void**>(&interface_ptr));
|
||||
}
|
||||
|
||||
// smart pointer overrides
|
||||
|
||||
constexpr T** operator&() { return &interface_ptr; }
|
||||
constexpr T* operator->() { return interface_ptr; }
|
||||
constexpr operator T*() const { return interface_ptr; }
|
||||
|
||||
T* Get() { return interface_ptr; }
|
||||
const T* Get() const { return interface_ptr; }
|
||||
|
||||
// release pointer - you need to manage it yourself or put it
|
||||
// into another ComSmartPtr then
|
||||
T* ReleasePtr() {
|
||||
auto old = interface_ptr;
|
||||
interface_ptr = nullptr;
|
||||
return old;
|
||||
}
|
||||
|
||||
private:
|
||||
T* interface_ptr { nullptr };
|
||||
};
|
||||
|
||||
} // namespace base
|
17
speech2/src/base/comresult.hpp
Normal file
17
speech2/src/base/comresult.hpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <variant>
|
||||
#include <windows.h>
|
||||
|
||||
template<class T>
|
||||
struct ComResult {
|
||||
|
||||
private:
|
||||
|
||||
using VariantType = std::variant<
|
||||
HRESULT,
|
||||
T
|
||||
>;
|
||||
|
||||
VariantType storage;
|
||||
};
|
120
speech2/src/main.cpp
Normal file
120
speech2/src/main.cpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
#include <stdio.h>
|
||||
#include <winscard.h>
|
||||
|
||||
#include <base/BThread.hpp>
|
||||
#include <base/Mutex.hpp>
|
||||
#include <base/Thread.hpp>
|
||||
|
||||
#include "speechapi.hpp"
|
||||
|
||||
// args
|
||||
// -v <voice> (voice to use)
|
||||
// -s 4|5 (what SAPI version to use)
|
||||
// -p 0..100 (pitch)
|
||||
// -s 0..100
|
||||
// [message]
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
#if 1
|
||||
if(FAILED(CoInitialize(nullptr))) {
|
||||
printf("Couldn't initalize COM\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
auto api = ISpeechAPI::CreateSapi4();
|
||||
if(!api) {
|
||||
printf("Couldn't allocate memory for speech API\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(auto hRes = api->Initialize(); FAILED(hRes)) {
|
||||
printf("Couldn't initalize SAPI 4 (hr: %08x)\n", hRes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 1
|
||||
auto voices = api->GetVoices();
|
||||
printf("Available voices:\n");
|
||||
for(auto& voice : voices) {
|
||||
auto& guid = voice.guid;
|
||||
|
||||
printf("%s (GUID {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X})\n", voice.voiceName.c_str(), guid.Data1, guid.Data2, guid.Data3,
|
||||
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(auto hRes = api->SelectVoice("Sam"); FAILED(hRes)) {
|
||||
printf("Test: Couldn't select Microsoft Sam\n");
|
||||
return 1;
|
||||
} else {
|
||||
printf("Test: Selected Microsoft Sam\n");
|
||||
}
|
||||
|
||||
#if 1
|
||||
if(auto hRes = api->SelectVoice("Mike"); FAILED(hRes)) {
|
||||
printf("Test: Couldn't select Microsoft Mike\n");
|
||||
return 1;
|
||||
} else {
|
||||
printf("Test: Seleced Microsoft Mike\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("Test: Selected voices successfully\n");
|
||||
|
||||
printf("Test: Destroying voice\n");
|
||||
delete api;
|
||||
|
||||
CoUninitialize();
|
||||
#endif
|
||||
|
||||
// condvar/threading tests
|
||||
#if 0
|
||||
static auto cv = base::osdep::BCondVar_Create();
|
||||
static auto PrintMutex = base::Mutex{};
|
||||
static auto n = 0;
|
||||
//auto n = 0;
|
||||
|
||||
Sleep(100);
|
||||
|
||||
base::Thread t([]() {
|
||||
base::osdep::BCondVar_Wait(cv, [](void* ctx) {
|
||||
base::LockGuard lk(PrintMutex);
|
||||
printf("t: wait predicate called %d\n", *static_cast<int*>(ctx));
|
||||
return *static_cast<int*>(ctx) == 4;
|
||||
}, static_cast<void*>(&n));
|
||||
|
||||
{
|
||||
base::LockGuard lk(PrintMutex);
|
||||
printf("t: condvar exited wait!\n");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
base::Thread t2([]() {
|
||||
base::osdep::BCondVar_Wait(cv, [](void* ctx) {
|
||||
base::LockGuard lk(PrintMutex);
|
||||
printf("t2: wait predicate called %d\n", *static_cast<int*>(ctx));
|
||||
return *static_cast<int*>(ctx) == 4;
|
||||
}, static_cast<void*>(&n));
|
||||
|
||||
{
|
||||
base::LockGuard lk(PrintMutex);
|
||||
printf("t2: condvar exited wait!\n");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
for(auto i = 0; i < 4; ++i) {
|
||||
base::osdep::BCondVar_SignalOne(cv);
|
||||
n++;
|
||||
Sleep(100);
|
||||
}
|
||||
|
||||
t2.Join();
|
||||
t.Join();
|
||||
base::osdep::BCondVar_Destroy(cv);
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
84
speech2/src/sapi4/api_sapi4.cpp
Normal file
84
speech2/src/sapi4/api_sapi4.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <base/comptr.hpp>
|
||||
|
||||
#include "sapi4/audio_buffer.hpp"
|
||||
#include "sapi4/include/speech.h"
|
||||
#include "speechapi.hpp"
|
||||
|
||||
struct SpeechAPI_SAPI4 : public ISpeechAPI {
|
||||
virtual ~SpeechAPI_SAPI4() {
|
||||
printf("~SpeechAPI_SAPI4\n");
|
||||
// if(pAudioOut)
|
||||
// pAudioOut->AddRef();
|
||||
|
||||
if(pCentral)
|
||||
pCentral->Release();
|
||||
};
|
||||
|
||||
HRESULT Initialize() override {
|
||||
HRESULT hRes;
|
||||
|
||||
hRes = pEnum.CreateInstance(CLSID_TTSEnumerator, CLSCTX_INPROC);
|
||||
if(FAILED(hRes))
|
||||
return hRes;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
std::vector<VoiceInfo> GetVoices() override {
|
||||
TTSMODEINFO found {};
|
||||
std::vector<VoiceInfo> ret;
|
||||
|
||||
while(!pEnum->Next(1, &found, nullptr)) {
|
||||
ret.push_back({ .guid = found.gModeID, .voiceName = found.szModeName });
|
||||
}
|
||||
|
||||
pEnum->Reset();
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT SelectVoiceImpl(const GUID& guid) {
|
||||
pAudioOut = new AudioOutBuffer();
|
||||
|
||||
if(pCentral)
|
||||
pCentral->Release();
|
||||
|
||||
ITTSCentral* central;
|
||||
if(auto hr = pEnum->Select(guid, ¢ral, static_cast<IUnknown*>(pAudioOut)); FAILED(hr))
|
||||
return hr;
|
||||
|
||||
pCentral = central;
|
||||
|
||||
// From Microsoft Speech SDK 4.0 documentation:
|
||||
// The engine will AddRef the interface, and release the interface when the engine is destroyed.
|
||||
// Because of this the application will need to call Release on the audio object after the select call or audio objects will be leaked.
|
||||
pAudioOut->Release();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT SelectVoice(std::string_view voiceName) override {
|
||||
TTSMODEINFO found {};
|
||||
|
||||
while(!pEnum->Next(1, &found, nullptr)) {
|
||||
if(voiceName == found.szModeName) {
|
||||
return SelectVoiceImpl(found.gModeID);
|
||||
}
|
||||
}
|
||||
|
||||
pEnum->Reset();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
base::ComPtr<ITTSEnum, &IID_ITTSEnum> pEnum;
|
||||
ITTSCentral* pCentral { nullptr };
|
||||
|
||||
// The above comment is also why this isn't a ComPtr.
|
||||
AudioOutBuffer* pAudioOut { nullptr };
|
||||
};
|
||||
|
||||
ISpeechAPI* ISpeechAPI::CreateSapi4() {
|
||||
return new SpeechAPI_SAPI4();
|
||||
}
|
185
speech2/src/sapi4/audio_buffer.cpp
Normal file
185
speech2/src/sapi4/audio_buffer.cpp
Normal file
|
@ -0,0 +1,185 @@
|
|||
#include "audio_buffer.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winerror.h>
|
||||
|
||||
// Implements IAudioDest.
|
||||
struct AudioOutBuffer::Dest : public IAudioDest {
|
||||
Dest(AudioOutBuffer* pOut) : pOut(pOut) {}
|
||||
~Dest() = default;
|
||||
|
||||
// IUnknown
|
||||
STDMETHODIMP QueryInterface(const IID& riid, LPVOID* ppvObj) noexcept override { return pOut->QueryInterface(riid, ppvObj); }
|
||||
|
||||
STDMETHODIMP_(ULONG) AddRef() noexcept override {
|
||||
m_iRefCount++;
|
||||
return pOut->AddRef();
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) Release() noexcept override {
|
||||
m_iRefCount--;
|
||||
return pOut->Release();
|
||||
}
|
||||
|
||||
// IAudioDest
|
||||
|
||||
STDMETHODIMP FreeSpace(DWORD* pFree, BOOL* pEOF) noexcept override { return E_NOTIMPL; }
|
||||
|
||||
STDMETHODIMP DataSet(PVOID pBuffer, DWORD dwSize) noexcept override {
|
||||
// TODO
|
||||
printf("AudioOutBuffer::Dest::DataSet()\n");
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP BookMark(DWORD pos) noexcept override {
|
||||
// Ignored
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
AudioOutBuffer* pOut;
|
||||
ULONG m_iRefCount{};
|
||||
};
|
||||
|
||||
// Implements IAudio.
|
||||
struct AudioOutBuffer::Audio : public IAudio {
|
||||
Audio(AudioOutBuffer* pOut) : pOut(pOut) {}
|
||||
~Audio() {
|
||||
};
|
||||
|
||||
// IUnknown
|
||||
STDMETHODIMP QueryInterface(const IID& riid, LPVOID* ppvObj) noexcept override { return pOut->QueryInterface(riid, ppvObj); }
|
||||
|
||||
STDMETHODIMP_(ULONG) AddRef() noexcept override {
|
||||
m_iRefCount++;
|
||||
return pOut->AddRef();
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) Release() noexcept override {
|
||||
m_iRefCount--;
|
||||
return pOut->Release();
|
||||
}
|
||||
|
||||
// IAudio
|
||||
|
||||
STDMETHODIMP Flush() noexcept override { return S_OK; }
|
||||
|
||||
STDMETHODIMP LevelGet(DWORD* pLevel) noexcept override { return E_NOTIMPL; }
|
||||
|
||||
STDMETHODIMP LevelSet(DWORD level) noexcept override { return E_NOTIMPL; }
|
||||
|
||||
STDMETHODIMP PassNotify(PVOID pSink, IID iid) noexcept override {
|
||||
printf("AudioOutBuffer::Audio::PassNotify() %p\n", pSink);
|
||||
if(pSink == nullptr) {
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if(iid != IID_IAudioDestNotifySink)
|
||||
return AUDERR_INVALIDNOTIFYSINK;
|
||||
|
||||
pOut->m_pDestNotifySink = static_cast<IAudioDestNotifySink*>(pSink);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP PosnGet(PQWORD pos) noexcept override {
|
||||
if(!pos)
|
||||
return E_POINTER;
|
||||
*pos = pOut->m_BufferWritten;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP Claim() noexcept override { return S_OK; }
|
||||
|
||||
STDMETHODIMP UnClaim() noexcept override { return S_OK; }
|
||||
|
||||
STDMETHODIMP Start() noexcept override {
|
||||
// TODO
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP Stop() noexcept override {
|
||||
// TODO
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP TotalGet(PQWORD total) noexcept override { return PosnGet(total); }
|
||||
|
||||
STDMETHODIMP ToFileTime(PQWORD time, FILETIME* out) noexcept override { return E_NOTIMPL; }
|
||||
|
||||
STDMETHODIMP WaveFormatGet(SDATA* pOut) noexcept override {
|
||||
// TODO
|
||||
|
||||
//IMalloc* pMalloc { nullptr };
|
||||
//if(auto hr = CoGetMalloc(1, &pMalloc); FAILED(hr))
|
||||
// return hr;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP WaveFormatSet(SDATA data) noexcept override {
|
||||
if(!data.pData)
|
||||
return E_INVALIDARG;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
AudioOutBuffer* pOut;
|
||||
|
||||
ULONG m_iRefCount{};
|
||||
};
|
||||
|
||||
AudioOutBuffer::AudioOutBuffer() {
|
||||
printf("AudioOutBuffer() %p\n", this);
|
||||
m_Audio = new AudioOutBuffer::Audio(this);
|
||||
m_AudioDestBuffer = new AudioOutBuffer::Dest(this);
|
||||
}
|
||||
|
||||
AudioOutBuffer::~AudioOutBuffer() {
|
||||
printf("~AudioOutBuffer() %p\n", this);
|
||||
if(m_AudioDestBuffer)
|
||||
delete m_AudioDestBuffer;
|
||||
|
||||
if(m_Audio)
|
||||
delete m_Audio;
|
||||
}
|
||||
|
||||
// IUnknown
|
||||
STDMETHODIMP AudioOutBuffer::QueryInterface(const IID& riid, LPVOID* ppvObj) noexcept {
|
||||
if(!ppvObj)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
*ppvObj = nullptr;
|
||||
|
||||
// This object only directly implements IUnknown, and proxies
|
||||
// to other implementation objects for other interfaces.
|
||||
if(riid == IID_IUnknown) {
|
||||
*ppvObj = static_cast<void*>(this);
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Return implementations
|
||||
if(riid == IID_IAudio) {
|
||||
*ppvObj = static_cast<void*>(m_Audio);
|
||||
//m_Audio->AddRef();
|
||||
return S_OK;
|
||||
} else if(riid == IID_IAudioDest) {
|
||||
*ppvObj = static_cast<void*>(m_AudioDestBuffer);
|
||||
//m_AudioDestBuffer->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) AudioOutBuffer::AddRef() {
|
||||
return InterlockedIncrement(&m_iRefCount);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) AudioOutBuffer::Release() {
|
||||
auto ulRefCount = InterlockedDecrement(&m_iRefCount);
|
||||
if(ulRefCount == 0) {
|
||||
printf("Deleting release AudioOutBuffer\n");
|
||||
delete this;
|
||||
}
|
||||
return ulRefCount;
|
||||
}
|
43
speech2/src/sapi4/audio_buffer.hpp
Normal file
43
speech2/src/sapi4/audio_buffer.hpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
#pragma once
|
||||
#include <windows.h>
|
||||
#include "base/comptr.hpp"
|
||||
#include "sapi4/include/speech.h"
|
||||
|
||||
// Implementation of SAPI 4 IAudio(Dest) to spit out wave format data to a buffer
|
||||
// TODO: out-line definition so other components can call methods they need
|
||||
struct AudioOutBuffer : public IUnknown {
|
||||
|
||||
// Implements IAudioDest.
|
||||
struct Dest;
|
||||
struct Audio;
|
||||
|
||||
AudioOutBuffer();
|
||||
virtual ~AudioOutBuffer();
|
||||
|
||||
AudioOutBuffer(const AudioOutBuffer&) = delete;
|
||||
AudioOutBuffer(AudioOutBuffer&&) = delete;
|
||||
|
||||
// IUnknown
|
||||
STDMETHODIMP QueryInterface(const IID& riid, LPVOID* ppvObj) noexcept override;
|
||||
STDMETHODIMP_(ULONG) AddRef() override;
|
||||
STDMETHODIMP_(ULONG) Release() override;
|
||||
|
||||
private:
|
||||
ULONG m_iRefCount{};
|
||||
|
||||
Dest* m_AudioDestBuffer{};
|
||||
Audio* m_Audio{};
|
||||
|
||||
enum class State {
|
||||
Clear,
|
||||
WroteHeader,
|
||||
WritingWaveData,
|
||||
Done
|
||||
};
|
||||
|
||||
//base::ComPtr<IAudioDestNotifySink, &IID_IAudioDestNotifySink> m_pDestNotifySink{};
|
||||
IAudioDestNotifySink* m_pDestNotifySink{nullptr};
|
||||
|
||||
QWORD m_BufferWritten{};
|
||||
|
||||
};
|
6
speech2/src/sapi4/guid_sapi4.cpp
Normal file
6
speech2/src/sapi4/guid_sapi4.cpp
Normal file
|
@ -0,0 +1,6 @@
|
|||
// This file declares all the SAPI 4.0 GUID's.
|
||||
|
||||
#include <windows.h>
|
||||
#include <initguid.h>
|
||||
|
||||
#include "sapi4/include/speech.h"
|
29
speech2/src/speechapi.hpp
Normal file
29
speech2/src/speechapi.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#include <windows.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/// base class for access to text-to-speech APIs.
|
||||
struct ISpeechAPI {
|
||||
|
||||
struct VoiceInfo {
|
||||
GUID guid{}; // Optional. May not be filled out if th e
|
||||
std::string voiceName;
|
||||
};
|
||||
|
||||
virtual ~ISpeechAPI() = default;
|
||||
|
||||
/// Creates a implementation of SpeechAPI for SAPI 4.
|
||||
/// COM must be initalized before calling this function.
|
||||
static ISpeechAPI* CreateSapi4();
|
||||
|
||||
/// Performs the bare level of initalization required to use the speech API
|
||||
virtual HRESULT Initialize() = 0;
|
||||
|
||||
virtual std::vector<VoiceInfo> GetVoices() = 0;
|
||||
|
||||
/// Selects a voice.
|
||||
virtual HRESULT SelectVoice(std::string_view voiceName) = 0;
|
||||
|
||||
|
||||
//virtual HRESULT Speak(LPCSTR text, char** pOutputBuffer, size_t* pOutSize) = 0;
|
||||
};
|
4
speech2/third_party/README.md
vendored
Normal file
4
speech2/third_party/README.md
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
Files in this directory are the intellectual property of:
|
||||
|
||||
- sapi4: Microsoft Speech SDK 4.0.4.2512
|
||||
- sapi5: Microsoft Speech SDK 5.1
|
63
speech2/third_party/sapi4/include/buildnum.h
vendored
Normal file
63
speech2/third_party/sapi4/include/buildnum.h
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* buildnum.h*/
|
||||
|
||||
|
||||
#ifndef BUILDNUM_H
|
||||
#define BUILDNUM_H
|
||||
/* NOTE: To change build number, change the definitions
|
||||
* of both BN_BN and BUILD_NUMBER. The rest will use
|
||||
* the BN_BN definition.
|
||||
*
|
||||
* Change log:
|
||||
*/
|
||||
#define BN_BN 2512
|
||||
#define BN_MAJOR 4
|
||||
#define BN_STR "2512"
|
||||
#ifndef BUILD_NUMBER
|
||||
#define BUILD_NUMBER "4.0.4." BN_STR "\0"
|
||||
#endif
|
||||
|
||||
#ifndef JUSTDEFINES
|
||||
char gszBuildNumber[] = "@(#) Microsoft Speech Build " BUILD_NUMBER;
|
||||
#endif
|
||||
|
||||
#ifndef BN_PRODUCT_VERSION
|
||||
#define BN_PRODUCT_VERSION 4,0,4,BN_BN
|
||||
#endif
|
||||
|
||||
#ifndef BN_FILE_VER
|
||||
#define BN_FILE_VERSION BN_PRODUCT_VERSION
|
||||
#else
|
||||
#define BN_FILE_VERSION BN_FILE_VER,BN_BN
|
||||
#endif//BN_FILE_VER
|
||||
|
||||
#ifndef BN_FILE_STR
|
||||
#define BN_FILE_VERSION_STR BUILD_NUMBER
|
||||
#else
|
||||
#define BN_FILE_VERSION_STR BN_FILE_STR " " BN_STR "\0"
|
||||
#endif
|
||||
|
||||
#ifndef BN_FLAGS
|
||||
#ifdef _DEBUG
|
||||
#define BN_FLAGS VS_FF_DEBUG
|
||||
#else
|
||||
#ifdef TEST
|
||||
#define BN_FLAGS VS_FF_PRERELEASE
|
||||
#else
|
||||
#define BN_FLAGS 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BN_FLAGSMASK
|
||||
#define BN_FLAGSMASK VS_FF_PRERELEASE | VS_FF_DEBUG
|
||||
#endif//BN_FLAGSMASK
|
||||
|
||||
#ifndef BN_PRODUCTNAME
|
||||
#define BN_PRODUCTNAME "Microsoft Speech\0"
|
||||
#endif//BN_PRODUCTNAME
|
||||
|
||||
#ifndef BN_COPYRIGHT
|
||||
#define BN_COPYRIGHT "Copyright © 1991-1998 Microsoft Corporation\0"
|
||||
#endif//BN_COPYRIGHT
|
||||
|
||||
#endif // BUILDNUM_H
|
69
speech2/third_party/sapi4/include/buildnum.rc
vendored
Normal file
69
speech2/third_party/sapi4/include/buildnum.rc
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
/* Each RC file that includes this file for version
|
||||
* stamping, must define the following items:
|
||||
*
|
||||
* #define VER_FILE_TYPE VFT_ // VFT_APP, VFT_DLL, VFT_DRV, VFT_VXD
|
||||
* #define VER_FILE_DESC "Your app name\0" // don't forget the explicit null.
|
||||
* #define VER_FILE_SUBTYPE 0 // All but driver should be 0
|
||||
* #define VER_FILE_INTNAME "<module-name>\0" //don't forget the null.
|
||||
*
|
||||
* Change Log:
|
||||
* 8/31/93 - benm - Tweaked to handle internal name correctly.
|
||||
*/
|
||||
#ifndef BUILDNUM_RC
|
||||
#define BUILDNUM_RC
|
||||
|
||||
#include <buildnum.h>
|
||||
#ifndef VS_FF_DEBUG
|
||||
#include <ver.h>
|
||||
#endif
|
||||
|
||||
// Default internal name to be same as file desc.
|
||||
#ifndef VER_INTERNAL_NAME
|
||||
#define VER_INTERNAL_NAME VER_FILE_DESC
|
||||
#endif
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION BN_FILE_VERSION
|
||||
PRODUCTVERSION BN_PRODUCT_VERSION
|
||||
FILEFLAGSMASK BN_FLAGSMASK
|
||||
FILEFLAGS BN_FLAGS
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
|
||||
FILETYPE VER_FILE_TYPE
|
||||
FILESUBTYPE VER_FILE_SUBTYPE
|
||||
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Microsoft Corporation\0"
|
||||
VALUE "FileDescription", VER_FILE_DESC
|
||||
VALUE "FileVersion", BN_FILE_VERSION_STR
|
||||
VALUE "InternalName", VER_INTERNAL_NAME
|
||||
VALUE "LegalCopyright", BN_COPYRIGHT
|
||||
VALUE "ProductName", BN_PRODUCTNAME
|
||||
VALUE "ProductVersion", BUILD_NUMBER
|
||||
VALUE "OriginalFilename", VER_ORIGINAL_FILENAME
|
||||
END
|
||||
|
||||
BLOCK "040904B0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Microsoft Corporation\0"
|
||||
VALUE "FileDescription", VER_FILE_DESC
|
||||
VALUE "FileVersion", BN_FILE_VERSION_STR
|
||||
VALUE "InternalName", VER_INTERNAL_NAME
|
||||
VALUE "LegalCopyright", BN_COPYRIGHT
|
||||
VALUE "ProductName", BN_PRODUCTNAME
|
||||
VALUE "ProductVersion", BUILD_NUMBER
|
||||
VALUE "OriginalFilename", VER_ORIGINAL_FILENAME
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1252
|
||||
END
|
||||
END
|
||||
|
||||
#endif // BUILDNUM_RC
|
313
speech2/third_party/sapi4/include/spchtel.h
vendored
Normal file
313
speech2/third_party/sapi4/include/spchtel.h
vendored
Normal file
|
@ -0,0 +1,313 @@
|
|||
/*****************************************************************
|
||||
Spchtel.H - Header file to use the Microsoft Speech telephony controls.
|
||||
|
||||
Copyright 1998 by Microsoft corporation.All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SPCHTEL_H_
|
||||
#define _SPCHTEL_H_
|
||||
|
||||
// Flag values for the ITelControl::TypeSet call
|
||||
#define INFOTYPE_PC 0x00000001
|
||||
#define INFOTYPE_TAPI20 0x00000002
|
||||
#define INFOTYPE_TAPI30 0x00000004
|
||||
|
||||
// Common return codes from controls
|
||||
// not usually handled, often returned
|
||||
#define TCR_ABORT ((DWORD)-1L) // the user has hung up
|
||||
#define TCR_NORESPONSE ((DWORD)-2L) // the user hasn't repsonded to the questions
|
||||
#define TCR_ASKOPERATOR ((DWORD)-3L) // the user has asked for an operator (often control just auto replies)
|
||||
#define TCR_ASKHANGUP ((DWORD)-4L) // the user has asked to hang up. App must handle
|
||||
#define TCR_ASKBACK ((DWORD)-5L) // the user has asked to go back and redo the previous thing
|
||||
|
||||
// usually handled by control, unless overrided
|
||||
#define TCR_ASKWHERE ((DWORD)-10L) // the user has asked where he/she is (usualy handled by control)
|
||||
#define TCR_ASKHELP ((DWORD)-11L) // the user has asked for help (usually handled by control)
|
||||
#define TCR_ASKREPEAT ((DWORD)-12L) // the user has asked for the question to be repeated (usually handled by the control)
|
||||
#define TCR_ASKSPEAKFASTER ((DWORD)-13L) // the user has asked to speak faster. usually handled by the control
|
||||
#define TCR_ASKSPEAKSLOWER ((DWORD)-14L) // the user has asked to speak slower. Usually handled by the control
|
||||
|
||||
|
||||
|
||||
// {F9D18BF8-E0ED-11d0-AB8B-08002BE4E3B7}
|
||||
DEFINE_GUID (CLSID_TelInfo,
|
||||
0xf9d18bf8, 0xe0ed, 0x11d0, 0xab, 0x8b, 0x8, 0x0, 0x2b, 0xe4, 0xe3, 0xb7);
|
||||
|
||||
/*
|
||||
* ITelNotifySink
|
||||
*/
|
||||
#undef INTERFACE
|
||||
#define INTERFACE ITelNotifySink
|
||||
|
||||
// {CD0C7D7C-E1CD-11d0-AB8B-08002BE4E3B7}
|
||||
DEFINE_GUID(IID_ITelNotifySink,
|
||||
0xcd0c7d7c, 0xe1cd, 0x11d0, 0xab, 0x8b, 0x8, 0x0, 0x2b, 0xe4, 0xe3, 0xb7);
|
||||
|
||||
DECLARE_INTERFACE_ (ITelNotifySink, IUnknown) {
|
||||
// IUnkown members
|
||||
STDMETHOD (QueryInterface) (THIS_ REFIID, LPVOID FAR *) PURE;
|
||||
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release) (THIS) PURE;
|
||||
|
||||
// ITelNotifySink members
|
||||
STDMETHOD (DTMF) (THIS_ WCHAR) PURE;
|
||||
STDMETHOD (Abort) (THIS_ DWORD) PURE;
|
||||
};
|
||||
typedef ITelNotifySink FAR *PITELNOTIFYSINK;
|
||||
|
||||
|
||||
/*
|
||||
* ITelControlNotifySink
|
||||
*/
|
||||
#undef INTERFACE
|
||||
#define INTERFACE ITelControlNotifySink
|
||||
|
||||
// {A55E2436-E297-11d0-AB8B-08002BE4E3B7}
|
||||
DEFINE_GUID(IID_ITelControlNotifySink,
|
||||
0xa55e2436, 0xe297, 0x11d0, 0xab, 0x8b, 0x8, 0x0, 0x2b, 0xe4, 0xe3, 0xb7);
|
||||
|
||||
DECLARE_INTERFACE_ (ITelControlNotifySink, IUnknown) {
|
||||
// IUnkown members
|
||||
STDMETHOD (QueryInterface) (THIS_ REFIID, LPVOID FAR *) PURE;
|
||||
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release) (THIS) PURE;
|
||||
|
||||
// ITelControlNotifySink members
|
||||
STDMETHOD (Finish) (THIS_ DWORD, PVOID, DWORD) PURE;
|
||||
STDMETHOD (Info) (THIS_ DWORD, PVOID, DWORD) PURE;
|
||||
};
|
||||
typedef ITelControlNotifySink FAR *PITELCONTROLNOTIFYSINK;
|
||||
|
||||
|
||||
/*
|
||||
* ITelInfo
|
||||
*/
|
||||
#undef INTERFACE
|
||||
#define INTERFACE ITelInfo
|
||||
|
||||
// {250F0433-E0EB-11d0-AB8B-08002BE4E3B7}
|
||||
DEFINE_GUID(IID_ITelInfo,
|
||||
0x250f0433, 0xe0eb, 0x11d0, 0xab, 0x8b, 0x8, 0x0, 0x2b, 0xe4, 0xe3, 0xb7);
|
||||
|
||||
DECLARE_INTERFACE_ (ITelInfo, IUnknown) {
|
||||
// IUnkown members
|
||||
STDMETHOD (QueryInterface) (THIS_ REFIID, LPVOID FAR *) PURE;
|
||||
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release) (THIS) PURE;
|
||||
|
||||
// ITelInfo members
|
||||
STDMETHOD (ObjectGet) (THIS_ GUID, LPUNKNOWN *) PURE;
|
||||
STDMETHOD (ObjectSet) (THIS_ GUID, LPUNKNOWN) PURE;
|
||||
STDMETHOD (DWORDGet) (THIS_ GUID, DWORD *) PURE;
|
||||
STDMETHOD (DWORDSet) (THIS_ GUID, DWORD) PURE;
|
||||
STDMETHOD (MemoryGet) (THIS_ GUID, PVOID *, DWORD *) PURE;
|
||||
STDMETHOD (MemorySet) (THIS_ GUID, PVOID, DWORD) PURE;
|
||||
STDMETHOD (SendDTMF) (THIS_ WCHAR) PURE;
|
||||
STDMETHOD (SendAbort) (THIS_ DWORD) PURE;
|
||||
STDMETHOD (TypeSet) (THIS_ DWORD) PURE;
|
||||
STDMETHOD (WaveDeviceSet) (THIS_ DWORD, DWORD) PURE;
|
||||
STDMETHOD (AudioSourceCreate) (THIS_ LPUNKNOWN *) PURE;
|
||||
STDMETHOD (AudioDestCreate) (THIS_ LPUNKNOWN *) PURE;
|
||||
STDMETHOD (QuickCreate) (THIS_ HMODULE, PSRMODEINFOW, PTTSMODEINFOW,
|
||||
PCWSTR, BOOL) PURE;
|
||||
};
|
||||
typedef ITelInfo FAR *PITELINFO;
|
||||
|
||||
|
||||
/*
|
||||
* ITelControl
|
||||
*/
|
||||
#undef INTERFACE
|
||||
#define INTERFACE ITelControl
|
||||
|
||||
// {17674DEB-E298-11d0-AB8B-08002BE4E3B7}
|
||||
DEFINE_GUID(IID_ITelControl,
|
||||
0x17674deb, 0xe298, 0x11d0, 0xab, 0x8b, 0x8, 0x0, 0x2b, 0xe4, 0xe3, 0xb7);
|
||||
|
||||
DECLARE_INTERFACE_ (ITelControl, IUnknown) {
|
||||
// IUnkown members
|
||||
STDMETHOD (QueryInterface) (THIS_ REFIID, LPVOID FAR *) PURE;
|
||||
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
|
||||
STDMETHOD_(ULONG,Release) (THIS) PURE;
|
||||
|
||||
// ITelControl members
|
||||
STDMETHOD (FromMemory) (THIS_ PVOID, DWORD) PURE;
|
||||
STDMETHOD (FromStream) (THIS_ IStream *) PURE;
|
||||
#ifdef STRICT
|
||||
STDMETHOD (FromResource) (THIS_ PVOID, DWORD) PURE;
|
||||
#else
|
||||
STDMETHOD (FromResource) (THIS_ HINSTANCE, DWORD) PURE;
|
||||
#endif
|
||||
STDMETHOD (FromFile) (THIS_ PCWSTR) PURE;
|
||||
STDMETHOD (Compile) (THIS_ LPWSTR*, DWORD*) PURE;
|
||||
STDMETHOD (IsCompiled) (THIS_ BOOL*) PURE;
|
||||
STDMETHOD (LanguageGet) (THIS_ LANGUAGEW*) PURE;
|
||||
STDMETHOD (ToMemory) (THIS_ PVOID*, DWORD*) PURE;
|
||||
STDMETHOD (ToStream) (THIS_ IStream *) PURE;
|
||||
STDMETHOD (ToFile) (THIS_ PCWSTR) PURE;
|
||||
STDMETHOD (TextGet) (THIS_ LPWSTR*, DWORD*) PURE;
|
||||
STDMETHOD (TextDefaultGet) (THIS_ LPWSTR*, DWORD*) PURE;
|
||||
STDMETHOD (ObjectSet) (THIS_ PITELINFO) PURE;
|
||||
STDMETHOD (Start) (THIS_ PITELCONTROLNOTIFYSINK) PURE;
|
||||
STDMETHOD (Abort) (THIS) PURE;
|
||||
};
|
||||
typedef ITelControl FAR *PITELCONTROL;
|
||||
|
||||
|
||||
//
|
||||
// GUID identifiers for objects
|
||||
//
|
||||
// {44DB6739-E10E-11d0-AB8B-08002BE4E3B7}
|
||||
DEFINE_GUID(TELOBJ_SPEECHRECOG,
|
||||
0x44db6739, 0xe10e, 0x11d0, 0xab, 0x8b, 0x8, 0x0, 0x2b, 0xe4, 0xe3, 0xb7);
|
||||
|
||||
// {44DB673B-E10E-11d0-AB8B-08002BE4E3B7}
|
||||
DEFINE_GUID(TELOBJ_TTSQUEUE,
|
||||
0x44db673b, 0xe10e, 0x11d0, 0xab, 0x8b, 0x8, 0x0, 0x2b, 0xe4, 0xe3, 0xb7);
|
||||
|
||||
// {44DB673C-E10E-11d0-AB8B-08002BE4E3B7}
|
||||
DEFINE_GUID(TELOBJ_LOGGING,
|
||||
0x44db673c, 0xe10e, 0x11d0, 0xab, 0x8b, 0x8, 0x0, 0x2b, 0xe4, 0xe3, 0xb7);
|
||||
|
||||
// {44DB673D-E10E-11d0-AB8B-08002BE4E3B7}
|
||||
DEFINE_GUID(TELOBJ_TAPI30,
|
||||
0x44db673d, 0xe10e, 0x11d0, 0xab, 0x8b, 0x8, 0x0, 0x2b, 0xe4, 0xe3, 0xb7);
|
||||
|
||||
// {44DB673E-E10E-11d0-AB8B-08002BE4E3B7}
|
||||
DEFINE_GUID(TELOBJ_NOTIFYSINK,
|
||||
0x44db673e, 0xe10e, 0x11d0, 0xab, 0x8b, 0x8, 0x0, 0x2b, 0xe4, 0xe3, 0xb7);
|
||||
|
||||
|
||||
// hcall for TAPI
|
||||
// {F40CC4C0-0D0A-11d2-BEF0-006008317CE8}
|
||||
DEFINE_GUID(TELDWORD_HCALL,
|
||||
0xf40cc4c0, 0xd0a, 0x11d2, 0xbe, 0xf0, 0x0, 0x60, 0x8, 0x31, 0x7c, 0xe8);
|
||||
|
||||
// hline for tapi
|
||||
// {F40CC4C1-0D0A-11d2-BEF0-006008317CE8}
|
||||
DEFINE_GUID(TELDWORD_HLINE,
|
||||
0xf40cc4c1, 0xd0a, 0x11d2, 0xbe, 0xf0, 0x0, 0x60, 0x8, 0x31, 0x7c, 0xe8);
|
||||
|
||||
// If this is set to TRUE, then beeps on a recognition are enabled.
|
||||
// Disabling speeds up the response time of the system, but some people
|
||||
// will speak before the beep. It's a tradeoff.
|
||||
// {DB7F6130-0D2D-11d2-BEF1-006008317CE8}
|
||||
DEFINE_GUID(TELDWORD_EnableRecognizeBeeps,
|
||||
0xdb7f6130, 0xd2d, 0x11d2, 0xbe, 0xf1, 0x0, 0x60, 0x8, 0x31, 0x7c, 0xe8);
|
||||
|
||||
// if set to true, and we're using tapi, then we should use tapi
|
||||
// beeps rather than recordings for recognition acknowledgement
|
||||
// beeps. This doesn't work properly on most telephony cards, and there's no
|
||||
// way to tell, so be careful about using it
|
||||
// {F40CC4C2-0D0A-11d2-BEF0-006008317CE8}
|
||||
DEFINE_GUID(TELDWORD_UseTAPIBeep,
|
||||
0xf40cc4c2, 0xd0a, 0x11d2, 0xbe, 0xf0, 0x0, 0x60, 0x8, 0x31, 0x7c, 0xe8);
|
||||
|
||||
// disable the ability for a user to change the speed
|
||||
// {59596FBE-F936-11d0-8FAD-08002BE4E62A}
|
||||
DEFINE_GUID(TELDWORD_DisableSpeedChange,
|
||||
0x59596fbe, 0xf936, 0x11d0, 0x8f, 0xad, 0x8, 0x0, 0x2b, 0xe4, 0xe6, 0x2a);
|
||||
|
||||
// enable the ability for the user to ask for an operator
|
||||
// {59596FBF-F936-11d0-8FAD-08002BE4E62A}
|
||||
DEFINE_GUID(TELDWORD_EnableOperator,
|
||||
0x59596fbf, 0xf936, 0x11d0, 0x8f, 0xad, 0x8, 0x0, 0x2b, 0xe4, 0xe6, 0x2a);
|
||||
|
||||
// eanble the user to ask to hang up. If TRUE application must handle
|
||||
// {59596FC0-F936-11d0-8FAD-08002BE4E62A}
|
||||
DEFINE_GUID(TELDWORD_EnableAskHangUp,
|
||||
0x59596fc0, 0xf936, 0x11d0, 0x8f, 0xad, 0x8, 0x0, 0x2b, 0xe4, 0xe6, 0x2a);
|
||||
|
||||
// if TRUE, then the system supports full duplex
|
||||
// both full duplex and echo cancelling must be TRUE for telephony controls to have barge in
|
||||
// {10FEF992-343F-11d1-BE71-006008317CE8}
|
||||
DEFINE_GUID(TELDWORD_FullDuplex,
|
||||
0x10fef992, 0x343f, 0x11d1, 0xbe, 0x71, 0x0, 0x60, 0x8, 0x31, 0x7c, 0xe8);
|
||||
|
||||
// if TRUE, then the system has echo cancelling built in.
|
||||
// both full duplex and echo cancelling must be TRUE for telephony controls to have barge in
|
||||
// {10FEF991-343F-11d1-BE71-006008317CE8}
|
||||
DEFINE_GUID(TELDWORD_EchoCancel,
|
||||
0x10fef991, 0x343f, 0x11d1, 0xbe, 0x71, 0x0, 0x60, 0x8, 0x31, 0x7c, 0xe8);
|
||||
|
||||
/**************************************************************************
|
||||
Telephon controls in spchtel.dll. */
|
||||
|
||||
// {53961A01-459B-11d1-BE77-006008317CE8}
|
||||
DEFINE_GUID(CLSID_YesNoControl,
|
||||
0x53961a01, 0x459b, 0x11d1, 0xbe, 0x77, 0x0, 0x60, 0x8, 0x31, 0x7c, 0xe8);
|
||||
|
||||
// {53961A02-459B-11d1-BE77-006008317CE8}
|
||||
DEFINE_GUID(CLSID_ExtensionControl,
|
||||
0x53961a02, 0x459b, 0x11d1, 0xbe, 0x77, 0x0, 0x60, 0x8, 0x31, 0x7c, 0xe8);
|
||||
|
||||
// {53961A03-459B-11d1-BE77-006008317CE8}
|
||||
DEFINE_GUID(CLSID_PhoneNumControl,
|
||||
0x53961a03, 0x459b, 0x11d1, 0xbe, 0x77, 0x0, 0x60, 0x8, 0x31, 0x7c, 0xe8);
|
||||
|
||||
// {53961A04-459B-11d1-BE77-006008317CE8}
|
||||
DEFINE_GUID(CLSID_GrammarControl,
|
||||
0x53961a04, 0x459b, 0x11d1, 0xbe, 0x77, 0x0, 0x60, 0x8, 0x31, 0x7c, 0xe8);
|
||||
|
||||
// {53961A05-459B-11d1-BE77-006008317CE8}
|
||||
DEFINE_GUID(CLSID_DateControl,
|
||||
0x53961a05, 0x459b, 0x11d1, 0xbe, 0x77, 0x0, 0x60, 0x8, 0x31, 0x7c, 0xe8);
|
||||
|
||||
// {53961A06-459B-11d1-BE77-006008317CE8}
|
||||
DEFINE_GUID(CLSID_TimeControl,
|
||||
0x53961a06, 0x459b, 0x11d1, 0xbe, 0x77, 0x0, 0x60, 0x8, 0x31, 0x7c, 0xe8);
|
||||
|
||||
// {53961A07-459B-11d1-BE77-006008317CE8}
|
||||
DEFINE_GUID(CLSID_RecordControl,
|
||||
0x53961a07, 0x459b, 0x11d1, 0xbe, 0x77, 0x0, 0x60, 0x8, 0x31, 0x7c, 0xe8);
|
||||
|
||||
// {53961A08-459B-11d1-BE77-006008317CE8}
|
||||
DEFINE_GUID(CLSID_SpellingControl,
|
||||
0x53961a08, 0x459b, 0x11d1, 0xbe, 0x77, 0x0, 0x60, 0x8, 0x31, 0x7c, 0xe8);
|
||||
|
||||
// {53961A09-459B-11d1-BE77-006008317CE8}
|
||||
DEFINE_GUID(CLSID_NameControl,
|
||||
0x53961a09, 0x459b, 0x11d1, 0xbe, 0x77, 0x0, 0x60, 0x8, 0x31, 0x7c, 0xe8);
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
Sample telephony controls GUIDs. These samples appear in the SDK. */
|
||||
// {C869F0DE-EF29-11d0-8FAD-08002BE4E62A}
|
||||
DEFINE_GUID(CLSID_SampleYesNoControl,
|
||||
0xc869f0de, 0xef29, 0x11d0, 0x8f, 0xad, 0x8, 0x0, 0x2b, 0xe4, 0xe6, 0x2a);
|
||||
|
||||
// {9DE44BA9-F94A-11d0-8FAD-08002BE4E62A}
|
||||
DEFINE_GUID(CLSID_SampleExtensionControl,
|
||||
0x9de44ba9, 0xf94a, 0x11d0, 0x8f, 0xad, 0x8, 0x0, 0x2b, 0xe4, 0xe6, 0x2a);
|
||||
|
||||
// {9DE44BAA-F94A-11d0-8FAD-08002BE4E62A}
|
||||
DEFINE_GUID(CLSID_SamplePhoneNumControl,
|
||||
0x9de44baa, 0xf94a, 0x11d0, 0x8f, 0xad, 0x8, 0x0, 0x2b, 0xe4, 0xe6, 0x2a);
|
||||
|
||||
// {9DE44BAB-F94A-11d0-8FAD-08002BE4E62A}
|
||||
DEFINE_GUID(CLSID_SampleGrammarControl,
|
||||
0x9de44bab, 0xf94a, 0x11d0, 0x8f, 0xad, 0x8, 0x0, 0x2b, 0xe4, 0xe6, 0x2a);
|
||||
|
||||
// {9DE44BAC-F94A-11d0-8FAD-08002BE4E62A}
|
||||
DEFINE_GUID(CLSID_SampleDateControl,
|
||||
0x9de44bac, 0xf94a, 0x11d0, 0x8f, 0xad, 0x8, 0x0, 0x2b, 0xe4, 0xe6, 0x2a);
|
||||
|
||||
// {9DE44BAD-F94A-11d0-8FAD-08002BE4E62A}
|
||||
DEFINE_GUID(CLSID_SampleTimeControl,
|
||||
0x9de44bad, 0xf94a, 0x11d0, 0x8f, 0xad, 0x8, 0x0, 0x2b, 0xe4, 0xe6, 0x2a);
|
||||
|
||||
// {275931C6-FD27-11d0-8FAE-08002BE4E62A}
|
||||
DEFINE_GUID(CLSID_SampleRecordControl,
|
||||
0x275931c6, 0xfd27, 0x11d0, 0x8f, 0xae, 0x8, 0x0, 0x2b, 0xe4, 0xe6, 0x2a);
|
||||
|
||||
// {9DE44BAE-F94A-11d0-8FAD-08002BE4E62A}
|
||||
DEFINE_GUID(CLSID_SampleSpellingControl,
|
||||
0x9de44bae, 0xf94a, 0x11d0, 0x8f, 0xad, 0x8, 0x0, 0x2b, 0xe4, 0xe6, 0x2a);
|
||||
|
||||
// {9DE44BAF-F94A-11d0-8FAD-08002BE4E62A}
|
||||
DEFINE_GUID(CLSID_SampleNameControl,
|
||||
0x9de44baf, 0xf94a, 0x11d0, 0x8f, 0xad, 0x8, 0x0, 0x2b, 0xe4, 0xe6, 0x2a);
|
||||
|
||||
|
||||
#endif // _SPCHTEL_H_
|
2456
speech2/third_party/sapi4/include/spchwrap.h
vendored
Normal file
2456
speech2/third_party/sapi4/include/spchwrap.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
6635
speech2/third_party/sapi4/include/speech.h
vendored
Normal file
6635
speech2/third_party/sapi4/include/speech.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
BIN
speech2/third_party/sapi4/lib/spchwrap.lib
vendored
Normal file
BIN
speech2/third_party/sapi4/lib/spchwrap.lib
vendored
Normal file
Binary file not shown.
2197
speech2/third_party/sapi5/idl/sapi.idl
vendored
Normal file
2197
speech2/third_party/sapi5/idl/sapi.idl
vendored
Normal file
File diff suppressed because it is too large
Load diff
4847
speech2/third_party/sapi5/idl/sapiaut.idl
vendored
Normal file
4847
speech2/third_party/sapi5/idl/sapiaut.idl
vendored
Normal file
File diff suppressed because it is too large
Load diff
818
speech2/third_party/sapi5/idl/sapiddk.idl
vendored
Normal file
818
speech2/third_party/sapi5/idl/sapiddk.idl
vendored
Normal file
|
@ -0,0 +1,818 @@
|
|||
/****************************************************************************
|
||||
* sapiddk.idl
|
||||
*
|
||||
* This is the interface definition file for the Microsoft Speech API DLL's
|
||||
* Version 5.0.
|
||||
*
|
||||
* It contains definitions for the DDI layer between SAPI.DLL and both
|
||||
* TTS and SR engines.
|
||||
*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
*****************************************************************************/
|
||||
|
||||
//--- Includes --------------------------------------------------------------
|
||||
import "oaidl.idl";
|
||||
import "ocidl.idl";
|
||||
import "sapi.idl";
|
||||
|
||||
//--- Locally scoped define for LANGID
|
||||
#ifndef LANGID
|
||||
#define LANGID WORD
|
||||
#endif
|
||||
|
||||
|
||||
//--- ITN Processor
|
||||
interface ISpITNProcessor;
|
||||
|
||||
//--- Grammar compiler and dynamic manipulation
|
||||
interface ISpErrorLog;
|
||||
interface ISpGrammarCompiler;
|
||||
interface ISpGramCompBackend;
|
||||
|
||||
//--- Phrase builder
|
||||
interface ISpPhraseBuilder;
|
||||
|
||||
//--- Token String Key Names
|
||||
cpp_quote("#define SPRECOEXTENSION L\"RecoExtension\"")
|
||||
cpp_quote("#define SPALTERNATESCLSID L\"AlternatesCLSID\"")
|
||||
|
||||
//--- ISpTokenUI -----------------------------------------------------------
|
||||
[
|
||||
object,
|
||||
uuid(F8E690F0-39CB-4843-B8D7-C84696E1119D),
|
||||
helpstring("ISpTokenUI Interface"),
|
||||
pointer_default(unique),
|
||||
restricted
|
||||
]
|
||||
interface ISpTokenUI : IUnknown
|
||||
{
|
||||
[local] HRESULT IsUISupported(
|
||||
[in] const WCHAR * pszTypeOfUI,
|
||||
[in] void * pvExtraData,
|
||||
[in] ULONG cbExtraData,
|
||||
[in] IUnknown * punkObject,
|
||||
[out] BOOL *pfSupported);
|
||||
[local] HRESULT DisplayUI(
|
||||
[in] HWND hwndParent,
|
||||
[in] const WCHAR * pszTitle,
|
||||
[in] const WCHAR * pszTypeOfUI,
|
||||
[in] void * pvExtraData,
|
||||
[in] ULONG cbExtraData,
|
||||
[in] ISpObjectToken * pToken,
|
||||
[in] IUnknown * punkObject);
|
||||
};
|
||||
|
||||
//--- ISpObjectTokenEnumBuilder ---------------------------------------------
|
||||
[
|
||||
object,
|
||||
uuid(06B64F9F-7FDA-11d2-B4F2-00C04F797396),
|
||||
helpstring("ISpObjectTokensEnumBuilder Interface"),
|
||||
pointer_default(unique),
|
||||
restricted
|
||||
]
|
||||
interface ISpObjectTokenEnumBuilder : IEnumSpObjectTokens
|
||||
{
|
||||
HRESULT SetAttribs(const WCHAR * pszReqAttribs, const WCHAR * pszOptAttribs);
|
||||
|
||||
HRESULT AddTokens(ULONG cTokens, ISpObjectToken ** pToken);
|
||||
HRESULT AddTokensFromDataKey(ISpDataKey * pDataKey, const WCHAR * pszSubKey, const WCHAR * pszCategoryId);
|
||||
HRESULT AddTokensFromTokenEnum(IEnumSpObjectTokens * pTokenEnum);
|
||||
|
||||
HRESULT Sort(const WCHAR * pszTokenIdToListFirst);
|
||||
};
|
||||
|
||||
//--- Handles for SR grammars and results
|
||||
cpp_quote("#if 0")
|
||||
typedef void * SPWORDHANDLE;
|
||||
typedef void * SPRULEHANDLE;
|
||||
typedef void * SPGRAMMARHANDLE;
|
||||
typedef void * SPRECOCONTEXTHANDLE;
|
||||
typedef void * SPPHRASERULEHANDLE;
|
||||
typedef void * SPPHRASEPROPERTYHANDLE;
|
||||
typedef void * SPTRANSITIONID;
|
||||
cpp_quote("#else")
|
||||
cpp_quote("DECLARE_HANDLE(SPWORDHANDLE);")
|
||||
cpp_quote("DECLARE_HANDLE(SPRULEHANDLE);")
|
||||
cpp_quote("DECLARE_HANDLE(SPGRAMMARHANDLE);")
|
||||
cpp_quote("DECLARE_HANDLE(SPRECOCONTEXTHANDLE);")
|
||||
cpp_quote("DECLARE_HANDLE(SPPHRASERULEHANDLE);")
|
||||
cpp_quote("DECLARE_HANDLE(SPPHRASEPROPERTYHANDLE);")
|
||||
cpp_quote("DECLARE_HANDLE(SPTRANSITIONID);")
|
||||
cpp_quote("#endif")
|
||||
|
||||
|
||||
//--- ISpErrorLog -----------------------------------------------------------
|
||||
// This interface is used to log error information.
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(F4711347-E608-11d2-A086-00C04F8EF9B5),
|
||||
helpstring("ISpErrorLog Interface"),
|
||||
pointer_default(unique),
|
||||
restricted
|
||||
]
|
||||
interface ISpErrorLog : IUnknown
|
||||
{
|
||||
HRESULT AddError(
|
||||
const long lLineNumber,
|
||||
HRESULT hr,
|
||||
const WCHAR * pszDescription,
|
||||
const WCHAR * pszHelpFile,
|
||||
DWORD dwHelpContext);
|
||||
};
|
||||
|
||||
//--- ISpGrammarCompiler ----------------------------------------------------
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(B1E29D58-A675-11D2-8302-00C04F8EE6C0),
|
||||
helpstring("ISpGrammarCompiler Interface"),
|
||||
pointer_default(unique),
|
||||
restricted
|
||||
]
|
||||
interface ISpGrammarCompiler : IUnknown
|
||||
{
|
||||
HRESULT CompileStream(
|
||||
IStream * pSource,
|
||||
IStream * pDest,
|
||||
IStream * pHeader,
|
||||
IUnknown * pReserved,
|
||||
ISpErrorLog * pErrorLog,
|
||||
[in] DWORD dwFlags);
|
||||
};
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(3DDCA27C-665C-4786-9F97-8C90C3488B61),
|
||||
helpstring("ISpGramCompBackend Interface"),
|
||||
pointer_default(unique),
|
||||
restricted
|
||||
]
|
||||
interface ISpGramCompBackend : ISpGrammarBuilder
|
||||
{
|
||||
HRESULT SetSaveObjects(IStream * pStream, ISpErrorLog * pErrorLog);
|
||||
|
||||
HRESULT InitFromBinaryGrammar(const SPBINARYGRAMMAR * pBinaryData);
|
||||
};
|
||||
|
||||
|
||||
//--- ISpITNProcessor ----------------------------------------------------------
|
||||
[
|
||||
object,
|
||||
uuid(12D7360F-A1C9-11d3-BC90-00C04F72DF9F),
|
||||
helpstring("ISpITNProcessor Interface"),
|
||||
pointer_default(unique),
|
||||
local,
|
||||
restricted
|
||||
]
|
||||
interface ISpITNProcessor : IUnknown
|
||||
{
|
||||
HRESULT LoadITNGrammar(WCHAR *pszCLSID);
|
||||
HRESULT ITNPhrase(ISpPhraseBuilder *pPhrase);
|
||||
};
|
||||
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(88A3342A-0BED-4834-922B-88D43173162F),
|
||||
local,
|
||||
helpstring("ISpPhraseBuilder Interface"),
|
||||
pointer_default(unique),
|
||||
restricted
|
||||
]
|
||||
interface ISpPhraseBuilder : ISpPhrase
|
||||
{
|
||||
HRESULT InitFromPhrase(const SPPHRASE * pPhrase);
|
||||
HRESULT InitFromSerializedPhrase(const SPSERIALIZEDPHRASE * pPhrase);
|
||||
HRESULT AddElements(ULONG cElements, const SPPHRASEELEMENT *pElement);
|
||||
HRESULT AddRules(const SPPHRASERULEHANDLE hParent, const SPPHRASERULE * pRule, SPPHRASERULEHANDLE * phNewRule);
|
||||
HRESULT AddProperties(const SPPHRASEPROPERTYHANDLE hParent, const SPPHRASEPROPERTY * pProperty, SPPHRASEPROPERTYHANDLE * phNewProperty);
|
||||
HRESULT AddReplacements(ULONG cReplacements, const SPPHRASEREPLACEMENT * pReplacements);
|
||||
};
|
||||
|
||||
|
||||
|
||||
//--- ISpTask ---------------------------------------------------------------
|
||||
|
||||
cpp_quote("#if defined(__cplusplus)")
|
||||
cpp_quote("interface ISpTask")
|
||||
cpp_quote("{")
|
||||
cpp_quote("virtual HRESULT STDMETHODCALLTYPE Execute(")
|
||||
cpp_quote(" void *pvTaskData,")
|
||||
cpp_quote(" volatile const BOOL* pfContinueProcessing) = 0;")
|
||||
cpp_quote("};")
|
||||
cpp_quote("#else")
|
||||
typedef void * ISpTask;
|
||||
cpp_quote("#endif")
|
||||
|
||||
//--- ISpThreadTask ---------------------------------------------------------
|
||||
|
||||
cpp_quote("#if defined(__cplusplus)")
|
||||
cpp_quote("interface ISpThreadTask")
|
||||
cpp_quote("{")
|
||||
cpp_quote("virtual HRESULT STDMETHODCALLTYPE InitThread(")
|
||||
cpp_quote(" void * pvTaskData,")
|
||||
cpp_quote(" HWND hwnd) = 0;")
|
||||
cpp_quote("virtual HRESULT STDMETHODCALLTYPE ThreadProc(")
|
||||
cpp_quote(" void *pvTaskData,")
|
||||
cpp_quote(" HANDLE hExitThreadEvent,")
|
||||
cpp_quote(" HANDLE hNotifyEvent,")
|
||||
cpp_quote(" HWND hwndWorker,")
|
||||
cpp_quote(" volatile const BOOL * pfContinueProcessing) = 0;")
|
||||
cpp_quote("virtual LRESULT STDMETHODCALLTYPE WindowMessage(")
|
||||
cpp_quote(" void *pvTaskData,")
|
||||
cpp_quote(" HWND hWnd,")
|
||||
cpp_quote(" UINT Msg,")
|
||||
cpp_quote(" WPARAM wParam,")
|
||||
cpp_quote(" LPARAM lParam) = 0;")
|
||||
cpp_quote("};")
|
||||
cpp_quote("#else")
|
||||
typedef void * ISpThreadTask;
|
||||
cpp_quote("#endif")
|
||||
|
||||
//--- ISpThreadControl ------------------------------------------------------
|
||||
[
|
||||
object,
|
||||
uuid(A6BE4D73-4403-4358-B22D-0346E23B1764),
|
||||
helpstring("ISpThreadControl Interface"),
|
||||
pointer_default(unique),
|
||||
local,
|
||||
restricted
|
||||
]
|
||||
interface ISpThreadControl : ISpNotifySink
|
||||
{
|
||||
HRESULT StartThread(DWORD dwFlags, HWND * phwnd);
|
||||
HRESULT WaitForThreadDone(
|
||||
BOOL fForceStop,
|
||||
HRESULT * phrThreadResult,
|
||||
ULONG msTimeOut);
|
||||
HRESULT TerminateThread(void);
|
||||
HANDLE ThreadHandle(void);
|
||||
DWORD ThreadId(void);
|
||||
HANDLE NotifyEvent(void);
|
||||
HWND WindowHandle(void);
|
||||
HANDLE ThreadCompleteEvent(void);
|
||||
HANDLE ExitThreadEvent(void);
|
||||
};
|
||||
|
||||
//--- ISpTaskManager --------------------------------------------------------
|
||||
// This interface is used to implement a task managment service provider
|
||||
// to optimize thread usage.
|
||||
|
||||
typedef [restricted] struct SPTMTHREADINFO
|
||||
{
|
||||
long lPoolSize; // Number of threads in pool (-1 default)
|
||||
long lPriority; // Priority of threads in pool
|
||||
ULONG ulConcurrencyLimit; // Number of threads allowed to concurrently execute (0 default)
|
||||
ULONG ulMaxQuickAllocThreads; // Maximum number of dedicated threads retained
|
||||
} SPTMTHREADINFO;
|
||||
|
||||
[
|
||||
local,
|
||||
uuid(2BAEEF81-2CA3-4331-98F3-26EC5ABEFB03),
|
||||
helpstring("ISpTaskManager Interface"),
|
||||
pointer_default(unique),
|
||||
restricted
|
||||
]
|
||||
interface ISpTaskManager : IUnknown
|
||||
{
|
||||
HRESULT SetThreadPoolInfo([in] const SPTMTHREADINFO* pPoolInfo);
|
||||
HRESULT GetThreadPoolInfo([out] SPTMTHREADINFO* pPoolInfo);
|
||||
|
||||
HRESULT QueueTask(
|
||||
[in] ISpTask* pTask,
|
||||
[in] void* pvTaskData,
|
||||
[in] HANDLE hCompEvent,
|
||||
[in, out] DWORD* pdwGroupId,
|
||||
[out] DWORD* pTaskID);
|
||||
HRESULT CreateReoccurringTask(
|
||||
[in] ISpTask* pTask,
|
||||
[in] void* pvTaskData,
|
||||
[in] HANDLE hCompEvent,
|
||||
[out] ISpNotifySink** ppTaskCtrl);
|
||||
HRESULT CreateThreadControl(
|
||||
[in] ISpThreadTask* pTask,
|
||||
[in] void* pvTaskData,
|
||||
[in] long nPriority,
|
||||
[out] ISpThreadControl** ppTaskCtrl);
|
||||
|
||||
HRESULT TerminateTask([in] DWORD dwTaskId, [in] ULONG ulWaitPeriod);
|
||||
HRESULT TerminateTaskGroup([in] DWORD dwGroupId, [in] ULONG ulWaitPeriod);
|
||||
};
|
||||
|
||||
|
||||
//--- ISpTTSEngineSite ------------------------------------------------------
|
||||
|
||||
typedef enum SPVSKIPTYPE
|
||||
{
|
||||
SPVST_SENTENCE = (1L << 0) // Skip sentences
|
||||
} SPVSKIPTYPE;
|
||||
|
||||
typedef enum SPVESACTIONS
|
||||
{
|
||||
SPVES_CONTINUE = 0,
|
||||
SPVES_ABORT = ( 1L << 0 ),
|
||||
SPVES_SKIP = ( 1L << 1 ),
|
||||
SPVES_RATE = ( 1L << 2 ),
|
||||
SPVES_VOLUME = ( 1L << 3 )
|
||||
} SPVESACTIONS;
|
||||
|
||||
[
|
||||
object,
|
||||
local,
|
||||
uuid(9880499B-CCE9-11d2-B503-00C04F797396),
|
||||
helpstring("ISpTTSEngineSite Interface"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface ISpTTSEngineSite : ISpEventSink
|
||||
{
|
||||
DWORD GetActions( void );
|
||||
HRESULT Write( [in]const void* pBuff, [in]ULONG cb, [out]ULONG *pcbWritten );
|
||||
HRESULT GetRate( [out]long* pRateAdjust );
|
||||
HRESULT GetVolume( [out]USHORT* pusVolume );
|
||||
HRESULT GetSkipInfo( [out]SPVSKIPTYPE* peType, [out]long* plNumItems );
|
||||
HRESULT CompleteSkip( [in]long ulNumSkipped );
|
||||
};
|
||||
|
||||
//--- ISpTTSEngine ----------------------------------------------------------
|
||||
|
||||
typedef struct SPVTEXTFRAG
|
||||
{
|
||||
struct SPVTEXTFRAG* pNext; // Next text fragment in list, NULL == end of list
|
||||
SPVSTATE State; // Current XML attribute state
|
||||
LPCWSTR pTextStart;
|
||||
ULONG ulTextLen;
|
||||
ULONG ulTextSrcOffset; // Original source position of the fragment text
|
||||
} SPVTEXTFRAG;
|
||||
|
||||
[
|
||||
object,
|
||||
local,
|
||||
uuid(A74D7C8E-4CC5-4f2f-A6EB-804DEE18500E),
|
||||
helpstring("ISpTTSEngine Interface"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface ISpTTSEngine : IUnknown
|
||||
{
|
||||
HRESULT Speak( [in]DWORD dwSpeakFlags,
|
||||
[in]REFGUID rguidFormatId, [in]const WAVEFORMATEX * pWaveFormatEx,
|
||||
[in]const SPVTEXTFRAG* pTextFragList, [in]ISpTTSEngineSite* pOutputSite );
|
||||
HRESULT GetOutputFormat( [in] const GUID * pTargetFmtId, [in] const WAVEFORMATEX * pTargetWaveFormatEx,
|
||||
[out] GUID * pOutputFormatId, [out] WAVEFORMATEX ** ppCoMemOutputWaveFormatEx);
|
||||
};
|
||||
|
||||
|
||||
|
||||
//--- SR Engine data structures ----------------------------------------
|
||||
|
||||
|
||||
typedef [restricted] struct SPWORDENTRY
|
||||
{
|
||||
SPWORDHANDLE hWord;
|
||||
LANGID LangID;
|
||||
WCHAR * pszDisplayText;
|
||||
WCHAR * pszLexicalForm;
|
||||
SPPHONEID * aPhoneId;
|
||||
void * pvClientContext;
|
||||
} SPWORDENTRY;
|
||||
|
||||
typedef [restricted] struct SPRULEENTRY
|
||||
{
|
||||
SPRULEHANDLE hRule;
|
||||
SPSTATEHANDLE hInitialState;
|
||||
DWORD Attributes; // SPCFGRULEATTRIBUTES
|
||||
void * pvClientRuleContext;
|
||||
void * pvClientGrammarContext;
|
||||
} SPRULEENTRY;
|
||||
|
||||
typedef enum SPTRANSITIONTYPE
|
||||
{
|
||||
SPTRANSEPSILON,
|
||||
SPTRANSWORD,
|
||||
SPTRANSRULE,
|
||||
SPTRANSTEXTBUF,
|
||||
SPTRANSWILDCARD,
|
||||
SPTRANSDICTATION
|
||||
} SPTRANSITIONTYPE;
|
||||
|
||||
typedef [restricted] struct SPTRANSITIONENTRY
|
||||
{
|
||||
SPTRANSITIONID ID;
|
||||
SPSTATEHANDLE hNextState;
|
||||
BYTE Type; // SPTRANSITIONTYPE
|
||||
char RequiredConfidence;
|
||||
struct
|
||||
{
|
||||
DWORD fHasProperty; // Boolean type
|
||||
};
|
||||
float Weight;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
SPSTATEHANDLE hRuleInitialState; // Only if Type == SPTRANSRULE
|
||||
SPRULEHANDLE hRule;
|
||||
void * pvClientRuleContext;
|
||||
};
|
||||
struct
|
||||
{
|
||||
SPWORDHANDLE hWord; // Only if Type == SPTRANSWORD
|
||||
void * pvClientWordContext;
|
||||
};
|
||||
struct
|
||||
{
|
||||
void * pvGrammarCookie; // Only if Type == SPTRANSTEXTBUF or SPTRANSWILDCARD or SPTRANSDICTATION
|
||||
};
|
||||
};
|
||||
} SPTRANSITIONENTRY;
|
||||
|
||||
typedef [restricted] struct SPTRANSITIONPROPERTY
|
||||
{
|
||||
const WCHAR * pszName;
|
||||
ULONG ulId;
|
||||
const WCHAR * pszValue;
|
||||
VARIANT vValue; // Will be VT_BOOL, VT_I4, VT_R4, VT_R8, or VT_BYREF (only for dynamic grammars)
|
||||
} SPTRANSITIONPROPERTY;
|
||||
|
||||
typedef [restricted] struct SPSTATEINFO
|
||||
{
|
||||
ULONG cAllocatedEntries;
|
||||
SPTRANSITIONENTRY * pTransitions;
|
||||
ULONG cEpsilons;
|
||||
ULONG cRules;
|
||||
ULONG cWords;
|
||||
ULONG cSpecialTransitions;
|
||||
} SPSTATEINFO;
|
||||
|
||||
typedef [restricted] struct SPPATHENTRY
|
||||
{
|
||||
SPTRANSITIONID hTransition;
|
||||
SPPHRASEELEMENT elem;
|
||||
} SPPATHENTRY;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//--- ISpCFGInterpreterSite -------------------------------------------------
|
||||
[
|
||||
object,
|
||||
uuid(6A6FFAD8-78B6-473d-B844-98152E4FB16B),
|
||||
helpstring("ISpCFGInterpreterSite Interface"),
|
||||
pointer_default(unique),
|
||||
local,
|
||||
restricted
|
||||
]
|
||||
interface ISpCFGInterpreterSite : IUnknown
|
||||
{
|
||||
HRESULT AddTextReplacement([in] SPPHRASEREPLACEMENT * pReplace);
|
||||
HRESULT AddProperty([in] const SPPHRASEPROPERTY *pProperty);
|
||||
HRESULT GetResourceValue(
|
||||
[in] const WCHAR *pszResourceName,
|
||||
[out] WCHAR ** ppCoMemResource);
|
||||
};
|
||||
|
||||
|
||||
//--- ISpCFGInterpreter -----------------------------------------------------
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(F3D3F926-11FC-11d3-BB97-00C04F8EE6C0),
|
||||
helpstring("ISpCFGInterpreter Interface"),
|
||||
pointer_default(unique),
|
||||
local,
|
||||
restricted
|
||||
]
|
||||
interface ISpCFGInterpreter : IUnknown
|
||||
{
|
||||
HRESULT InitGrammar(
|
||||
[in] const WCHAR * pszGrammarName,
|
||||
[in] const void ** pvGrammarData);
|
||||
HRESULT Interpret(
|
||||
[in] ISpPhraseBuilder * pPhrase,
|
||||
[in] const ULONG ulFirstElement,
|
||||
[in] const ULONG ulCountOfElements,
|
||||
[in] ISpCFGInterpreterSite * pSite);
|
||||
};
|
||||
|
||||
|
||||
typedef enum SPCFGNOTIFY
|
||||
{
|
||||
SPCFGN_ADD,
|
||||
SPCFGN_REMOVE,
|
||||
SPCFGN_INVALIDATE,
|
||||
SPCFGN_ACTIVATE,
|
||||
SPCFGN_DEACTIVATE
|
||||
} SPCFGNOTIFY;
|
||||
|
||||
//--- ISpSREngineSite -------------------------------------------------------
|
||||
|
||||
typedef enum SPRESULTTYPE
|
||||
{
|
||||
SPRT_CFG = 0,
|
||||
SPRT_SLM = 1,
|
||||
SPRT_PROPRIETARY = 2,
|
||||
SPRT_FALSE_RECOGNITION = ( 1L << 2 ) // Flag used to indicate a false recognition
|
||||
} SPRESULTTYPE;
|
||||
|
||||
typedef struct tagSPPHRASEALT
|
||||
{
|
||||
ISpPhraseBuilder * pPhrase;
|
||||
ULONG ulStartElementInParent;
|
||||
ULONG cElementsInParent;
|
||||
ULONG cElementsInAlternate;
|
||||
void * pvAltExtra;
|
||||
ULONG cbAltExtra;
|
||||
} SPPHRASEALT;
|
||||
|
||||
// Result structure passed from engine to SAPI
|
||||
typedef struct SPRECORESULTINFO
|
||||
{
|
||||
ULONG cbSize; // Total size of this structure
|
||||
SPRESULTTYPE eResultType; // Type of result object (CFG, SLM, or Proprietary)
|
||||
BOOL fHypothesis; // If true then this recognition is a hypothesis
|
||||
BOOL fProprietaryAutoPause;// This field is only used for SPERT_PROPRIETARY grammars. If true, recognition will pause.
|
||||
ULONGLONG ullStreamPosStart; // Start and end stream positions of recognition
|
||||
ULONGLONG ullStreamPosEnd;
|
||||
SPGRAMMARHANDLE hGrammar; // Required for SPERT_SLM and SPERT_PROPRIETARY else NULL
|
||||
ULONG ulSizeEngineData; // Size of pvEngineData
|
||||
void * pvEngineData; // Extra engine specific data
|
||||
ISpPhraseBuilder* pPhrase; // Pointer to phrase object
|
||||
SPPHRASEALT* aPhraseAlts; // Alternates array
|
||||
ULONG ulNumAlts; // Number of alternates in the array
|
||||
} SPRECORESULTINFO;
|
||||
|
||||
typedef enum SPWORDINFOOPT
|
||||
{
|
||||
SPWIO_NONE = 0,
|
||||
SPWIO_WANT_TEXT = 1
|
||||
} SPWORDINFOOPT;
|
||||
|
||||
|
||||
typedef enum SPRULEINFOOPT
|
||||
{
|
||||
SPRIO_NONE = 0,
|
||||
} SPRULEINFOOPT;
|
||||
|
||||
typedef struct SPPARSEINFO
|
||||
{
|
||||
ULONG cbSize;
|
||||
SPRULEHANDLE hRule;
|
||||
ULONGLONG ullAudioStreamPosition;
|
||||
ULONG ulAudioSize;
|
||||
ULONG cTransitions;
|
||||
SPPATHENTRY * pPath;
|
||||
GUID SREngineID;
|
||||
ULONG ulSREnginePrivateDataSize;
|
||||
const BYTE * pSREnginePrivateData;
|
||||
BOOL fHypothesis;
|
||||
} SPPARSEINFO;
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(3B414AEC-720C-4883-B9EF-178CD394FB3A),
|
||||
helpstring("ISpSREngineSite Interface"),
|
||||
pointer_default(unique),
|
||||
local
|
||||
]
|
||||
interface ISpSREngineSite : IUnknown
|
||||
{
|
||||
HRESULT Read([in] void * pv, [in] ULONG cb, [out] ULONG * pcbRead);
|
||||
HRESULT DataAvailable(ULONG * pcb);
|
||||
HRESULT SetBufferNotifySize([in] ULONG cbSize);
|
||||
HRESULT ParseFromTransitions([in] const SPPARSEINFO * pParseInfo,
|
||||
[out] ISpPhraseBuilder ** ppNewPhrase);
|
||||
HRESULT Recognition([in] const SPRECORESULTINFO * pResultInfo);
|
||||
HRESULT AddEvent([in] const SPEVENT* pEvent, [in] SPRECOCONTEXTHANDLE hSAPIRecoContext);
|
||||
HRESULT Synchronize([in] ULONGLONG ullProcessedThruPos);
|
||||
HRESULT GetWordInfo([in, out] SPWORDENTRY * pWordEntry, [in] SPWORDINFOOPT Options); // Caller must fill in hWord. if fWantWordText then caller must CoTaskMemFree the pszWord.
|
||||
HRESULT SetWordClientContext(SPWORDHANDLE hWord, void * pvClientContext);
|
||||
HRESULT GetRuleInfo([in, out] SPRULEENTRY * pRuleEntry, [in] SPRULEINFOOPT Options); // Caller must fill in hRule.SPRULEHANDLE hRule, BOOL * pfActive, BOOL *pfAutoPause, SPSTATEHANDLE * phInitialState, void ** ppvClientContext);
|
||||
HRESULT SetRuleClientContext(SPRULEHANDLE hRule, void * pvClientContext);
|
||||
HRESULT GetStateInfo(SPSTATEHANDLE hState, SPSTATEINFO * pStateInfo);
|
||||
HRESULT GetResource( [in] SPRULEHANDLE hRule, [in] const WCHAR *pszResourceName, [out] WCHAR ** ppCoMemResource );
|
||||
HRESULT GetTransitionProperty([in] SPTRANSITIONID ID, [out] SPTRANSITIONPROPERTY **ppCoMemProperty);
|
||||
HRESULT IsAlternate( [in]SPRULEHANDLE hRule, [in]SPRULEHANDLE hAltRule );
|
||||
HRESULT GetMaxAlternates( [in]SPRULEHANDLE hRule, [out]ULONG* pulNumAlts );
|
||||
HRESULT GetContextMaxAlternates( [in] SPRECOCONTEXTHANDLE hContext, [out] ULONG * pulNumAlts);
|
||||
HRESULT UpdateRecoPos([in] ULONGLONG ullCurrentRecoPos);
|
||||
};
|
||||
|
||||
//--- ISpSREngine -----------------------------------------------------------
|
||||
typedef enum SPPROPSRC
|
||||
{
|
||||
SPPROPSRC_RECO_INST,
|
||||
SPPROPSRC_RECO_CTX,
|
||||
SPPROPSRC_RECO_GRAMMAR
|
||||
} SPPROPSRC;
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(2F472991-854B-4465-B613-FBAFB3AD8ED8),
|
||||
helpstring("ISpSREngine Interface"),
|
||||
pointer_default(unique),
|
||||
local
|
||||
]
|
||||
interface ISpSREngine : IUnknown
|
||||
{
|
||||
HRESULT SetSite([in] ISpSREngineSite *pSite);
|
||||
|
||||
HRESULT GetInputAudioFormat(
|
||||
[in] const GUID * pguidSourceFormatId,
|
||||
[in] const WAVEFORMATEX * pSourceWaveFormatEx,
|
||||
[out] GUID * pguidDesiredFormatId,
|
||||
[out] WAVEFORMATEX ** ppCoMemDesiredWaveFormatEx);
|
||||
|
||||
HRESULT RecognizeStream([in] REFGUID rguidFmtId, [in] const WAVEFORMATEX * pWaveFormatEx,
|
||||
[in] HANDLE hRequestSync, [in] HANDLE hDataAvailable,
|
||||
[in] HANDLE hExit, [in] BOOL fNewAudioStream, [in] BOOL fRealTimeAudio,
|
||||
[in] ISpObjectToken * pAudioObjectToken);
|
||||
|
||||
HRESULT SetRecoProfile(ISpObjectToken * pProfile);
|
||||
|
||||
HRESULT OnCreateGrammar([in] void * pvEngineRecoContext,
|
||||
[in] SPGRAMMARHANDLE hSAPIGrammar,
|
||||
[out] void ** ppvEngineGrammarContext);
|
||||
|
||||
HRESULT OnDeleteGrammar([in] void * pvEngineGrammar);
|
||||
|
||||
HRESULT LoadProprietaryGrammar(
|
||||
[in] void * pvEngineGrammar,
|
||||
[in] REFGUID rguidParam,
|
||||
[in, string] const WCHAR * pszStringParam,
|
||||
[in] const void * pvDataParam,
|
||||
[in] ULONG ulDataSize,
|
||||
[in] SPLOADOPTIONS Options); // Note for SAPI 5.0 this is always SPLO_NONE
|
||||
|
||||
HRESULT UnloadProprietaryGrammar([in] void * pvEngineGrammar);
|
||||
|
||||
HRESULT SetProprietaryRuleState([in] void * pvEngineGrammar,
|
||||
[in, string] const WCHAR * pszName,
|
||||
[in] void * pReserved,
|
||||
[in] SPRULESTATE NewState,
|
||||
[out] ULONG * pcRulesChanged);
|
||||
HRESULT SetProprietaryRuleIdState([in] void * pvEngineGrammar,
|
||||
[in] DWORD dwRuleId,
|
||||
[in] SPRULESTATE NewState);
|
||||
HRESULT LoadSLM([in] void * pvEngineGrammar, [in, string] const WCHAR * pszTopicName);
|
||||
HRESULT UnloadSLM([in] void * pvEngineGrammar);
|
||||
HRESULT SetSLMState([in] void * pvEngineGrammar, [in] SPRULESTATE NewState);
|
||||
HRESULT SetWordSequenceData([in] void * pvEngineGrammar, [in] const WCHAR * pText, [in] ULONG cchText, [in] const SPTEXTSELECTIONINFO * pInfo);
|
||||
HRESULT SetTextSelection([in] void * pvEngineGrammar, [in] const SPTEXTSELECTIONINFO * pInfo);
|
||||
HRESULT IsPronounceable([in] void * pvEngineGrammar, [in, string] const WCHAR * pszWord, [out] SPWORDPRONOUNCEABLE *pWordPronounceable);
|
||||
|
||||
HRESULT OnCreateRecoContext(
|
||||
[in] SPRECOCONTEXTHANDLE hSAPIRecoContext,
|
||||
[out] void ** ppvEngineContext);
|
||||
HRESULT OnDeleteRecoContext([in] void * pvEngineContext);
|
||||
|
||||
HRESULT PrivateCall([in] void * pvEngineContext, [in, out] PVOID pCallFrame, [in] ULONG ulCallFrameSize);
|
||||
|
||||
HRESULT SetAdaptationData([in] void * pvEngineContext, const WCHAR *pAdaptationData, const ULONG cch);
|
||||
|
||||
HRESULT SetPropertyNum( [in]SPPROPSRC eSrc, [in]void* pvSrcObj,
|
||||
[in]const WCHAR* pName, [in]LONG lValue );
|
||||
HRESULT GetPropertyNum( [in]SPPROPSRC eSrc, [in]void* pvSrcObj,
|
||||
[in]const WCHAR* pName, [out]LONG* lValue );
|
||||
HRESULT SetPropertyString( [in]SPPROPSRC eSrc, [in]void* pvSrcObj,
|
||||
[in]const WCHAR* pName, [in]const WCHAR* pValue );
|
||||
HRESULT GetPropertyString( [in]SPPROPSRC eSrc, [in]void* pvSrcObj,
|
||||
[in]const WCHAR* pName, [out]WCHAR** ppCoMemValue );
|
||||
|
||||
HRESULT SetGrammarState([in] void * pvEngineGrammar, [in] SPGRAMMARSTATE eGrammarState);
|
||||
|
||||
HRESULT WordNotify(SPCFGNOTIFY Action, ULONG cWords, const SPWORDENTRY * pWords);
|
||||
HRESULT RuleNotify(SPCFGNOTIFY Action, ULONG cRules, const SPRULEENTRY * pRules);
|
||||
|
||||
HRESULT PrivateCallEx([in] void * pvEngineContext, [in] const void * pInCallFrame, [in] ULONG ulInCallFrameSize,
|
||||
[out] void ** ppvCoMemResponse, [out] ULONG * pulResponseSize);
|
||||
|
||||
HRESULT SetContextState([in] void * pvEngineContext, [in] SPCONTEXTSTATE eContextState);
|
||||
};
|
||||
|
||||
|
||||
//--- ISpSRAlternates
|
||||
|
||||
typedef struct tagSPPHRASEALTREQUEST
|
||||
{
|
||||
ULONG ulStartElement;
|
||||
ULONG cElements;
|
||||
ULONG ulRequestAltCount;
|
||||
|
||||
void * pvResultExtra;
|
||||
ULONG cbResultExtra;
|
||||
|
||||
ISpPhrase * pPhrase;
|
||||
ISpRecoContext * pRecoContext;
|
||||
} SPPHRASEALTREQUEST;
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(FECE8294-2BE1-408f-8E68-2DE377092F0E),
|
||||
helpstring("ISpSRAlternates Interface"),
|
||||
pointer_default(unique),
|
||||
local
|
||||
]
|
||||
interface ISpSRAlternates : IUnknown
|
||||
{
|
||||
HRESULT GetAlternates([in] SPPHRASEALTREQUEST * pAltRequest,
|
||||
[out] SPPHRASEALT **ppAlts,
|
||||
[out] ULONG *pcAlts);
|
||||
HRESULT Commit([in] SPPHRASEALTREQUEST * pAltRequest,
|
||||
[in] SPPHRASEALT * pAlt,
|
||||
[out] void **ppvResultExtra,
|
||||
[out] ULONG *pcbResultExtra);
|
||||
}
|
||||
|
||||
// Interface used by engine specific recoctxt extension object to call into engine
|
||||
[
|
||||
object,
|
||||
uuid(8E7C791E-4467-11d3-9723-00C04F72DB08),
|
||||
helpstring("_ISpPrivateEngineCall Interface"),
|
||||
pointer_default(unique),
|
||||
local
|
||||
]
|
||||
interface _ISpPrivateEngineCall : IUnknown
|
||||
{
|
||||
HRESULT CallEngine([in, out] void * pCallFrame, [in] ULONG ulCallFrameSize);
|
||||
HRESULT CallEngineEx([in] const void * pInFrame, [in] ULONG ulInFrameSize,
|
||||
[out] void ** ppCoMemOutFrame, [out] ULONG * pulOutFrameSize);
|
||||
}
|
||||
|
||||
//
|
||||
//--- CoClass definitions ---------------------------------------------------
|
||||
//
|
||||
|
||||
[
|
||||
helpstring("Microsoft Speech Object DDK Library"),
|
||||
uuid(9903F14C-12CE-4c99-9986-2EE3D7D588A8),
|
||||
version(5.0)
|
||||
]
|
||||
library SpeechDDKLib
|
||||
{
|
||||
importlib("stdole32.tlb");
|
||||
importlib("stdole2.tlb");
|
||||
|
||||
//--- SpDataKey ---------------------------------------------------------
|
||||
[
|
||||
uuid(D9F6EE60-58C9-458b-88E1-2F908FD7F87C),
|
||||
helpstring("Data Key")
|
||||
]
|
||||
coclass SpDataKey
|
||||
{
|
||||
interface ISpRegDataKey;
|
||||
[default] interface ISpDataKey;
|
||||
}
|
||||
|
||||
//--- SpObjectTokenEnum --------------------------------------------------
|
||||
[
|
||||
uuid(3918D75F-0ACB-41f2-B733-92AA15BCECF6),
|
||||
helpstring("Object Token Enumerator")
|
||||
]
|
||||
coclass SpObjectTokenEnum
|
||||
{
|
||||
interface ISpObjectTokenEnumBuilder;
|
||||
[default] interface IEnumSpObjectTokens;
|
||||
}
|
||||
|
||||
//--- SpPhraseBuilder ---------------------------------------------------
|
||||
[
|
||||
uuid(777B6BBD-2FF2-11d3-88FE-00C04F8EF9B5),
|
||||
helpstring("Phrase Builder Class")
|
||||
]
|
||||
coclass SpPhraseBuilder
|
||||
{
|
||||
[default] interface ISpPhraseBuilder;
|
||||
}
|
||||
//--- SpITNProcessor ----------------------------------------------------
|
||||
[
|
||||
uuid(12D73610-A1C9-11d3-BC90-00C04F72DF9F),
|
||||
helpstring("SpITNProcessor Class"),
|
||||
restricted
|
||||
]
|
||||
coclass SpITNProcessor
|
||||
{
|
||||
[default] interface ISpITNProcessor;
|
||||
};
|
||||
//--- SpGrammarCompiler ---------------------------------------------
|
||||
[
|
||||
uuid(B1E29D59-A675-11D2-8302-00C04F8EE6C0),
|
||||
helpstring("Microsoft Speech Grammar Compiler")
|
||||
]
|
||||
coclass SpGrammarCompiler
|
||||
{
|
||||
[default] interface ISpGrammarCompiler;
|
||||
};
|
||||
|
||||
//--- SpGramCompBackend ---------------------------------------------
|
||||
[
|
||||
uuid(DA93E903-C843-11D2-A084-00C04F8EF9B5),
|
||||
helpstring("Grammar Class"),
|
||||
restricted
|
||||
]
|
||||
coclass SpGramCompBackend
|
||||
{
|
||||
[default] interface ISpGramCompBackend;
|
||||
};
|
||||
|
||||
}
|
854
speech2/third_party/sapi5/include/Spddkhlp.h
vendored
Normal file
854
speech2/third_party/sapi5/include/Spddkhlp.h
vendored
Normal file
|
@ -0,0 +1,854 @@
|
|||
/*******************************************************************************
|
||||
* SPDDKHLP.h *
|
||||
*------------*
|
||||
* Description:
|
||||
* This is the header file for core helper functions implementation.
|
||||
*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
*
|
||||
*******************************************************************************/
|
||||
#ifndef SPDDKHLP_h
|
||||
#define SPDDKHLP_h
|
||||
|
||||
#ifndef SPHelper_h
|
||||
#include <sphelper.h>
|
||||
#endif
|
||||
|
||||
#include <sapiddk.h>
|
||||
|
||||
#ifndef SPError_h
|
||||
#include <SPError.h>
|
||||
#endif
|
||||
|
||||
#ifndef SPDebug_h
|
||||
#include <SPDebug.h>
|
||||
#endif
|
||||
|
||||
#ifndef _INC_LIMITS
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifndef _INC_CRTDBG
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
#ifndef _INC_MALLOC
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#ifndef _INC_MMSYSTEM
|
||||
#include <mmsystem.h>
|
||||
#endif
|
||||
|
||||
#ifndef __comcat_h__
|
||||
#include <comcat.h>
|
||||
#endif
|
||||
|
||||
//=== Constants ==============================================================
|
||||
#define sp_countof(x) ((sizeof(x) / sizeof(*(x))))
|
||||
|
||||
#define SP_IS_BAD_WRITE_PTR(p) ( SPIsBadWritePtr( p, sizeof(*(p)) ))
|
||||
#define SP_IS_BAD_READ_PTR(p) ( SPIsBadReadPtr( p, sizeof(*(p)) ))
|
||||
#define SP_IS_BAD_CODE_PTR(p) ( ::IsBadCodePtr((FARPROC)(p) )
|
||||
#define SP_IS_BAD_INTERFACE_PTR(p) ( SPIsBadInterfacePtr( (p) ) )
|
||||
#define SP_IS_BAD_VARIANT_PTR(p) ( SPIsBadVARIANTPtr( (p) ) )
|
||||
#define SP_IS_BAD_STRING_PTR(p) ( SPIsBadStringPtr( (p) ) )
|
||||
|
||||
#define SP_IS_BAD_OPTIONAL_WRITE_PTR(p) ((p) && SPIsBadWritePtr( p, sizeof(*(p)) ))
|
||||
#define SP_IS_BAD_OPTIONAL_READ_PTR(p) ((p) && SPIsBadReadPtr( p, sizeof(*(p)) ))
|
||||
#define SP_IS_BAD_OPTIONAL_INTERFACE_PTR(p) ((p) && SPIsBadInterfacePtr(p))
|
||||
#define SP_IS_BAD_OPTIONAL_STRING_PTR(p) ((p) && SPIsBadStringPtr(p))
|
||||
|
||||
//=== Class, Enum, Struct, Template, and Union Declarations ==================
|
||||
|
||||
//=== Inlines ================================================================
|
||||
|
||||
/*** Pointer validation functions
|
||||
*/
|
||||
|
||||
// TODO: Add decent debug output for bad parameters
|
||||
|
||||
inline BOOL SPIsBadStringPtr( const WCHAR * psz, ULONG cMaxChars = 0xFFFF )
|
||||
{
|
||||
BOOL IsBad = false;
|
||||
__try
|
||||
{
|
||||
do
|
||||
{
|
||||
if( *psz++ == 0 ) return IsBad;
|
||||
}
|
||||
while( --cMaxChars );
|
||||
}
|
||||
__except( GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION )
|
||||
{
|
||||
IsBad = true;
|
||||
}
|
||||
|
||||
return IsBad;
|
||||
}
|
||||
|
||||
inline BOOL SPIsBadReadPtr( const void* pMem, UINT Size )
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
BOOL bIsBad = ::IsBadReadPtr( pMem, Size );
|
||||
SPDBG_ASSERT(!bIsBad);
|
||||
return bIsBad;
|
||||
#else
|
||||
return ::IsBadReadPtr( pMem, Size );
|
||||
#endif
|
||||
}
|
||||
|
||||
inline BOOL SPIsBadWritePtr( void* pMem, UINT Size )
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
BOOL bIsBad = ::IsBadWritePtr( pMem, Size );
|
||||
SPDBG_ASSERT(!bIsBad);
|
||||
return bIsBad;
|
||||
#else
|
||||
return ::IsBadWritePtr( pMem, Size );
|
||||
#endif
|
||||
}
|
||||
|
||||
inline BOOL SPIsBadInterfacePtr( const IUnknown* pUnknown )
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
BOOL bIsBad = ( ::IsBadReadPtr( pUnknown, sizeof( *pUnknown ) ) ||
|
||||
::IsBadCodePtr( (FARPROC)((void**)pUnknown)[0] ))?
|
||||
(true):(false);
|
||||
SPDBG_ASSERT(!bIsBad);
|
||||
return bIsBad;
|
||||
#else
|
||||
return ( ::IsBadReadPtr( pUnknown, sizeof( *pUnknown ) ) ||
|
||||
::IsBadCodePtr( (FARPROC)((void**)pUnknown)[0] ))?
|
||||
(true):(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline BOOL SPIsBadVARIANTPtr( const VARIANT* pVar )
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
BOOL bIsBad = ::IsBadReadPtr( pVar, sizeof( *pVar ) );
|
||||
SPDBG_ASSERT(!bIsBad);
|
||||
return bIsBad;
|
||||
#else
|
||||
return ::IsBadReadPtr( pVar, sizeof( *pVar ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __ATLCOM_H__ //--- Only enable these if ATL is being used
|
||||
|
||||
//
|
||||
// Helper functions can be used to implement GetObjectToken/SetObjectToken for objects that
|
||||
// support ISpObjectWithToken
|
||||
//
|
||||
inline HRESULT SpGenericSetObjectToken(ISpObjectToken * pCallersToken, CComPtr<ISpObjectToken> & cpObjToken)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (SP_IS_BAD_INTERFACE_PTR(pCallersToken))
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cpObjToken)
|
||||
{
|
||||
hr = SPERR_ALREADY_INITIALIZED;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpObjToken = pCallersToken;
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
inline HRESULT SpGenericGetObjectToken(ISpObjectToken ** ppCallersToken, CComPtr<ISpObjectToken> & cpObjToken)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (SP_IS_BAD_WRITE_PTR(ppCallersToken))
|
||||
{
|
||||
hr = E_POINTER;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppCallersToken = cpObjToken;
|
||||
if (*ppCallersToken)
|
||||
{
|
||||
(*ppCallersToken)->AddRef();
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = S_FALSE;
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
#endif // __ATLCOM_H__
|
||||
|
||||
|
||||
//
|
||||
// Helper class for SPSTATEINFO sturcture automatically initializes and cleans up
|
||||
// the structure + provides a few helper functions.
|
||||
//
|
||||
class CSpStateInfo : public SPSTATEINFO
|
||||
{
|
||||
public:
|
||||
CSpStateInfo()
|
||||
{
|
||||
cAllocatedEntries = NULL;
|
||||
pTransitions = NULL;
|
||||
}
|
||||
~CSpStateInfo()
|
||||
{
|
||||
::CoTaskMemFree(pTransitions);
|
||||
}
|
||||
SPTRANSITIONENTRY * FirstEpsilon()
|
||||
{
|
||||
return pTransitions;
|
||||
}
|
||||
SPTRANSITIONENTRY * FirstRule()
|
||||
{
|
||||
return pTransitions + cEpsilons;
|
||||
}
|
||||
SPTRANSITIONENTRY * FirstWord()
|
||||
{
|
||||
return pTransitions + cEpsilons + cRules;
|
||||
}
|
||||
SPTRANSITIONENTRY * FirstSpecialTransition()
|
||||
{
|
||||
return pTransitions + cEpsilons + cRules + cWords;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// This basic queue implementation can be used to maintin linked lists of classes. The class T
|
||||
// must contain the member m_pNext which is used by this template to point to the next element.
|
||||
// If the bPurgeWhenDeleted is TRUE then all of the elements in the queue will be deleted
|
||||
// when the queue is deleted, otherwise they will not.
|
||||
// If bMaintainCount is TRUE then a running count will be maintained, and GetCount() will be
|
||||
// efficent. If it is FALSE then a running count will not be maintained, and GetCount() will
|
||||
// be an order N operation. If you do not require a count, then
|
||||
//
|
||||
|
||||
template <class T, BOOL bPurgeWhenDeleted> class CSpBasicList;
|
||||
|
||||
template <class T, BOOL bPurgeWhenDeleted = TRUE, BOOL bMaintainCount = FALSE>
|
||||
class CSpBasicQueue
|
||||
{
|
||||
public:
|
||||
T * m_pHead;
|
||||
T * m_pTail;
|
||||
ULONG m_cElements; // Warning! Use GetCount() -- Not maintained if bMaintainCount is FALSE.
|
||||
|
||||
CSpBasicQueue()
|
||||
{
|
||||
m_pHead = NULL;
|
||||
if (bMaintainCount)
|
||||
{
|
||||
m_cElements = 0;
|
||||
}
|
||||
}
|
||||
|
||||
~CSpBasicQueue()
|
||||
{
|
||||
if (bPurgeWhenDeleted)
|
||||
{
|
||||
Purge();
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CreateNode(T ** ppNode)
|
||||
{
|
||||
*ppNode = new T;
|
||||
if (*ppNode)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
T * GetNext(const T * pNode)
|
||||
{
|
||||
return pNode->m_pNext;
|
||||
}
|
||||
|
||||
|
||||
T * Item(ULONG i)
|
||||
{
|
||||
T * pNode = m_pHead;
|
||||
while (pNode && i)
|
||||
{
|
||||
i--;
|
||||
pNode = pNode->m_pNext;
|
||||
}
|
||||
return pNode;
|
||||
}
|
||||
|
||||
void InsertAfter(T * pPrev, T * pNewNode)
|
||||
{
|
||||
if (pPrev)
|
||||
{
|
||||
pNewNode->m_pNext = pPrev->m_pNext;
|
||||
pPrev->m_pNext = pNewNode;
|
||||
if (pNewNode->m_pNext == NULL)
|
||||
{
|
||||
m_pTail = pNewNode;
|
||||
}
|
||||
if (bMaintainCount) ++m_cElements;
|
||||
}
|
||||
else
|
||||
{
|
||||
InsertHead(pNewNode);
|
||||
}
|
||||
}
|
||||
|
||||
void InsertTail(T * pNode)
|
||||
{
|
||||
pNode->m_pNext = NULL;
|
||||
if (m_pHead)
|
||||
{
|
||||
m_pTail->m_pNext = pNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pHead = pNode;
|
||||
}
|
||||
m_pTail = pNode;
|
||||
if (bMaintainCount) ++m_cElements;
|
||||
}
|
||||
|
||||
void InsertHead(T * pNode)
|
||||
{
|
||||
pNode->m_pNext = m_pHead;
|
||||
if (m_pHead == NULL)
|
||||
{
|
||||
m_pTail = pNode;
|
||||
}
|
||||
m_pHead = pNode;
|
||||
if (bMaintainCount) ++m_cElements;
|
||||
}
|
||||
|
||||
T * RemoveHead()
|
||||
{
|
||||
T * pNode = m_pHead;
|
||||
if (pNode)
|
||||
{
|
||||
m_pHead = pNode->m_pNext;
|
||||
if (bMaintainCount) --m_cElements;
|
||||
}
|
||||
return pNode;
|
||||
}
|
||||
|
||||
T * RemoveTail()
|
||||
{
|
||||
T * pNode = m_pHead;
|
||||
if (pNode)
|
||||
{
|
||||
if (pNode == m_pTail)
|
||||
{
|
||||
m_pHead = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
T * pPrev;
|
||||
do
|
||||
{
|
||||
pPrev = pNode;
|
||||
pNode = pNode->m_pNext;
|
||||
} while ( pNode != m_pTail );
|
||||
pPrev->m_pNext = NULL;
|
||||
m_pTail = pPrev;
|
||||
}
|
||||
if (bMaintainCount) --m_cElements;
|
||||
}
|
||||
return pNode;
|
||||
}
|
||||
|
||||
void Purge()
|
||||
{
|
||||
while (m_pHead)
|
||||
{
|
||||
T * pDie = m_pHead;
|
||||
m_pHead = pDie->m_pNext;
|
||||
delete pDie;
|
||||
}
|
||||
if (bMaintainCount) m_cElements = 0;
|
||||
}
|
||||
|
||||
void ExplicitPurge()
|
||||
{
|
||||
T * pDie;
|
||||
BYTE * pb;
|
||||
|
||||
while (m_pHead)
|
||||
{
|
||||
pDie = m_pHead;
|
||||
m_pHead = pDie->m_pNext;
|
||||
|
||||
pDie->~T();
|
||||
|
||||
pb = reinterpret_cast<BYTE *>(pDie);
|
||||
delete [] pb;
|
||||
}
|
||||
if (bMaintainCount) m_cElements = 0;
|
||||
}
|
||||
|
||||
|
||||
T * GetTail() const
|
||||
{
|
||||
if (m_pHead)
|
||||
{
|
||||
return m_pTail;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
T * GetHead() const
|
||||
{
|
||||
return m_pHead;
|
||||
}
|
||||
|
||||
BOOL IsEmpty() const
|
||||
{
|
||||
return m_pHead == NULL;
|
||||
}
|
||||
|
||||
BOOL Remove(T * pNode)
|
||||
{
|
||||
if (m_pHead == pNode)
|
||||
{
|
||||
m_pHead = pNode->m_pNext;
|
||||
if (bMaintainCount) --m_cElements;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
T * pCur = m_pHead;
|
||||
while (pCur)
|
||||
{
|
||||
T * pNext = pCur->m_pNext;
|
||||
if (pNext == pNode)
|
||||
{
|
||||
if ((pCur->m_pNext = pNode->m_pNext) == NULL)
|
||||
{
|
||||
m_pTail = pCur;
|
||||
}
|
||||
if (bMaintainCount) --m_cElements;
|
||||
return TRUE;
|
||||
}
|
||||
pCur = pNext;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void MoveAllToHeadOf(CSpBasicQueue & DestQueue)
|
||||
{
|
||||
if (m_pHead)
|
||||
{
|
||||
m_pTail->m_pNext = DestQueue.m_pHead;
|
||||
if (DestQueue.m_pHead == NULL)
|
||||
{
|
||||
DestQueue.m_pTail = m_pTail;
|
||||
}
|
||||
DestQueue.m_pHead = m_pHead;
|
||||
m_pHead = NULL;
|
||||
if (bMaintainCount)
|
||||
{
|
||||
DestQueue.m_cElements += m_cElements;
|
||||
m_cElements = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MoveAllToList(CSpBasicList<T, bPurgeWhenDeleted> & List)
|
||||
{
|
||||
if (m_pHead)
|
||||
{
|
||||
m_pTail->m_pNext = List.m_pFirst;
|
||||
List.m_pFirst = m_pHead;
|
||||
m_pHead = NULL;
|
||||
}
|
||||
if (bMaintainCount)
|
||||
{
|
||||
m_cElements = 0;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL MoveToList(T * pNode, CSpBasicList<T, bPurgeWhenDeleted> & List)
|
||||
{
|
||||
BOOL bFound = Remove(pNode);
|
||||
if (bFound)
|
||||
{
|
||||
List.AddNode(pNode);
|
||||
}
|
||||
return bFound;
|
||||
}
|
||||
|
||||
ULONG GetCount() const
|
||||
{
|
||||
if (bMaintainCount)
|
||||
{
|
||||
return m_cElements;
|
||||
}
|
||||
else
|
||||
{
|
||||
ULONG c = 0;
|
||||
for (T * pNode = m_pHead;
|
||||
pNode;
|
||||
pNode = pNode->m_pNext, c++) {}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// The following functions require the class T to implement a static function:
|
||||
//
|
||||
// LONG Compare(const T * pElem1, const T * pElem2)
|
||||
//
|
||||
// which returns < 0 if pElem1 is less than pElem2, 0 if they are equal, and > 0 if
|
||||
// pElem1 is greater than pElem2.
|
||||
//
|
||||
void InsertSorted(T * pNode)
|
||||
{
|
||||
if (m_pHead)
|
||||
{
|
||||
if (T::Compare(pNode, m_pTail) >= 0)
|
||||
{
|
||||
pNode->m_pNext = NULL;
|
||||
m_pTail->m_pNext = pNode;
|
||||
m_pTail = pNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// We don't have to worry about walking off of the end of the list here since
|
||||
// we have already checked the tail.
|
||||
//
|
||||
T ** ppNext = &m_pHead;
|
||||
while (T::Compare(pNode, *ppNext) >= 0)
|
||||
{
|
||||
ppNext = &((*ppNext)->m_pNext);
|
||||
}
|
||||
pNode->m_pNext = *ppNext;
|
||||
*ppNext = pNode;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pNode->m_pNext = NULL;
|
||||
m_pHead = m_pTail = pNode;
|
||||
}
|
||||
if (bMaintainCount) ++m_cElements;
|
||||
}
|
||||
|
||||
HRESULT InsertSortedUnique(T * pNode)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (m_pHead)
|
||||
{
|
||||
if (T::Compare(pNode, m_pTail) > 0)
|
||||
{
|
||||
pNode->m_pNext = NULL;
|
||||
m_pTail->m_pNext = pNode;
|
||||
m_pTail = pNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// We don't have to worry about walking off of the end of the list here since
|
||||
// we have already checked the tail.
|
||||
//
|
||||
T ** ppNext = &m_pHead;
|
||||
while (T::Compare(pNode, *ppNext) > 0)
|
||||
{
|
||||
ppNext = &((*ppNext)->m_pNext);
|
||||
}
|
||||
if (T::Compare(pNode, *ppNext) != 0)
|
||||
{
|
||||
pNode->m_pNext = *ppNext;
|
||||
*ppNext = pNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pNode;
|
||||
hr = S_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pNode->m_pNext = NULL;
|
||||
m_pHead = m_pTail = pNode;
|
||||
}
|
||||
if (bMaintainCount) ++m_cElements;
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// These functions must support the "==" operator for the TFIND type.
|
||||
//
|
||||
template <class TFIND>
|
||||
T * Find(TFIND & FindVal) const
|
||||
{
|
||||
for (T * pNode = m_pHead; pNode && (!(*pNode == FindVal)); pNode = pNode->m_pNext)
|
||||
{}
|
||||
return pNode;
|
||||
}
|
||||
|
||||
template <class TFIND>
|
||||
T * FindNext(const T * pCurNode, TFIND & FindVal) const
|
||||
{
|
||||
for (T * pNode = pCurNode->m_pNext; pNode && (!(*pNode == FindVal)); pNode = pNode->m_pNext)
|
||||
{}
|
||||
return pNode;
|
||||
}
|
||||
|
||||
//
|
||||
// Searches for and removes a single list element
|
||||
//
|
||||
template <class TFIND>
|
||||
T * FindAndRemove(TFIND & FindVal)
|
||||
{
|
||||
T * pNode = m_pHead;
|
||||
if (pNode)
|
||||
{
|
||||
if (*pNode == FindVal)
|
||||
{
|
||||
m_pHead = pNode->m_pNext;
|
||||
if (bMaintainCount) --m_cElements;
|
||||
}
|
||||
else
|
||||
{
|
||||
T * pPrev = pNode;
|
||||
for (pNode = pNode->m_pNext;
|
||||
pNode;
|
||||
pPrev = pNode, pNode = pNode->m_pNext)
|
||||
{
|
||||
if (*pNode == FindVal)
|
||||
{
|
||||
pPrev->m_pNext = pNode->m_pNext;
|
||||
if (pNode->m_pNext == NULL)
|
||||
{
|
||||
m_pTail = pPrev;
|
||||
}
|
||||
if (bMaintainCount) --m_cElements;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return pNode;
|
||||
}
|
||||
|
||||
//
|
||||
// Searches for and deletes all list elements that match
|
||||
//
|
||||
template <class TFIND>
|
||||
void FindAndDeleteAll(TFIND & FindVal)
|
||||
{
|
||||
T * pNode = m_pHead;
|
||||
while (pNode && *pNode == FindVal)
|
||||
{
|
||||
m_pHead = pNode->m_pNext;
|
||||
delete pNode;
|
||||
if (bMaintainCount) --m_cElements;
|
||||
pNode = m_pHead;
|
||||
}
|
||||
T * pPrev = pNode;
|
||||
while (pNode)
|
||||
{
|
||||
T * pNext = pNode->m_pNext;
|
||||
if (*pNode == FindVal)
|
||||
{
|
||||
pPrev->m_pNext = pNext;
|
||||
delete pNode;
|
||||
if (bMaintainCount) --m_cElements;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPrev = pNode;
|
||||
}
|
||||
pNode = pNext;
|
||||
}
|
||||
m_pTail = pPrev; // Just always set it in case we removed the tail.
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
template <class T, BOOL bPurgeWhenDeleted = TRUE>
|
||||
class CSpBasicList
|
||||
{
|
||||
public:
|
||||
T * m_pFirst;
|
||||
CSpBasicList() : m_pFirst(NULL) {}
|
||||
~CSpBasicList()
|
||||
{
|
||||
if (bPurgeWhenDeleted)
|
||||
{
|
||||
Purge();
|
||||
}
|
||||
}
|
||||
|
||||
void Purge()
|
||||
{
|
||||
while (m_pFirst)
|
||||
{
|
||||
T * pNext = m_pFirst->m_pNext;
|
||||
delete m_pFirst;
|
||||
m_pFirst = pNext;
|
||||
}
|
||||
}
|
||||
|
||||
void ExplicitPurge()
|
||||
{
|
||||
T * pDie;
|
||||
BYTE * pb;
|
||||
|
||||
while (m_pFirst)
|
||||
{
|
||||
pDie = m_pFirst;
|
||||
m_pFirst = pDie->m_pNext;
|
||||
|
||||
pDie->~T();
|
||||
|
||||
pb = reinterpret_cast<BYTE *>(pDie);
|
||||
delete [] pb;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT RemoveFirstOrAllocateNew(T ** ppNode)
|
||||
{
|
||||
if (m_pFirst)
|
||||
{
|
||||
*ppNode = m_pFirst;
|
||||
m_pFirst = m_pFirst->m_pNext;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppNode = new T;
|
||||
if (*ppNode == NULL)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void AddNode(T * pNode)
|
||||
{
|
||||
pNode->m_pNext = m_pFirst;
|
||||
m_pFirst = pNode;
|
||||
}
|
||||
T * GetFirst()
|
||||
{
|
||||
return m_pFirst;
|
||||
}
|
||||
T * RemoveFirst()
|
||||
{
|
||||
T * pNode = m_pFirst;
|
||||
if (pNode)
|
||||
{
|
||||
m_pFirst = pNode->m_pNext;
|
||||
}
|
||||
return pNode;
|
||||
}
|
||||
};
|
||||
|
||||
#define STACK_ALLOC(TYPE, COUNT) (TYPE *)_alloca(sizeof(TYPE) * (COUNT))
|
||||
#define STACK_ALLOC_AND_ZERO(TYPE, COUNT) (TYPE *)memset(_alloca(sizeof(TYPE) * (COUNT)), 0, (sizeof(TYPE) * (COUNT)))
|
||||
#define STACK_ALLOC_AND_COPY(TYPE, COUNT, SOURCE) (TYPE *)memcpy(_alloca(sizeof(TYPE) * (COUNT)), (SOURCE), (sizeof(TYPE) * (COUNT)))
|
||||
|
||||
inline HRESULT SpGetSubTokenFromToken(
|
||||
ISpObjectToken * pToken,
|
||||
const WCHAR * pszSubKeyName,
|
||||
ISpObjectToken ** ppToken,
|
||||
BOOL fCreateIfNotExist = FALSE)
|
||||
{
|
||||
SPDBG_FUNC("SpGetTokenFromDataKey");
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (SP_IS_BAD_INTERFACE_PTR(pToken) ||
|
||||
SP_IS_BAD_STRING_PTR(pszSubKeyName) ||
|
||||
SP_IS_BAD_WRITE_PTR(ppToken))
|
||||
{
|
||||
hr = E_POINTER;
|
||||
}
|
||||
|
||||
// First, either create or open the datakey for the new token
|
||||
CComPtr<ISpDataKey> cpDataKeyForNewToken;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (fCreateIfNotExist)
|
||||
{
|
||||
hr = pToken->CreateKey(pszSubKeyName, &cpDataKeyForNewToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = pToken->OpenKey(pszSubKeyName, &cpDataKeyForNewToken);
|
||||
}
|
||||
}
|
||||
|
||||
// The sub token's category will be the token id of it's parent token
|
||||
CSpDynamicString dstrCategoryId;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = pToken->GetId(&dstrCategoryId);
|
||||
}
|
||||
|
||||
// The sub token's token id will be it's category id + "\\" the key name
|
||||
CSpDynamicString dstrTokenId;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
dstrTokenId = dstrCategoryId;
|
||||
dstrTokenId.Append2(L"\\", pszSubKeyName);
|
||||
}
|
||||
|
||||
// Now create the token and initalize it
|
||||
CComPtr<ISpObjectTokenInit> cpTokenInit;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = cpTokenInit.CoCreateInstance(CLSID_SpObjectToken);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = cpTokenInit->InitFromDataKey(dstrCategoryId, dstrTokenId, cpDataKeyForNewToken);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
*ppToken = cpTokenInit.Detach();
|
||||
}
|
||||
|
||||
SPDBG_REPORT_ON_FAIL(hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
HRESULT SpCreateObjectFromSubToken(ISpObjectToken * pToken, const WCHAR * pszSubKeyName, T ** ppObject,
|
||||
IUnknown * pUnkOuter = NULL, DWORD dwClsCtxt = CLSCTX_ALL)
|
||||
{
|
||||
SPDBG_FUNC("SpCreateObjectFromSubToken");
|
||||
HRESULT hr;
|
||||
|
||||
CComPtr<ISpObjectToken> cpSubToken;
|
||||
hr = SpGetSubTokenFromToken(pToken, pszSubKeyName, &cpSubToken);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = SpCreateObjectFromToken(cpSubToken, ppObject, pUnkOuter, dwClsCtxt);
|
||||
}
|
||||
|
||||
SPDBG_REPORT_ON_FAIL(hr);
|
||||
return hr;
|
||||
}
|
||||
|
||||
#endif /* This must be the last line in the file */
|
25599
speech2/third_party/sapi5/include/sapi.h
vendored
Normal file
25599
speech2/third_party/sapi5/include/sapi.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
4557
speech2/third_party/sapi5/include/sapiddk.h
vendored
Normal file
4557
speech2/third_party/sapi5/include/sapiddk.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
1432
speech2/third_party/sapi5/include/spcollec.h
vendored
Normal file
1432
speech2/third_party/sapi5/include/spcollec.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
636
speech2/third_party/sapi5/include/spdebug.h
vendored
Normal file
636
speech2/third_party/sapi5/include/spdebug.h
vendored
Normal file
|
@ -0,0 +1,636 @@
|
|||
/*******************************************************************************
|
||||
* SPDebug.h *
|
||||
*-----------*
|
||||
* Description:
|
||||
* This header file contains debug output services for SAPI5
|
||||
*-------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
*******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <TCHAR.h>
|
||||
#include <crtdbg.h>
|
||||
|
||||
#ifdef ASSERT_WITH_STACK
|
||||
#include "AssertWithStack.h"
|
||||
#endif
|
||||
|
||||
const TCHAR g_szSpDebugKey[] = _T("SPDebug");
|
||||
const TCHAR g_szSpDebugFuncTraceReportMode[] = _T("FuncTraceMode");
|
||||
const TCHAR g_szSpDebugFuncTraceReportFile[] = _T("FuncTraceFile");
|
||||
const TCHAR g_szSpDebugParamInfoReportMode[] = _T("ParamInfoMode");
|
||||
const TCHAR g_szSpDebugParamInfoReportFile[] = _T("ParamInfoFile");
|
||||
const TCHAR g_szSpDebugDumpInfoReportMode[] = _T("DumpInfoMode");
|
||||
const TCHAR g_szSpDebugDumpInfoReportFile[] = _T("DumpInfoFile");
|
||||
const TCHAR g_szSpDebugAssertReportMode[] = _T("AssertMode");
|
||||
const TCHAR g_szSpDebugAssertReportFile[] = _T("AssertFile");
|
||||
const TCHAR g_szSpDebugHRFailReportMode[] = _T("HRFailMode");
|
||||
const TCHAR g_szSpDebugHRFailReportFile[] = _T("HRFailFile");
|
||||
|
||||
const TCHAR g_szSpDebugAssertSettingsReReadEachTime[] = _T("AssertSettingsReReadEachTime");
|
||||
const TCHAR g_szSpDebugServerOnStart[] = _T("DebugServerOnStart");
|
||||
const TCHAR g_szSpDebugClientOnStart[] = _T("DebugClientOnStart");
|
||||
|
||||
const TCHAR g_szSpDebugLog[] = _T("c:\\spdebug.log");
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
class CSpDebug
|
||||
{
|
||||
public:
|
||||
|
||||
CSpDebug()
|
||||
{
|
||||
m_mutex = NULL;
|
||||
m_reportModePrev = -1;
|
||||
m_hfilePrev = NULL;
|
||||
Read();
|
||||
}
|
||||
|
||||
~CSpDebug()
|
||||
{
|
||||
if (m_mutex != NULL)
|
||||
{
|
||||
CloseHandle(m_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL FuncTrace(BOOL fEnter = TRUE)
|
||||
{
|
||||
return fEnter
|
||||
? Enter(_CRT_WARN, m_FuncTraceMode, m_szFuncTraceFile)
|
||||
: Leave();
|
||||
}
|
||||
|
||||
BOOL ParamInfo(BOOL fEnter = TRUE)
|
||||
{
|
||||
return fEnter
|
||||
? Enter(_CRT_WARN, m_ParamInfoMode, m_szParamInfoFile)
|
||||
: Leave();
|
||||
}
|
||||
|
||||
BOOL DumpInfo(BOOL fEnter = TRUE)
|
||||
{
|
||||
return fEnter
|
||||
? Enter(_CRT_WARN, m_DumpInfoMode, m_szDumpInfoFile)
|
||||
: Leave();
|
||||
}
|
||||
|
||||
BOOL Assert(BOOL fEnter = TRUE)
|
||||
{
|
||||
if (m_fAssertSettingsReReadEachTime)
|
||||
Read();
|
||||
|
||||
return fEnter
|
||||
? Enter(_CRT_ASSERT, m_AssertMode, m_szAssertFile)
|
||||
: Leave();
|
||||
}
|
||||
|
||||
BOOL HRFail(BOOL fEnter = TRUE)
|
||||
{
|
||||
return fEnter
|
||||
? Enter(_CRT_WARN, m_HRFailMode, m_szHRFailFile)
|
||||
: Leave();
|
||||
}
|
||||
|
||||
BOOL DebugServerOnStart()
|
||||
{
|
||||
return m_fDebugServerOnStart;
|
||||
}
|
||||
|
||||
BOOL DebugClientOnStart()
|
||||
{
|
||||
return m_fDebugClientOnStart;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void Read()
|
||||
{
|
||||
HKEY hkeyDebug;
|
||||
RegCreateKeyEx(
|
||||
HKEY_CLASSES_ROOT,
|
||||
g_szSpDebugKey,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
KEY_READ | KEY_WRITE,
|
||||
NULL,
|
||||
&hkeyDebug,
|
||||
NULL);
|
||||
if (hkeyDebug == NULL)
|
||||
{
|
||||
RegCreateKeyEx(
|
||||
HKEY_CLASSES_ROOT,
|
||||
g_szSpDebugKey,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
KEY_READ,
|
||||
NULL,
|
||||
&hkeyDebug,
|
||||
NULL);
|
||||
}
|
||||
|
||||
DWORD dw = sizeof(m_fAssertSettingsReReadEachTime);
|
||||
if (RegQueryValueEx(
|
||||
hkeyDebug,
|
||||
g_szSpDebugAssertSettingsReReadEachTime,
|
||||
NULL,
|
||||
NULL,
|
||||
LPBYTE(&m_fAssertSettingsReReadEachTime),
|
||||
&dw) != ERROR_SUCCESS)
|
||||
{
|
||||
m_fAssertSettingsReReadEachTime = FALSE;
|
||||
RegSetValueEx(
|
||||
hkeyDebug,
|
||||
g_szSpDebugAssertSettingsReReadEachTime,
|
||||
NULL,
|
||||
REG_DWORD,
|
||||
LPBYTE(&m_fAssertSettingsReReadEachTime),
|
||||
sizeof(m_fAssertSettingsReReadEachTime));
|
||||
}
|
||||
|
||||
ReadFor(
|
||||
hkeyDebug,
|
||||
g_szSpDebugFuncTraceReportMode,
|
||||
g_szSpDebugFuncTraceReportFile,
|
||||
&m_FuncTraceMode,
|
||||
m_szFuncTraceFile,
|
||||
0,
|
||||
g_szSpDebugLog);
|
||||
ReadFor(
|
||||
hkeyDebug,
|
||||
g_szSpDebugParamInfoReportMode,
|
||||
g_szSpDebugParamInfoReportFile,
|
||||
&m_ParamInfoMode,
|
||||
m_szParamInfoFile,
|
||||
0,
|
||||
g_szSpDebugLog);
|
||||
ReadFor(
|
||||
hkeyDebug,
|
||||
g_szSpDebugDumpInfoReportMode,
|
||||
g_szSpDebugDumpInfoReportFile,
|
||||
&m_DumpInfoMode,
|
||||
m_szDumpInfoFile,
|
||||
_CRTDBG_MODE_DEBUG,
|
||||
g_szSpDebugLog);
|
||||
ReadFor(
|
||||
hkeyDebug,
|
||||
g_szSpDebugAssertReportMode,
|
||||
g_szSpDebugAssertReportFile,
|
||||
&m_AssertMode,
|
||||
m_szAssertFile,
|
||||
_CRTDBG_MODE_WNDW,
|
||||
g_szSpDebugLog);
|
||||
ReadFor(
|
||||
hkeyDebug,
|
||||
g_szSpDebugHRFailReportMode,
|
||||
g_szSpDebugHRFailReportFile,
|
||||
&m_HRFailMode,
|
||||
m_szHRFailFile,
|
||||
_CRTDBG_MODE_DEBUG,
|
||||
g_szSpDebugLog);
|
||||
|
||||
dw = sizeof(m_fDebugServerOnStart);
|
||||
if (RegQueryValueEx(
|
||||
hkeyDebug,
|
||||
g_szSpDebugServerOnStart,
|
||||
NULL,
|
||||
NULL,
|
||||
LPBYTE(&m_fDebugServerOnStart),
|
||||
&dw) != ERROR_SUCCESS)
|
||||
{
|
||||
m_fDebugServerOnStart = FALSE;
|
||||
RegSetValueEx(
|
||||
hkeyDebug,
|
||||
g_szSpDebugServerOnStart,
|
||||
NULL,
|
||||
REG_DWORD,
|
||||
LPBYTE(&m_fDebugServerOnStart),
|
||||
sizeof(m_fDebugServerOnStart));
|
||||
}
|
||||
|
||||
dw = sizeof(m_fDebugClientOnStart);
|
||||
if (RegQueryValueEx(
|
||||
hkeyDebug,
|
||||
g_szSpDebugClientOnStart,
|
||||
NULL,
|
||||
NULL,
|
||||
LPBYTE(&m_fDebugClientOnStart),
|
||||
&dw) != ERROR_SUCCESS)
|
||||
{
|
||||
m_fDebugClientOnStart = FALSE;
|
||||
RegSetValueEx(
|
||||
hkeyDebug,
|
||||
g_szSpDebugClientOnStart,
|
||||
NULL,
|
||||
REG_DWORD,
|
||||
LPBYTE(&m_fDebugClientOnStart),
|
||||
sizeof(m_fDebugClientOnStart));
|
||||
}
|
||||
|
||||
RegCloseKey(hkeyDebug);
|
||||
}
|
||||
|
||||
void ReadFor(
|
||||
HKEY hkey,
|
||||
const TCHAR * pszModeValueName,
|
||||
const TCHAR * pszFileValueName,
|
||||
DWORD * pdwModeValue,
|
||||
TCHAR * pszFileValue,
|
||||
DWORD dwDefaultModeValue,
|
||||
const TCHAR * pszDefaultFileValue)
|
||||
{
|
||||
DWORD dw = sizeof(*pdwModeValue);
|
||||
if (RegQueryValueEx(
|
||||
hkey,
|
||||
pszModeValueName,
|
||||
NULL,
|
||||
NULL,
|
||||
LPBYTE(pdwModeValue),
|
||||
&dw) != ERROR_SUCCESS)
|
||||
{
|
||||
*pdwModeValue = dwDefaultModeValue;
|
||||
RegSetValueEx(
|
||||
hkey,
|
||||
pszModeValueName,
|
||||
NULL,
|
||||
REG_DWORD,
|
||||
LPBYTE(pdwModeValue),
|
||||
sizeof(*pdwModeValue));
|
||||
}
|
||||
|
||||
dw = MAX_PATH;
|
||||
if (RegQueryValueEx(
|
||||
hkey,
|
||||
pszFileValueName,
|
||||
NULL,
|
||||
NULL,
|
||||
LPBYTE(pszFileValue),
|
||||
&dw) != ERROR_SUCCESS)
|
||||
{
|
||||
_tcscpy(pszFileValue, pszDefaultFileValue);
|
||||
RegSetValueEx(
|
||||
hkey,
|
||||
pszFileValueName,
|
||||
NULL,
|
||||
REG_SZ,
|
||||
LPBYTE(pszFileValue),
|
||||
MAX_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL Enter(int reportType, DWORD &reportMode, TCHAR * pszFile)
|
||||
{
|
||||
if (reportMode != 0)
|
||||
{
|
||||
// We'll hold the mutex, until the caller also calls Leave
|
||||
if (m_mutex == NULL)
|
||||
{
|
||||
m_mutex = CreateMutex(NULL, FALSE, _T("SpDebug"));
|
||||
}
|
||||
WaitForSingleObject(m_mutex, INFINITE);
|
||||
|
||||
m_reportType = reportType;
|
||||
m_reportModePrev = _CrtSetReportMode(reportType, reportMode);
|
||||
if (reportMode & _CRTDBG_MODE_FILE)
|
||||
{
|
||||
HANDLE hfile = CreateFile(
|
||||
pszFile,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_ALWAYS,
|
||||
0,
|
||||
NULL);
|
||||
SetFilePointer(hfile, 0, NULL, FILE_END);
|
||||
m_hfilePrev = (_HFILE)_CrtSetReportFile(reportType, (_HFILE)hfile);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL Leave()
|
||||
{
|
||||
int reportMode = _CrtSetReportMode(m_reportType, m_reportModePrev);
|
||||
if (reportMode & _CRTDBG_MODE_FILE)
|
||||
{
|
||||
CloseHandle((_HFILE)_CrtSetReportFile(m_reportType, (_HFILE)m_hfilePrev));
|
||||
}
|
||||
|
||||
ReleaseMutex(m_mutex);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
HANDLE m_mutex;
|
||||
|
||||
int m_reportType;
|
||||
int m_reportModePrev;
|
||||
_HFILE m_hfilePrev;
|
||||
|
||||
BOOL m_fAssertSettingsReReadEachTime;
|
||||
|
||||
DWORD m_FuncTraceMode;
|
||||
TCHAR m_szFuncTraceFile[MAX_PATH + 1];
|
||||
DWORD m_ParamInfoMode;
|
||||
TCHAR m_szParamInfoFile[MAX_PATH + 1];
|
||||
DWORD m_DumpInfoMode;
|
||||
TCHAR m_szDumpInfoFile[MAX_PATH + 1];
|
||||
DWORD m_AssertMode;
|
||||
TCHAR m_szAssertFile[MAX_PATH + 1];
|
||||
DWORD m_HRFailMode;
|
||||
TCHAR m_szHRFailFile[MAX_PATH + 1];
|
||||
|
||||
BOOL m_fDebugServerOnStart;
|
||||
BOOL m_fDebugClientOnStart;
|
||||
};
|
||||
|
||||
inline CSpDebug *PSpDebug()
|
||||
{
|
||||
static CSpDebug debug;
|
||||
return &debug;
|
||||
}
|
||||
|
||||
class CSpFuncTrace
|
||||
{
|
||||
public:
|
||||
|
||||
CSpFuncTrace(PCHAR pFuncName)
|
||||
{
|
||||
m_pFuncName = pFuncName;
|
||||
if (PSpDebug()->FuncTrace())
|
||||
{
|
||||
_RPT1( _CRT_WARN, "\nEntering Function: %s\n", m_pFuncName );
|
||||
PSpDebug()->FuncTrace(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
~CSpFuncTrace()
|
||||
{
|
||||
if (PSpDebug()->FuncTrace())
|
||||
{
|
||||
_RPT1( _CRT_WARN, "Leaving Function: %s\n", m_pFuncName );
|
||||
PSpDebug()->FuncTrace(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
PCHAR m_pFuncName;
|
||||
};
|
||||
|
||||
#endif // _DEBUG
|
||||
|
||||
//=== User macros ==============================================================
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
#define SPDBG_FUNC(name) \
|
||||
CSpFuncTrace functrace(name)
|
||||
|
||||
#if defined(ASSERT_WITH_STACK) && !defined(_WIN64)
|
||||
#define SPDBG_REPORT_ON_FAIL(hr) \
|
||||
do \
|
||||
{ \
|
||||
HRESULT _hr = (hr); \
|
||||
if (FAILED(_hr) && PSpDebug()->HRFail()) \
|
||||
{ \
|
||||
SYSTEMTIME sysTime; \
|
||||
GetLocalTime(&sysTime); \
|
||||
CHAR pszHrWithTime[100]; \
|
||||
sprintf(pszHrWithTime, "%lX\n\n%d.%d.%d %02d:%02d:%02d", \
|
||||
_hr, \
|
||||
sysTime.wMonth,sysTime.wDay,sysTime.wYear, \
|
||||
sysTime.wHour,sysTime.wMinute,sysTime.wSecond); \
|
||||
PCHAR pszStack = \
|
||||
(PCHAR)_alloca( \
|
||||
cchMaxAssertStackLevelStringLen * \
|
||||
cfrMaxAssertStackLevels + 1); \
|
||||
GetStringFromStackLevels(0, 10, pszStack); \
|
||||
_RPT4(_CRT_WARN, \
|
||||
"%s(%d): Failed HR = %s\n\n%s\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
pszHrWithTime, \
|
||||
pszStack); \
|
||||
PSpDebug()->HRFail(FALSE); \
|
||||
} \
|
||||
} while (0)
|
||||
#else // ASSERT_WITH_STACK & !_WIN64
|
||||
#define SPDBG_REPORT_ON_FAIL(hr) \
|
||||
do \
|
||||
{ \
|
||||
HRESULT _hr = (hr); \
|
||||
if (FAILED(_hr) && PSpDebug()->HRFail()) \
|
||||
{ \
|
||||
_RPT3(_CRT_WARN, "%s(%d): Failed HR = %lX\n", __FILE__, __LINE__, (_hr) );\
|
||||
PSpDebug()->HRFail(FALSE); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif // ASSERT_WITH_STACK
|
||||
|
||||
#define SPDBG_ASSERT(expr) \
|
||||
do \
|
||||
{ \
|
||||
if (!(expr)) \
|
||||
{ \
|
||||
if (PSpDebug()->Assert()) \
|
||||
{ \
|
||||
_ASSERTE( expr ); \
|
||||
PSpDebug()->Assert(FALSE); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define SPDBG_VERIFY(expr) \
|
||||
SPDBG_ASSERT(expr)
|
||||
|
||||
#define SPDBG_PMSG0(format) \
|
||||
do \
|
||||
{ \
|
||||
if (PSpDebug()->ParamInfo()) \
|
||||
{ \
|
||||
_RPT0(_CRT_WARN, format); \
|
||||
PSpDebug()->ParamInfo(FALSE); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SPDBG_PMSG1(format, arg1) \
|
||||
do \
|
||||
{ \
|
||||
if (PSpDebug()->ParamInfo()) \
|
||||
{ \
|
||||
_RPT1(_CRT_WARN, format, arg1); \
|
||||
PSpDebug()->ParamInfo(FALSE); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SPDBG_PMSG2(format, arg1, arg2) \
|
||||
do \
|
||||
{ \
|
||||
if (PSpDebug()->ParamInfo()) \
|
||||
{ \
|
||||
_RPT2(_CRT_WARN, format, arg1, arg2); \
|
||||
PSpDebug()->ParamInfo(FALSE); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SPDBG_PMSG3(format, arg1, arg2, arg3) \
|
||||
do \
|
||||
{ \
|
||||
if (PSpDebug()->ParamInfo()) \
|
||||
{ \
|
||||
_RPT3(_CRT_WARN, format, arg1, arg2, arg3); \
|
||||
PSpDebug()->ParamInfo(FALSE); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SPDBG_PMSG4(format, arg1, arg2, arg3, arg4) \
|
||||
do \
|
||||
{ \
|
||||
if (PSpDebug()->ParamInfo()) \
|
||||
{ \
|
||||
_RPT4(_CRT_WARN, format, arg1, arg2, arg3, arg4); \
|
||||
PSpDebug()->ParamInfo(FALSE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SPDBG_DMSG0(format) \
|
||||
do \
|
||||
{ \
|
||||
if (PSpDebug()->DumpInfo()) \
|
||||
{ \
|
||||
_RPT0(_CRT_WARN, format); \
|
||||
PSpDebug()->DumpInfo(FALSE); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SPDBG_DMSG1(format, arg1) \
|
||||
do \
|
||||
{ \
|
||||
if (PSpDebug()->DumpInfo()) \
|
||||
{ \
|
||||
_RPT1(_CRT_WARN, format, arg1); \
|
||||
PSpDebug()->DumpInfo(FALSE); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SPDBG_DMSG2(format, arg1, arg2) \
|
||||
do \
|
||||
{ \
|
||||
if (PSpDebug()->DumpInfo()) \
|
||||
{ \
|
||||
_RPT2(_CRT_WARN, format, arg1, arg2); \
|
||||
PSpDebug()->DumpInfo(FALSE); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SPDBG_DMSG3(format, arg1, arg2, arg3) \
|
||||
do \
|
||||
{ \
|
||||
if (PSpDebug()->DumpInfo()) \
|
||||
{ \
|
||||
_RPT3(_CRT_WARN, format, arg1, arg2, arg3); \
|
||||
PSpDebug()->DumpInfo(FALSE); \
|
||||
} \
|
||||
} while (0)
|
||||
#define SPDBG_DMSG4(format, arg1, arg2, arg3, arg4) \
|
||||
do \
|
||||
{ \
|
||||
if (PSpDebug()->DumpInfo()) \
|
||||
{ \
|
||||
_RPT4(_CRT_WARN, format, arg1, arg2, arg3, arg4); \
|
||||
PSpDebug()->DumpInfo(FALSE); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SPDBG_RETURN(hr) \
|
||||
{ \
|
||||
HRESULT __hr = (hr); \
|
||||
if (FAILED(__hr)) \
|
||||
{ \
|
||||
SPDBG_REPORT_ON_FAIL(__hr); \
|
||||
} \
|
||||
return __hr; \
|
||||
}
|
||||
|
||||
#define SPDBG_DEBUG_SERVER_ON_START() \
|
||||
{ \
|
||||
if (PSpDebug()->DebugServerOnStart()) \
|
||||
{ \
|
||||
if (MessageBox( \
|
||||
GetDesktopWindow(), \
|
||||
_T("Attach Debugger to the SAPI Server process?"), \
|
||||
_T("SAPI"), \
|
||||
MB_YESNO) == IDYES) \
|
||||
{ \
|
||||
USES_CONVERSION; \
|
||||
TCHAR szCommand[MAX_PATH + 1]; \
|
||||
wsprintf( \
|
||||
szCommand, \
|
||||
_T("msdev -p %d"), \
|
||||
GetCurrentProcessId()); \
|
||||
system(T2A(szCommand)); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SPDBG_DEBUG_CLIENT_ON_START() \
|
||||
{ \
|
||||
if (PSpDebug()->DebugClientOnStart()) \
|
||||
{ \
|
||||
TCHAR szModule[MAX_PATH + 1]; \
|
||||
szModule[0] = '\0'; \
|
||||
TCHAR * pszSapiServer = \
|
||||
_T("sapisvr.exe"); \
|
||||
GetModuleFileName( \
|
||||
NULL, \
|
||||
szModule, \
|
||||
MAX_PATH); \
|
||||
if ((_tcslen(szModule) <= \
|
||||
_tcslen(pszSapiServer) || \
|
||||
_tcsicmp( \
|
||||
szModule + \
|
||||
_tcslen(szModule) - \
|
||||
_tcslen(pszSapiServer), \
|
||||
pszSapiServer) != 0) && \
|
||||
MessageBox( \
|
||||
GetDesktopWindow(), \
|
||||
_T("Attach Debugger to the SAPI Client process?"), \
|
||||
_T("SAPI"), \
|
||||
MB_YESNO) == IDYES) \
|
||||
{ \
|
||||
USES_CONVERSION; \
|
||||
TCHAR szCommand[MAX_PATH + 1]; \
|
||||
wsprintf( \
|
||||
szCommand, \
|
||||
_T("msdev -p %d"), \
|
||||
GetCurrentProcessId()); \
|
||||
system(T2A(szCommand)); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#else // _DEBUG
|
||||
|
||||
#define SPDBG_FUNC(name)
|
||||
#define SPDBG_REPORT_ON_FAIL(hr)
|
||||
#define SPDBG_ASSERT(expr)
|
||||
#define SPDBG_VERIFY(expr) (expr)
|
||||
#define SPDBG_PMSG0(format)
|
||||
#define SPDBG_PMSG1(format, arg1)
|
||||
#define SPDBG_PMSG2(format, arg1, arg2)
|
||||
#define SPDBG_PMSG3(format, arg1, arg2, arg3)
|
||||
#define SPDBG_PMSG4(format, arg1, arg2, arg3, arg4)
|
||||
#define SPDBG_DMSG0(format)
|
||||
#define SPDBG_DMSG1(format, arg1)
|
||||
#define SPDBG_DMSG2(format, arg1, arg2)
|
||||
#define SPDBG_DMSG3(format, arg1, arg2, arg3)
|
||||
#define SPDBG_DMSG4(format, arg1, arg2, arg3, arg4)
|
||||
#define SPDBG_RETURN(hr) return (hr)
|
||||
#define SPDBG_DEBUG_SERVER_ON_START()
|
||||
#define SPDBG_DEBUG_CLIENT_ON_START()
|
||||
|
||||
#endif // _DEBUG
|
559
speech2/third_party/sapi5/include/sperror.h
vendored
Normal file
559
speech2/third_party/sapi5/include/sperror.h
vendored
Normal file
|
@ -0,0 +1,559 @@
|
|||
/*******************************************************************************
|
||||
* SPError.h *
|
||||
*-----------*
|
||||
* Description:
|
||||
* This header file contains the custom error codes specific to SAPI5
|
||||
*-------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
*******************************************************************************/
|
||||
#ifndef SPError_h
|
||||
#define SPError_h
|
||||
|
||||
#ifndef _WINERROR_
|
||||
#include <winerror.h>
|
||||
#endif
|
||||
|
||||
#define FACILITY_SAPI FACILITY_ITF
|
||||
#define SAPI_ERROR_BASE 0x5000
|
||||
|
||||
#define MAKE_SAPI_HRESULT(sev, err) MAKE_HRESULT(sev, FACILITY_SAPI, err)
|
||||
#define MAKE_SAPI_ERROR(err) MAKE_SAPI_HRESULT(SEVERITY_ERROR, err + SAPI_ERROR_BASE)
|
||||
#define MAKE_SAPI_SCODE(scode) MAKE_SAPI_HRESULT(SEVERITY_SUCCESS, scode + SAPI_ERROR_BASE)
|
||||
|
||||
/*** SPERR_UNINITIALIZED 0x80045001 -2147201023
|
||||
* The object has not been properly initialized.
|
||||
*/
|
||||
#define SPERR_UNINITIALIZED MAKE_SAPI_ERROR(0x001)
|
||||
|
||||
/*** SPERR_ALREADY_INITIALIZED 0x80045002 -2147201022
|
||||
* The object has already been initialized.
|
||||
*/
|
||||
#define SPERR_ALREADY_INITIALIZED MAKE_SAPI_ERROR(0x002)
|
||||
|
||||
/*** SPERR_UNSUPPORTED_FORMAT 0x80045003 -2147201021
|
||||
* The caller has specified an unsupported format.
|
||||
*/
|
||||
#define SPERR_UNSUPPORTED_FORMAT MAKE_SAPI_ERROR(0x003)
|
||||
|
||||
/*** SPERR_INVALID_FLAGS 0x80045004 -2147201020
|
||||
* The caller has specified invalid flags for this operation.
|
||||
*/
|
||||
#define SPERR_INVALID_FLAGS MAKE_SAPI_ERROR(0x004)
|
||||
|
||||
/*** SP_END_OF_STREAM 0x00045005 282629
|
||||
* The operation has reached the end of stream.
|
||||
*/
|
||||
#define SP_END_OF_STREAM MAKE_SAPI_SCODE(0x005)
|
||||
|
||||
/*** SPERR_DEVICE_BUSY 0x80045006 -2147201018
|
||||
* The wave device is busy.
|
||||
*/
|
||||
#define SPERR_DEVICE_BUSY MAKE_SAPI_ERROR(0x006)
|
||||
|
||||
/*** SPERR_DEVICE_NOT_SUPPORTED 0x80045007 -2147201017
|
||||
* The wave device is not supported.
|
||||
*/
|
||||
#define SPERR_DEVICE_NOT_SUPPORTED MAKE_SAPI_ERROR(0x007)
|
||||
|
||||
/*** SPERR_DEVICE_NOT_ENABLED 0x80045008 -2147201016
|
||||
* The wave device is not enabled.
|
||||
*/
|
||||
#define SPERR_DEVICE_NOT_ENABLED MAKE_SAPI_ERROR(0x008)
|
||||
|
||||
/*** SPERR_NO_DRIVER 0x80045009 -2147201015
|
||||
* There is no wave driver installed.
|
||||
*/
|
||||
#define SPERR_NO_DRIVER MAKE_SAPI_ERROR(0x009)
|
||||
|
||||
/*** SPERR_FILEMUSTBEUNICODE 0x8004500a -2147201014
|
||||
* The file must be Unicode.
|
||||
*/
|
||||
#define SPERR_FILE_MUST_BE_UNICODE MAKE_SAPI_ERROR(0x00a)
|
||||
|
||||
/*** SP_INSUFFICIENTDATA 0x0004500b 282635
|
||||
*
|
||||
*/
|
||||
#define SP_INSUFFICIENT_DATA MAKE_SAPI_SCODE(0x00b)
|
||||
|
||||
/*** SPERR_INVALID_PHRASE_ID 0x8004500c -2147201012
|
||||
* The phrase ID specified does not exist or is out of range.
|
||||
*/
|
||||
#define SPERR_INVALID_PHRASE_ID MAKE_SAPI_ERROR(0x00c)
|
||||
|
||||
/*** SPERR_BUFFER_TOO_SMALL 0x8004500d -2147201011
|
||||
* The caller provided a buffer too small to return a result.
|
||||
*/
|
||||
#define SPERR_BUFFER_TOO_SMALL MAKE_SAPI_ERROR(0x00d)
|
||||
|
||||
/*** SPERR_FORMAT_NOT_SPECIFIED 0x8004500e -2147201010
|
||||
* Caller did not specify a format prior to opening a stream.
|
||||
*/
|
||||
#define SPERR_FORMAT_NOT_SPECIFIED MAKE_SAPI_ERROR(0x00e)
|
||||
|
||||
/*** SPERR_AUDIO_STOPPED 0x8004500f -2147201009
|
||||
* This method is deprecated. Use SP_AUDIO_STOPPED instead.
|
||||
*/
|
||||
#define SPERR_AUDIO_STOPPED MAKE_SAPI_ERROR(0x00f)
|
||||
|
||||
/*** SP_AUDIO_PAUSED 0x00045010 282640
|
||||
* This will be returned only on input (read) streams when the stream is paused. Reads on
|
||||
* paused streams will not block, and this return code indicates that all of the data has been
|
||||
* removed from the stream.
|
||||
*/
|
||||
#define SP_AUDIO_PAUSED MAKE_SAPI_SCODE(0x010)
|
||||
|
||||
/*** SPERR_RULE_NOT_FOUND 0x80045011 -2147201007
|
||||
* Invalid rule name passed to ActivateGrammar.
|
||||
*/
|
||||
#define SPERR_RULE_NOT_FOUND MAKE_SAPI_ERROR(0x011)
|
||||
|
||||
/*** SPERR_TTS_ENGINE_EXCEPTION 0x80045012 -2147201006
|
||||
* An exception was raised during a call to the current TTS driver.
|
||||
*/
|
||||
#define SPERR_TTS_ENGINE_EXCEPTION MAKE_SAPI_ERROR(0x012)
|
||||
|
||||
/*** SPERR_TTS_NLP_EXCEPTION 0x80045013 -2147201005
|
||||
* An exception was raised during a call to an application sentence filter.
|
||||
*/
|
||||
#define SPERR_TTS_NLP_EXCEPTION MAKE_SAPI_ERROR(0x013)
|
||||
|
||||
/*** SPERR_ENGINE_BUSY 0x80045014 -2147201004
|
||||
* In speech recognition, the current method can not be performed while
|
||||
* a grammar rule is active.
|
||||
*/
|
||||
#define SPERR_ENGINE_BUSY MAKE_SAPI_ERROR(0x014)
|
||||
|
||||
/*** SP_AUDIO_CONVERSION_ENABLED 0x00045015 282645
|
||||
* The operation was successful, but only with automatic stream format conversion.
|
||||
*/
|
||||
#define SP_AUDIO_CONVERSION_ENABLED MAKE_SAPI_SCODE(0x015)
|
||||
|
||||
/*** SP_NO_HYPOTHESIS_AVAILABLE 0x00045016 282646
|
||||
* There is currently no hypothesis recognition available.
|
||||
*/
|
||||
#define SP_NO_HYPOTHESIS_AVAILABLE MAKE_SAPI_SCODE(0x016)
|
||||
|
||||
/*** SPERR_CANT_CREATE 0x80045017 -2147201001
|
||||
* Can not create a new object instance for the specified object category.
|
||||
*/
|
||||
#define SPERR_CANT_CREATE MAKE_SAPI_ERROR(0x017)
|
||||
|
||||
/*** SP_ALREADY_IN_LEX 0x00045018 282648
|
||||
* The word, pronunciation, or POS pair being added is already in lexicon.
|
||||
*/
|
||||
#define SP_ALREADY_IN_LEX MAKE_SAPI_SCODE(0x018)
|
||||
|
||||
/*** SPERR_NOT_IN_LEX 0x80045019 -2147200999
|
||||
* The word does not exist in the lexicon.
|
||||
*/
|
||||
#define SPERR_NOT_IN_LEX MAKE_SAPI_ERROR(0x019)
|
||||
|
||||
/*** SP_LEX_NOTHING_TO_SYNC 0x0004501a 282650
|
||||
* The client is currently synced with the lexicon.
|
||||
*/
|
||||
#define SP_LEX_NOTHING_TO_SYNC MAKE_SAPI_SCODE(0x01a)
|
||||
|
||||
/*** SPERR_LEX_VERY_OUT_OF_SYNC 0x8004501b -2147200997
|
||||
* The client is excessively out of sync with the lexicon. Mismatches may not be incrementally sync'd.
|
||||
*/
|
||||
#define SPERR_LEX_VERY_OUT_OF_SYNC MAKE_SAPI_ERROR(0x01b)
|
||||
|
||||
/*** SPERR_UNDEFINED_FORWARD_RULE_REF 0x8004501c -2147200996
|
||||
* A rule reference in a grammar was made to a named rule that was never defined.
|
||||
*/
|
||||
#define SPERR_UNDEFINED_FORWARD_RULE_REF MAKE_SAPI_ERROR(0x01c)
|
||||
|
||||
/*** SPERR_EMPTY_RULE 0x8004501d -2147200995
|
||||
* A non-dynamic grammar rule that has no body.
|
||||
*/
|
||||
#define SPERR_EMPTY_RULE MAKE_SAPI_ERROR(0x01d)
|
||||
|
||||
/*** SPERR_GRAMMAR_COMPILER_INTERNAL_ERROR 0x8004501e -2147200994
|
||||
* The grammar compiler failed due to an internal state error.
|
||||
*/
|
||||
#define SPERR_GRAMMAR_COMPILER_INTERNAL_ERROR MAKE_SAPI_ERROR(0x01e)
|
||||
|
||||
|
||||
/*** SPERR_RULE_NOT_DYNAMIC 0x8004501f -2147200993
|
||||
* An attempt was made to modify a non-dynamic rule.
|
||||
*/
|
||||
#define SPERR_RULE_NOT_DYNAMIC MAKE_SAPI_ERROR(0x01f)
|
||||
|
||||
/*** SPERR_DUPLICATE_RULE_NAME 0x80045020 -2147200992
|
||||
* A rule name was duplicated.
|
||||
*/
|
||||
#define SPERR_DUPLICATE_RULE_NAME MAKE_SAPI_ERROR(0x020)
|
||||
|
||||
/*** SPERR_DUPLICATE_RESOURCE_NAME 0x80045021 -2147200991
|
||||
* A resource name was duplicated for a given rule.
|
||||
*/
|
||||
#define SPERR_DUPLICATE_RESOURCE_NAME MAKE_SAPI_ERROR(0x021)
|
||||
|
||||
|
||||
/*** SPERR_TOO_MANY_GRAMMARS 0x80045022 -2147200990
|
||||
* Too many grammars have been loaded.
|
||||
*/
|
||||
#define SPERR_TOO_MANY_GRAMMARS MAKE_SAPI_ERROR(0x022)
|
||||
|
||||
/*** SPERR_CIRCULAR_REFERENCE 0x80045023 -2147200989
|
||||
* Circular reference in import rules of grammars.
|
||||
*/
|
||||
#define SPERR_CIRCULAR_REFERENCE MAKE_SAPI_ERROR(0x023)
|
||||
|
||||
/*** SPERR_INVALID_IMPORT 0x80045024 -2147200988
|
||||
* A rule reference to an imported grammar that could not be resolved.
|
||||
*/
|
||||
#define SPERR_INVALID_IMPORT MAKE_SAPI_ERROR(0x024)
|
||||
|
||||
/*** SPERR_INVALID_WAV_FILE 0x80045025 -2147200987
|
||||
* The format of the WAV file is not supported.
|
||||
*/
|
||||
#define SPERR_INVALID_WAV_FILE MAKE_SAPI_ERROR(0x025)
|
||||
|
||||
/*** SP_REQUEST_PENDING 0x00045026 282662
|
||||
* This success code indicates that an SR method called with the SPRIF_ASYNC flag is
|
||||
* being processed. When it has finished processing, an SPFEI_ASYNC_COMPLETED event will be generated.
|
||||
*/
|
||||
#define SP_REQUEST_PENDING MAKE_SAPI_SCODE(0x026)
|
||||
|
||||
/*** SPERR_ALL_WORDS_OPTIONAL 0x80045027 -2147200985
|
||||
* A grammar rule was defined with a null path through the rule. That is, it is possible
|
||||
* to satisfy the rule conditions with no words.
|
||||
*/
|
||||
#define SPERR_ALL_WORDS_OPTIONAL MAKE_SAPI_ERROR(0x027)
|
||||
|
||||
/*** SPERR_INSTANCE_CHANGE_INVALID 0x80045028 -2147200984
|
||||
* It is not possible to change the current engine or input. This occurs in the
|
||||
* following cases:
|
||||
*
|
||||
* 1) SelectEngine called while a recognition context exists, or
|
||||
* 2) SetInput called in the shared instance case.
|
||||
*/
|
||||
#define SPERR_INSTANCE_CHANGE_INVALID MAKE_SAPI_ERROR(0x028)
|
||||
|
||||
/*** SPERR_RULE_NAME_ID_CONFLICT 0x80045029 -2147200983
|
||||
* A rule exists with matching IDs (names) but different names (IDs).
|
||||
*/
|
||||
#define SPERR_RULE_NAME_ID_CONFLICT MAKE_SAPI_ERROR(0x029)
|
||||
|
||||
/*** SPERR_NO_RULES 0x8004502a -2147200982
|
||||
* A grammar contains no top-level, dynamic, or exported rules. There is no possible
|
||||
* way to activate or otherwise use any rule in this grammar.
|
||||
*/
|
||||
#define SPERR_NO_RULES MAKE_SAPI_ERROR(0x02a)
|
||||
|
||||
/*** SPERR_CIRCULAR_RULE_REF 0x8004502b -2147200981
|
||||
* Rule 'A' refers to a second rule 'B' which, in turn, refers to rule 'A'.
|
||||
*/
|
||||
#define SPERR_CIRCULAR_RULE_REF MAKE_SAPI_ERROR(0x02b)
|
||||
|
||||
/*** SP_NO_PARSE_FOUND 0x0004502c 282668
|
||||
* Parse path cannot be parsed given the currently active rules.
|
||||
*/
|
||||
#define SP_NO_PARSE_FOUND MAKE_SAPI_SCODE(0x02c)
|
||||
|
||||
/*** SPERR_NO_PARSE_FOUND 0x8004502d -2147200979
|
||||
* Parse path cannot be parsed given the currently active rules.
|
||||
*/
|
||||
#define SPERR_INVALID_HANDLE MAKE_SAPI_ERROR(0x02d)
|
||||
|
||||
/*** SPERR_REMOTE_CALL_TIMED_OUT 0x8004502e -2147200978
|
||||
* A marshaled remote call failed to respond.
|
||||
*/
|
||||
#define SPERR_REMOTE_CALL_TIMED_OUT MAKE_SAPI_ERROR(0x02e)
|
||||
|
||||
/*** SPERR_AUDIO_BUFFER_OVERFLOW 0x8004502f -2147200977
|
||||
* This will only be returned on input (read) streams when the stream is paused because
|
||||
* the SR driver has not retrieved data recently.
|
||||
*/
|
||||
#define SPERR_AUDIO_BUFFER_OVERFLOW MAKE_SAPI_ERROR(0x02f)
|
||||
|
||||
|
||||
/*** SPERR_NO_AUDIO_DATA 0x80045030 -2147200976
|
||||
* The result does not contain any audio, nor does the portion of the element chain of the result
|
||||
* contain any audio.
|
||||
*/
|
||||
#define SPERR_NO_AUDIO_DATA MAKE_SAPI_ERROR(0x030)
|
||||
|
||||
/*** SPERR_DEAD_ALTERNATE 0x80045031 -2147200975
|
||||
* This alternate is no longer a valid alternate to the result it was obtained from.
|
||||
* Returned from ISpPhraseAlt methods.
|
||||
*/
|
||||
#define SPERR_DEAD_ALTERNATE MAKE_SAPI_ERROR(0x031)
|
||||
|
||||
/*** SPERR_HIGH_LOW_CONFIDENCE 0x80045032 -2147200974
|
||||
* The result does not contain any audio, nor does the portion of the element chain of the result
|
||||
* contain any audio. Returned from ISpResult::GetAudio and ISpResult::SpeakAudio.
|
||||
*/
|
||||
#define SPERR_HIGH_LOW_CONFIDENCE MAKE_SAPI_ERROR(0x032)
|
||||
|
||||
/*** SPERR_INVALID_FORMAT_STRING 0x80045033 -2147200973
|
||||
* The XML format string for this RULEREF is invalid, e.g. not a GUID or REFCLSID.
|
||||
*/
|
||||
#define SPERR_INVALID_FORMAT_STRING MAKE_SAPI_ERROR(0x033)
|
||||
|
||||
/*** SP_UNSUPPORTED_ON_STREAM_INPUT 0x00045034 282676
|
||||
* The operation is not supported for stream input.
|
||||
*/
|
||||
#define SP_UNSUPPORTED_ON_STREAM_INPUT MAKE_SAPI_SCODE(0x034)
|
||||
|
||||
/*** SPERR_APPLEX_READ_ONLY 0x80045035 -2147200971
|
||||
* The operation is invalid for all but newly created application lexicons.
|
||||
*/
|
||||
#define SPERR_APPLEX_READ_ONLY MAKE_SAPI_ERROR(0x035)
|
||||
|
||||
/*** SPERR_NO_TERMINATING_RULE_PATH 0x80045036 -2147200970
|
||||
*
|
||||
*/
|
||||
|
||||
#define SPERR_NO_TERMINATING_RULE_PATH MAKE_SAPI_ERROR(0x036)
|
||||
|
||||
/*** SP_WORD_EXISTS_WITHOUT_PRONUNCIATION 0x00045037 282679
|
||||
* The word exists but without pronunciation.
|
||||
*/
|
||||
#define SP_WORD_EXISTS_WITHOUT_PRONUNCIATION MAKE_SAPI_SCODE(0x037)
|
||||
|
||||
/*** SPERR_STREAM_CLOSED 0x80045038 -2147200968
|
||||
* An operation was attempted on a stream object that has been closed.
|
||||
*/
|
||||
#define SPERR_STREAM_CLOSED MAKE_SAPI_ERROR(0x038)
|
||||
|
||||
// --- The following error codes are taken directly from WIN32 ---
|
||||
|
||||
/*** SPERR_NO_MORE_ITEMS 0x80045039 -2147200967
|
||||
* When enumerating items, the requested index is greater than the count of items.
|
||||
*/
|
||||
#define SPERR_NO_MORE_ITEMS MAKE_SAPI_ERROR(0x039)
|
||||
|
||||
/*** SPERR_NOT_FOUND 0x8004503a -2147200966
|
||||
* The requested data item (data key, value, etc.) was not found.
|
||||
*/
|
||||
#define SPERR_NOT_FOUND MAKE_SAPI_ERROR(0x03a)
|
||||
|
||||
/*** SPERR_INVALID_AUDIO_STATE 0x8004503b -2147200965
|
||||
* Audio state passed to SetState() is invalid.
|
||||
*/
|
||||
#define SPERR_INVALID_AUDIO_STATE MAKE_SAPI_ERROR(0x03b)
|
||||
|
||||
/*** SPERR_GENERIC_MMSYS_ERROR 0x8004503c -2147200964
|
||||
* A generic MMSYS error not caught by _MMRESULT_TO_HRESULT.
|
||||
*/
|
||||
#define SPERR_GENERIC_MMSYS_ERROR MAKE_SAPI_ERROR(0x03c)
|
||||
|
||||
/*** SPERR_MARSHALER_EXCEPTION 0x8004503d -2147200963
|
||||
* An exception was raised during a call to the marshaling code.
|
||||
*/
|
||||
#define SPERR_MARSHALER_EXCEPTION MAKE_SAPI_ERROR(0x03d)
|
||||
|
||||
/*** SPERR_NOT_DYNAMIC_GRAMMAR 0x8004503e -2147200962
|
||||
* Attempt was made to manipulate a non-dynamic grammar.
|
||||
*/
|
||||
#define SPERR_NOT_DYNAMIC_GRAMMAR MAKE_SAPI_ERROR(0x03e)
|
||||
|
||||
/*** SPERR_AMBIGUOUS_PROPERTY 0x8004503f -2147200961
|
||||
* Cannot add ambiguous property.
|
||||
*/
|
||||
#define SPERR_AMBIGUOUS_PROPERTY MAKE_SAPI_ERROR(0x03f)
|
||||
|
||||
/*** SPERR_INVALID_REGISTRY_KEY 0x80045040 -2147200960
|
||||
* The key specified is invalid.
|
||||
*/
|
||||
#define SPERR_INVALID_REGISTRY_KEY MAKE_SAPI_ERROR(0x040)
|
||||
|
||||
/*** SPERR_INVALID_TOKEN_ID 0x80045041 -2147200959
|
||||
* The token specified is invalid.
|
||||
*/
|
||||
#define SPERR_INVALID_TOKEN_ID MAKE_SAPI_ERROR(0x041)
|
||||
|
||||
/*** SPERR_XML_BAD_SYNTAX 0x80045042 -2147200958
|
||||
* The xml parser failed due to bad syntax.
|
||||
*/
|
||||
#define SPERR_XML_BAD_SYNTAX MAKE_SAPI_ERROR(0x042)
|
||||
|
||||
/*** SPERR_XML_RESOURCE_NOT_FOUND 0x80045043 -2147200957
|
||||
* The xml parser failed to load a required resource (e.g., voice, phoneconverter, etc.).
|
||||
*/
|
||||
#define SPERR_XML_RESOURCE_NOT_FOUND MAKE_SAPI_ERROR(0x043)
|
||||
|
||||
/*** SPERR_TOKEN_IN_USE 0x80045044 -2147200956
|
||||
* Attempted to remove registry data from a token that is already in use elsewhere.
|
||||
*/
|
||||
#define SPERR_TOKEN_IN_USE MAKE_SAPI_ERROR(0x044)
|
||||
|
||||
/*** SPERR_TOKEN_DELETED 0x80045045 -2147200955
|
||||
* Attempted to perform an action on an object token that has had associated registry key deleted.
|
||||
*/
|
||||
#define SPERR_TOKEN_DELETED MAKE_SAPI_ERROR(0x045)
|
||||
|
||||
/*** SPERR_MULTI_LINGUAL_NOT_SUPPORTED 0x80045046 -2147200954
|
||||
* The selected voice was registered as multi-lingual. SAPI does not support multi-lingual registration.
|
||||
*/
|
||||
#define SPERR_MULTI_LINGUAL_NOT_SUPPORTED MAKE_SAPI_ERROR(0x046)
|
||||
|
||||
/*** SPERR_EXPORT_DYNAMIC_RULE 0x80045047 -2147200953
|
||||
* Exported rules cannot refer directly or indirectly to a dynamic rule.
|
||||
*/
|
||||
#define SPERR_EXPORT_DYNAMIC_RULE MAKE_SAPI_ERROR(0x047)
|
||||
|
||||
/*** SPERR_STGF_ERROR 0x80045048 -2147200952
|
||||
* Error parsing the SAPI Text Grammar Format (XML grammar).
|
||||
*/
|
||||
#define SPERR_STGF_ERROR MAKE_SAPI_ERROR(0x048)
|
||||
|
||||
/*** SPERR_WORDFORMAT_ERROR 0x80045049 -2147200951
|
||||
* Incorrect word format, probably due to incorrect pronunciation string.
|
||||
*/
|
||||
#define SPERR_WORDFORMAT_ERROR MAKE_SAPI_ERROR(0x049)
|
||||
|
||||
/*** SPERR_STREAM_NOT_ACTIVE 0x8004504a -2147200950
|
||||
* Methods associated with active audio stream cannot be called unless stream is active.
|
||||
*/
|
||||
#define SPERR_STREAM_NOT_ACTIVE MAKE_SAPI_ERROR(0x04a)
|
||||
|
||||
/*** SPERR_ENGINE_RESPONSE_INVALID 0x8004504b -2147200949
|
||||
* Arguments or data supplied by the engine are in an invalid format or are inconsistent.
|
||||
*/
|
||||
#define SPERR_ENGINE_RESPONSE_INVALID MAKE_SAPI_ERROR(0x04b)
|
||||
|
||||
/*** SPERR_SR_ENGINE_EXCEPTION 0x8004504c -2147200948
|
||||
* An exception was raised during a call to the current SR engine.
|
||||
*/
|
||||
#define SPERR_SR_ENGINE_EXCEPTION MAKE_SAPI_ERROR(0x04c)
|
||||
|
||||
/*** SPERR_STREAM_POS_INVALID 0x8004504d -2147200947
|
||||
* Stream position information supplied from engine is inconsistent.
|
||||
*/
|
||||
#define SPERR_STREAM_POS_INVALID MAKE_SAPI_ERROR(0x04d)
|
||||
|
||||
/*** SP_RECOGNIZER_INACTIVE 0x0004504e 282702
|
||||
* Operation could not be completed because the recognizer is inactive. It is inactive either
|
||||
* because the recognition state is currently inactive or because no rules are active .
|
||||
*/
|
||||
#define SP_RECOGNIZER_INACTIVE MAKE_SAPI_SCODE(0x04e)
|
||||
|
||||
/*** SPERR_REMOTE_CALL_ON_WRONG_THREAD 0x8004504f -2147200945
|
||||
* When making a remote call to the server, the call was made on the wrong thread.
|
||||
*/
|
||||
#define SPERR_REMOTE_CALL_ON_WRONG_THREAD MAKE_SAPI_ERROR(0x04f)
|
||||
|
||||
/*** SPERR_REMOTE_PROCESS_TERMINATED 0x80045050 -2147200944
|
||||
* The remote process terminated unexpectedly.
|
||||
*/
|
||||
#define SPERR_REMOTE_PROCESS_TERMINATED MAKE_SAPI_ERROR(0x050)
|
||||
|
||||
/*** SPERR_REMOTE_PROCESS_ALREADY_RUNNING 0x80045051 -2147200943
|
||||
* The remote process is already running; it cannot be started a second time.
|
||||
*/
|
||||
#define SPERR_REMOTE_PROCESS_ALREADY_RUNNING MAKE_SAPI_ERROR(0x051)
|
||||
|
||||
/*** SPERR_LANGID_MISMATCH 0x80045052 -2147200942
|
||||
* An attempt to load a CFG grammar with a LANGID different than other loaded grammars.
|
||||
*/
|
||||
#define SPERR_LANGID_MISMATCH MAKE_SAPI_ERROR(0x052)
|
||||
|
||||
/*** SP_PARTIAL_PARSE_FOUND 0x00045053 282707
|
||||
* A grammar-ending parse has been found that does not use all available words.
|
||||
*/
|
||||
#define SP_PARTIAL_PARSE_FOUND MAKE_SAPI_SCODE(0x053)
|
||||
|
||||
/*** SPERR_NOT_TOPLEVEL_RULE 0x80045054 -2147200940
|
||||
* An attempt to deactivate or activate a non-toplevel rule.
|
||||
*/
|
||||
#define SPERR_NOT_TOPLEVEL_RULE MAKE_SAPI_ERROR(0x054)
|
||||
|
||||
/*** SP_NO_RULE_ACTIVE 0x00045055 282709
|
||||
* An attempt to parse when no rule was active.
|
||||
*/
|
||||
#define SP_NO_RULE_ACTIVE MAKE_SAPI_SCODE(0x055)
|
||||
|
||||
/*** SPERR_LEX_REQUIRES_COOKIE 0x80045056 -2147200938
|
||||
* An attempt to ask a container lexicon for all words at once.
|
||||
*/
|
||||
#define SPERR_LEX_REQUIRES_COOKIE MAKE_SAPI_ERROR(0x056)
|
||||
|
||||
/*** SP_STREAM_UNINITIALIZED 0x00045057 282711
|
||||
* An attempt to activate a rule/dictation/etc without calling SetInput
|
||||
* first in the inproc case.
|
||||
*/
|
||||
#define SP_STREAM_UNINITIALIZED MAKE_SAPI_SCODE(0x057)
|
||||
|
||||
|
||||
// Error x058 is not used in SAPI 5.0
|
||||
|
||||
|
||||
/*** SPERR_UNSUPPORTED_LANG 0x80045059 -2147200935
|
||||
* The requested language is not supported.
|
||||
*/
|
||||
#define SPERR_UNSUPPORTED_LANG MAKE_SAPI_ERROR(0x059)
|
||||
|
||||
/*** SPERR_VOICE_PAUSED 0x8004505a -2147200934
|
||||
* The operation cannot be performed because the voice is currently paused.
|
||||
*/
|
||||
#define SPERR_VOICE_PAUSED MAKE_SAPI_ERROR(0x05a)
|
||||
|
||||
/*** SPERR_AUDIO_BUFFER_UNDERFLOW 0x8004505b -2147200933
|
||||
* This will only be returned on input (read) streams when the real time audio device
|
||||
* stops returning data for a long period of time.
|
||||
*/
|
||||
#define SPERR_AUDIO_BUFFER_UNDERFLOW MAKE_SAPI_ERROR(0x05b)
|
||||
|
||||
/*** SPERR_AUDIO_STOPPED_UNEXPECTEDLY 0x8004505c -2147200932
|
||||
* An audio device stopped returning data from the Read() method even though it was in
|
||||
* the run state. This error is only returned in the END_SR_STREAM event.
|
||||
*/
|
||||
#define SPERR_AUDIO_STOPPED_UNEXPECTEDLY MAKE_SAPI_ERROR(0x05c)
|
||||
|
||||
/*** SPERR_NO_WORD_PRONUNCIATION 0x8004505d -2147200931
|
||||
* The SR engine is unable to add this word to a grammar. The application may need to supply
|
||||
* an explicit pronunciation for this word.
|
||||
*/
|
||||
#define SPERR_NO_WORD_PRONUNCIATION MAKE_SAPI_ERROR(0x05d)
|
||||
|
||||
/*** SPERR_ALTERNATES_WOULD_BE_INCONSISTENT 0x8004505e -2147200930
|
||||
* An attempt to call ScaleAudio on a recognition result having previously
|
||||
* called GetAlternates. Allowing the call to succeed would result in
|
||||
* the previously created alternates located in incorrect audio stream positions.
|
||||
*/
|
||||
#define SPERR_ALTERNATES_WOULD_BE_INCONSISTENT MAKE_SAPI_ERROR(0x05e)
|
||||
|
||||
/*** SPERR_NOT_SUPPORTED_FOR_SHARED_RECOGNIZER 0x8004505f -2147200929
|
||||
* The method called is not supported for the shared recognizer.
|
||||
* For example, ISpRecognizer::GetInputStream().
|
||||
*/
|
||||
#define SPERR_NOT_SUPPORTED_FOR_SHARED_RECOGNIZER MAKE_SAPI_ERROR(0x05f)
|
||||
|
||||
/*** SPERR_TIMEOUT 0x80045060 -2147200928
|
||||
* A task could not complete because the SR engine had timed out.
|
||||
*/
|
||||
#define SPERR_TIMEOUT MAKE_SAPI_ERROR(0x060)
|
||||
|
||||
|
||||
/*** SPERR_REENTER_SYNCHRONIZE 0x80045061 -2147200927
|
||||
* A SR engine called synchronize while inside of a synchronize call.
|
||||
*/
|
||||
#define SPERR_REENTER_SYNCHRONIZE MAKE_SAPI_ERROR(0x061)
|
||||
|
||||
/*** SPERR_STATE_WITH_NO_ARCS 0x80045062 -2147200926
|
||||
* The grammar contains a node no arcs.
|
||||
*/
|
||||
#define SPERR_STATE_WITH_NO_ARCS MAKE_SAPI_ERROR(0x062)
|
||||
|
||||
/*** SPERR_NOT_ACTIVE_SESSION 0x80045063 -2147200925
|
||||
* Neither audio output and input is supported for non-active console sessions.
|
||||
*/
|
||||
#define SPERR_NOT_ACTIVE_SESSION MAKE_SAPI_ERROR(0x063)
|
||||
|
||||
/*** SPERR_ALREADY_DELETED 0x80045064 -2147200924
|
||||
* The object is a stale reference and is invalid to use.
|
||||
* For example having a ISpeechGrammarRule object reference and then calling
|
||||
* ISpeechRecoGrammar::Reset() will cause the rule object to be invalidated.
|
||||
* Calling any methods after this will result in this error.
|
||||
*/
|
||||
#define SPERR_ALREADY_DELETED MAKE_SAPI_ERROR(0x064)
|
||||
|
||||
/*** SP_AUDIO_STOPPED 0x00045065 282725
|
||||
* This can be returned from Read or Write calls audio streams when the stream is stopped.
|
||||
*/
|
||||
#define SP_AUDIO_STOPPED MAKE_SAPI_SCODE(0x065)
|
||||
|
||||
#endif //--- This must be the last line in the file
|
605
speech2/third_party/sapi5/include/speventq.h
vendored
Normal file
605
speech2/third_party/sapi5/include/speventq.h
vendored
Normal file
|
@ -0,0 +1,605 @@
|
|||
/*******************************************************************************
|
||||
* SPEventQ.h *
|
||||
*------------*
|
||||
* Description:
|
||||
* This is the header file for the SAPI5 event queue implementation.
|
||||
*-------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
*******************************************************************************/
|
||||
#ifndef SPEventQ_h
|
||||
#define SPEventQ_h
|
||||
|
||||
#ifndef SPHelper_h
|
||||
#include <SPHelper.h>
|
||||
#endif
|
||||
|
||||
#ifndef SPCollec_h
|
||||
#include <SPCollec.h>
|
||||
#endif
|
||||
|
||||
//=== Inline helpers for copying and deleting events ============================
|
||||
|
||||
|
||||
//=== Class definition ==========================================================
|
||||
|
||||
class CSpEventNode : public CSpEvent
|
||||
{
|
||||
public:
|
||||
CSpEventNode * m_pNext;
|
||||
static LONG Compare(const CSpEventNode * p1, const CSpEventNode *p2)
|
||||
{
|
||||
// Assumes offsets DO or DO NOT reset when stream number changes
|
||||
if (p1->ulStreamNum < p2->ulStreamNum)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (p1->ulStreamNum > p2->ulStreamNum)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (p1->ullAudioStreamOffset < p2->ullAudioStreamOffset)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (p1->ullAudioStreamOffset > p2->ullAudioStreamOffset)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef CSpBasicQueue<CSpEventNode, TRUE, TRUE> CSpEventList;
|
||||
|
||||
#define DECLARE_SPNOTIFYSOURCE_METHODS(T) \
|
||||
STDMETHODIMP SetNotifySink(ISpNotifySink * pNotifySink) \
|
||||
{ return T._SetNotifySink(pNotifySink); } \
|
||||
STDMETHODIMP SetNotifyWindowMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) \
|
||||
{ return T._SetNotifyWindowMessage(hWnd, Msg, wParam, lParam); } \
|
||||
STDMETHODIMP SetNotifyCallbackFunction(SPNOTIFYCALLBACK * pfnCallback, WPARAM wParam, LPARAM lParam) \
|
||||
{ return T._SetNotifyCallbackFunction(pfnCallback, wParam, lParam); } \
|
||||
STDMETHODIMP SetNotifyCallbackInterface(ISpNotifyCallback * pSpCallback, WPARAM wParam, LPARAM lParam) \
|
||||
{ return T._SetNotifyCallbackInterface(pSpCallback, wParam, lParam); } \
|
||||
STDMETHODIMP SetNotifyWin32Event() \
|
||||
{ return T._SetNotifyWin32Event(); } \
|
||||
STDMETHODIMP WaitForNotifyEvent(DWORD dwMilliseconds) \
|
||||
{ return T._WaitForNotifyEvent(dwMilliseconds); } \
|
||||
STDMETHODIMP_(HANDLE) GetNotifyEventHandle() \
|
||||
{ return T._GetNotifyEventHandle(); }
|
||||
|
||||
#define DECLARE_SPEVENTSOURCE_METHODS(T) \
|
||||
DECLARE_SPNOTIFYSOURCE_METHODS(T) \
|
||||
STDMETHODIMP SetInterest(ULONGLONG ullEventInterest, ULONGLONG ullQueuedInterest) \
|
||||
{ return T._SetInterest(ullEventInterest, ullQueuedInterest); } \
|
||||
STDMETHODIMP GetEvents(ULONG ulCount, SPEVENT* pEventArray, ULONG * pulFetched) \
|
||||
{ return T._GetEvents(ulCount, pEventArray, pulFetched); } \
|
||||
STDMETHODIMP GetInfo(SPEVENTSOURCEINFO *pInfo) \
|
||||
{ return T._GetInfo(pInfo); }
|
||||
|
||||
|
||||
|
||||
class CSpEventSource
|
||||
{
|
||||
public:
|
||||
CSpEventSource(CComObjectRootEx<CComMultiThreadModel> * pParent) :
|
||||
m_pParent(pParent)
|
||||
{
|
||||
m_ullEventInterest = 0; m_ullQueuedInterest = 0;
|
||||
m_ulStreamNum = 0;
|
||||
}
|
||||
HRESULT _SetNotifySink(ISpNotifySink * pNotifySink);
|
||||
HRESULT _SetNotifyWindowMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||
HRESULT _SetNotifyCallbackFunction(SPNOTIFYCALLBACK * pfnCallback, WPARAM wParam, LPARAM lParam);
|
||||
HRESULT _SetNotifyCallbackInterface(ISpNotifyCallback * pSpCallback, WPARAM wParam, LPARAM lParam);
|
||||
HRESULT _SetNotifyWin32Event();
|
||||
HRESULT _WaitForNotifyEvent(DWORD dwMilliseconds);
|
||||
HANDLE _GetNotifyEventHandle();
|
||||
|
||||
HRESULT _SetInterest(ULONGLONG ullEventInterest , ULONGLONG ullQueuedInterest);
|
||||
HRESULT _GetEvents( ULONG ulCount, SPEVENT* pEventArray, ULONG * pulFetched );
|
||||
HRESULT _GetInfo(SPEVENTSOURCEINFO *pInfo );
|
||||
|
||||
/*--- Non interface methods ---*/
|
||||
HRESULT _CompleteEvents( ULONGLONG ullPos = 0xFFFFFFFFFFFFFFFF );
|
||||
inline void _MoveAllToFreeList(CSpEventList * pList);
|
||||
inline void _RemoveAllEvents();
|
||||
inline HRESULT _AddEvent(const SPEVENT & Event);
|
||||
inline HRESULT _AddEvents(const SPEVENT* pEventArray, ULONG ulCount);
|
||||
inline HRESULT _DeserializeAndAddEvent(const BYTE * pBuffer, ULONG * pcbUsed);
|
||||
inline HRESULT _GetStreamNumber(const ULONGLONG ullAudioOffset, ULONG *pulStreamNum);
|
||||
//=== Data members ==============================
|
||||
public:
|
||||
ULONGLONG m_ullEventInterest;
|
||||
ULONGLONG m_ullQueuedInterest;
|
||||
ULONG m_ulStreamNum;
|
||||
CSpEventList m_PendingList;
|
||||
CSpEventList m_CompletedList;
|
||||
CSpEventList m_FreeList;
|
||||
CComPtr<ISpNotifySink> m_cpNotifySink;
|
||||
CComPtr<ISpNotifyTranslator> m_cpEventTranslator; // If non-NULL then Win32 events being used
|
||||
CComObjectRootEx<CComMultiThreadModel> * m_pParent;
|
||||
CComAutoCriticalSection m_NotifyObjChangeCrit; // Critical section used to make sure that
|
||||
// the notify object (m_cpNotifySink) not changed
|
||||
// while waiting on it.
|
||||
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
//=== Inlines =========================================================
|
||||
//
|
||||
|
||||
//
|
||||
// WARNING: If this logic changes, you will need to change the logic in SetNotifyWin32Event also.
|
||||
//
|
||||
inline HRESULT CSpEventSource::_SetNotifySink(ISpNotifySink * pNotifySink)
|
||||
{
|
||||
if (SP_IS_BAD_OPTIONAL_INTERFACE_PTR(pNotifySink))
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pParent->Lock();
|
||||
m_NotifyObjChangeCrit.Lock();
|
||||
m_cpEventTranslator.Release();
|
||||
m_cpNotifySink = pNotifySink;
|
||||
if (m_cpNotifySink && m_CompletedList.GetHead())
|
||||
{
|
||||
m_cpNotifySink->Notify();
|
||||
}
|
||||
m_NotifyObjChangeCrit.Unlock();
|
||||
m_pParent->Unlock();
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* CSpEventSource::_SetNotifyWindowMessage *
|
||||
*-----------------------------------------*
|
||||
* Description:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
********************************************************************* RAL ***/
|
||||
|
||||
inline HRESULT CSpEventSource::_SetNotifyWindowMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
SPDBG_FUNC("CSpEventSource::_SetNotifyWindowMessage");
|
||||
HRESULT hr = S_OK;
|
||||
CComPtr<ISpNotifyTranslator> cpTranslator;
|
||||
hr = cpTranslator.CoCreateInstance(CLSID_SpNotifyTranslator);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = cpTranslator->InitWindowMessage(hWnd, Msg, wParam, lParam);
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = _SetNotifySink(cpTranslator);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
/****************************************************************************
|
||||
* CSpEventSource::_SetNotifyCallbackFunction *
|
||||
*--------------------------------------------*
|
||||
* Description:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
********************************************************************* RAL ***/
|
||||
|
||||
inline HRESULT CSpEventSource::_SetNotifyCallbackFunction(SPNOTIFYCALLBACK * pfnCallback, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
SPDBG_FUNC("CSpEventSource::_SetNotifyCallbackFunction");
|
||||
HRESULT hr = S_OK;
|
||||
CComPtr<ISpNotifyTranslator> cpTranslator;
|
||||
hr = cpTranslator.CoCreateInstance(CLSID_SpNotifyTranslator);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = cpTranslator->InitCallback(pfnCallback, wParam, lParam);
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = _SetNotifySink(cpTranslator);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
/****************************************************************************
|
||||
* CSpEventSource::_SetNotifyCallbackInterface *
|
||||
*---------------------------------------------*
|
||||
* Description:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
********************************************************************* RAL ***/
|
||||
|
||||
inline HRESULT CSpEventSource::_SetNotifyCallbackInterface(ISpNotifyCallback * pSpCallback, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
SPDBG_FUNC("CSpEventSource::_SetNotifyCallbackInterface");
|
||||
HRESULT hr = S_OK;
|
||||
CComPtr<ISpNotifyTranslator> cpTranslator;
|
||||
hr = cpTranslator.CoCreateInstance(CLSID_SpNotifyTranslator);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = cpTranslator->InitSpNotifyCallback(pSpCallback, wParam, lParam);
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = _SetNotifySink(cpTranslator);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
/****************************************************************************
|
||||
* CSpEventSource::_SetNotifyWin32Event *
|
||||
*--------------------------------------*
|
||||
* Description:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
********************************************************************* RAL ***/
|
||||
|
||||
inline HRESULT CSpEventSource::_SetNotifyWin32Event(void)
|
||||
{
|
||||
SPDBG_FUNC("CSpEventSource::_SetNotifyWin32Event");
|
||||
HRESULT hr = S_OK;
|
||||
CComPtr<ISpNotifyTranslator> cpTranslator;
|
||||
hr = cpTranslator.CoCreateInstance(CLSID_SpNotifyTranslator);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = cpTranslator->InitWin32Event(NULL, TRUE);
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
//
|
||||
// In this case we do NOT call _SetNotify sink since we want to set the cpEventTranslator
|
||||
//
|
||||
m_pParent->Lock();
|
||||
m_NotifyObjChangeCrit.Lock();
|
||||
m_cpEventTranslator = cpTranslator;
|
||||
m_cpNotifySink = cpTranslator;
|
||||
if (m_cpNotifySink && m_CompletedList.GetHead())
|
||||
{
|
||||
m_cpNotifySink->Notify();
|
||||
}
|
||||
m_NotifyObjChangeCrit.Unlock();
|
||||
m_pParent->Unlock();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
/****************************************************************************
|
||||
* CSpEventSource::_WaitForNotifyEvent *
|
||||
*-------------------------------------*
|
||||
* Description:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
********************************************************************* RAL ***/
|
||||
|
||||
inline HRESULT CSpEventSource::_WaitForNotifyEvent(DWORD dwMilliseconds)
|
||||
{
|
||||
SPDBG_FUNC("CSpEventSource::_WaitForNotifyEvent");
|
||||
HRESULT hr = S_OK;
|
||||
m_NotifyObjChangeCrit.Lock();
|
||||
if (m_cpEventTranslator)
|
||||
{
|
||||
hr = m_cpEventTranslator->Wait(dwMilliseconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_cpNotifySink)
|
||||
{
|
||||
hr = SPERR_ALREADY_INITIALIZED;
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = _SetNotifyWin32Event();
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = m_cpEventTranslator->Wait(dwMilliseconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_NotifyObjChangeCrit.Unlock();
|
||||
return hr;
|
||||
}
|
||||
/****************************************************************************
|
||||
* CSpEventSource::_GetNotifyEventHandle *
|
||||
*---------------------------------------*
|
||||
* Description:
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
********************************************************************* RAL ***/
|
||||
|
||||
inline HANDLE CSpEventSource::_GetNotifyEventHandle()
|
||||
{
|
||||
HANDLE h = NULL;
|
||||
SPDBG_FUNC("CSpEventSource::_GetNotifyEventHandle");
|
||||
m_NotifyObjChangeCrit.Lock();
|
||||
if (!m_cpNotifySink)
|
||||
{
|
||||
_SetNotifyWin32Event();
|
||||
}
|
||||
if (m_cpEventTranslator)
|
||||
{
|
||||
h = m_cpEventTranslator->GetEventHandle();
|
||||
}
|
||||
m_NotifyObjChangeCrit.Unlock();
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
inline HRESULT CSpEventSource::_SetInterest( ULONGLONG ullEventInterest, ULONGLONG ullQueuedInterest )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
m_pParent->Lock();
|
||||
|
||||
if(ullEventInterest && SPFEI_FLAGCHECK != (ullEventInterest & SPFEI_FLAGCHECK))
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
}
|
||||
else if(ullQueuedInterest && SPFEI_FLAGCHECK != (ullQueuedInterest & SPFEI_FLAGCHECK))
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
}
|
||||
else if ((ullQueuedInterest | ullEventInterest) != ullEventInterest)
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ullEventInterest = ullEventInterest;
|
||||
m_ullQueuedInterest = ullQueuedInterest;
|
||||
}
|
||||
m_pParent->Unlock();
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Same as AddEvents except: No param validation, and caller must take the critical section
|
||||
// prior to calling.
|
||||
//
|
||||
inline HRESULT CSpEventSource::_AddEvents( const SPEVENT* pEventArray, ULONG ulCount )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
for( ULONG i = 0; i < ulCount && SUCCEEDED(hr = _AddEvent(pEventArray[i])); ++i ) {}
|
||||
return hr;
|
||||
}
|
||||
|
||||
inline HRESULT CSpEventSource::_AddEvent(const SPEVENT & Event)
|
||||
{
|
||||
SPDBG_ASSERT(Event.eEventId < 64);
|
||||
SPDBG_ASSERT(Event.elParamType == SPET_LPARAM_IS_UNDEFINED ||
|
||||
Event.elParamType == SPET_LPARAM_IS_TOKEN ||
|
||||
Event.elParamType == SPET_LPARAM_IS_OBJECT ||
|
||||
Event.elParamType == SPET_LPARAM_IS_POINTER ||
|
||||
Event.elParamType == SPET_LPARAM_IS_STRING);
|
||||
#ifdef _DEBUG
|
||||
if (Event.eEventId == SPEI_VOICE_CHANGE)
|
||||
{
|
||||
SPDBG_ASSERT(Event.elParamType == SPET_LPARAM_IS_TOKEN);
|
||||
}
|
||||
else if (Event.eEventId == SPEI_RECOGNITION || Event.eEventId == SPEI_FALSE_RECOGNITION || Event.eEventId == SPEI_HYPOTHESIS)
|
||||
{
|
||||
SPDBG_ASSERT(Event.elParamType == SPET_LPARAM_IS_OBJECT);
|
||||
}
|
||||
else if (Event.eEventId ==SPEI_REQUEST_UI || Event.eEventId == SPEI_TTS_BOOKMARK)
|
||||
{
|
||||
SPDBG_ASSERT(Event.elParamType == SPET_LPARAM_IS_STRING);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( (1i64 << Event.eEventId) & m_ullEventInterest )
|
||||
{
|
||||
CSpEventNode *pNode = m_FreeList.RemoveHead();
|
||||
if (pNode == NULL)
|
||||
{
|
||||
pNode = new CSpEventNode();
|
||||
if (pNode == NULL)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
pNode->CopyFrom(&Event);
|
||||
m_PendingList.InsertSorted(pNode);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
inline HRESULT CSpEventSource::
|
||||
_DeserializeAndAddEvent(const BYTE *pBuffer, ULONG * pcbUsed)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
const SPEVENT * pSrcEvent = (const SPEVENT *)pBuffer;
|
||||
SPDBG_ASSERT(pSrcEvent->eEventId < 64);
|
||||
if ( (1i64 << pSrcEvent->eEventId) & m_ullEventInterest )
|
||||
{
|
||||
CSpEventNode *pNode = m_FreeList.RemoveHead();
|
||||
if (pNode == NULL)
|
||||
{
|
||||
pNode = new CSpEventNode();
|
||||
if (pNode == NULL)
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = pNode->Deserialize(((const SPSERIALIZEDEVENT64 *)(pBuffer)), pcbUsed);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
m_PendingList.InsertSorted(pNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_FreeList.InsertHead(pNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// WCE compiler does not work propertly with template
|
||||
#ifndef _WIN32_WCE
|
||||
*pcbUsed = SpEventSerializeSize<SPSERIALIZEDEVENT64>(pSrcEvent);
|
||||
#else
|
||||
*pcbUsed = SpEventSerializeSize(pSrcEvent, sizeof(SPSERIALIZEDEVENT64));
|
||||
#endif
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
inline HRESULT CSpEventSource::_GetEvents( ULONG ulCount, SPEVENT* pEventArray, ULONG *pulFetched )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
m_pParent->Lock();
|
||||
if( SPIsBadWritePtr( pEventArray, sizeof( SPEVENT ) * ulCount ) ||
|
||||
SP_IS_BAD_OPTIONAL_WRITE_PTR(pulFetched) )
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
}
|
||||
else
|
||||
{
|
||||
ULONG ulCopied = 0;
|
||||
ULONG ulRemaining = ulCount;
|
||||
CSpEventNode * pCur = m_CompletedList.m_pHead;
|
||||
CSpEventNode * pLastCopied = NULL;
|
||||
while (ulRemaining && pCur)
|
||||
{
|
||||
pCur->Detach(pEventArray + ulCopied);
|
||||
pLastCopied = pCur;
|
||||
ulCopied++;
|
||||
pCur = pCur->m_pNext;
|
||||
ulRemaining--;
|
||||
}
|
||||
if (ulCopied)
|
||||
{
|
||||
if (m_FreeList.m_pHead == NULL)
|
||||
{
|
||||
m_FreeList.m_pTail = pLastCopied;
|
||||
}
|
||||
pLastCopied->m_pNext = m_FreeList.m_pHead;
|
||||
m_FreeList.m_pHead = m_CompletedList.m_pHead;
|
||||
m_CompletedList.m_pHead = pCur;
|
||||
m_CompletedList.m_cElements -= ulCopied;
|
||||
m_FreeList.m_cElements += ulCopied;
|
||||
}
|
||||
if (ulCopied < ulCount)
|
||||
{
|
||||
hr = S_FALSE;
|
||||
}
|
||||
if (pulFetched)
|
||||
{
|
||||
*pulFetched = ulCopied;
|
||||
}
|
||||
}
|
||||
m_pParent->Unlock();
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
inline HRESULT CSpEventSource::_GetInfo( SPEVENTSOURCEINFO * pInfo )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
m_pParent->Lock();
|
||||
if( SP_IS_BAD_WRITE_PTR( pInfo ) )
|
||||
{
|
||||
hr = E_POINTER;
|
||||
}
|
||||
else
|
||||
{
|
||||
pInfo->ulCount = m_CompletedList.GetCount();
|
||||
pInfo->ullEventInterest = m_ullEventInterest;
|
||||
pInfo->ullQueuedInterest= m_ullQueuedInterest;
|
||||
}
|
||||
m_pParent->Unlock();
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// The caller must call this function with the critical section owned
|
||||
//
|
||||
inline HRESULT CSpEventSource::_CompleteEvents( ULONGLONG ullPos )
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (m_PendingList.m_pHead && m_PendingList.m_pHead->ullAudioStreamOffset <= ullPos)
|
||||
{
|
||||
BOOL bNotify = FALSE;
|
||||
while (m_PendingList.m_pHead &&
|
||||
m_PendingList.m_pHead->ullAudioStreamOffset <= ullPos)
|
||||
{
|
||||
CSpEventNode *pNode = m_PendingList.RemoveHead();
|
||||
if(pNode->ulStreamNum != m_ulStreamNum)
|
||||
{
|
||||
m_ulStreamNum = pNode->ulStreamNum;
|
||||
}
|
||||
if ( (1i64 << pNode->eEventId) & m_ullEventInterest )
|
||||
{
|
||||
bNotify = TRUE;
|
||||
//
|
||||
// NOTE: If we're forwarding events to an event sink then we'll only
|
||||
// pay attention to the Interest flags. If we're going to notify, then
|
||||
// we'll only queue completed events that the user has explicitly asked
|
||||
// us to store as completed events.
|
||||
//
|
||||
if ( (1i64 << pNode->eEventId) & m_ullQueuedInterest )
|
||||
{
|
||||
m_CompletedList.InsertSorted(pNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
pNode->Clear();
|
||||
m_FreeList.InsertHead(pNode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pNode->Clear();
|
||||
m_FreeList.InsertHead(pNode);
|
||||
}
|
||||
}
|
||||
if (bNotify && m_cpNotifySink)
|
||||
{
|
||||
hr = m_cpNotifySink->Notify();
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
};
|
||||
|
||||
|
||||
inline void CSpEventSource::_MoveAllToFreeList(CSpEventList * pList)
|
||||
{
|
||||
CSpEventNode * pNode;
|
||||
while ((pNode = pList->RemoveHead()) != NULL)
|
||||
{
|
||||
pNode->Clear();
|
||||
m_FreeList.InsertHead(pNode);
|
||||
}
|
||||
}
|
||||
inline void CSpEventSource::_RemoveAllEvents( )
|
||||
{
|
||||
m_pParent->Lock();
|
||||
|
||||
_MoveAllToFreeList(&m_CompletedList);
|
||||
_MoveAllToFreeList(&m_PendingList);
|
||||
m_pParent->Unlock();
|
||||
}
|
||||
|
||||
inline HRESULT CSpEventSource::_GetStreamNumber(const ULONGLONG ullAudioOffset, ULONG *pulStreamNum)
|
||||
{
|
||||
CSpEventNode *pNode = m_PendingList.m_pHead;
|
||||
*pulStreamNum = m_ulStreamNum;
|
||||
for(;pNode && pNode->ullAudioStreamOffset <= ullAudioOffset; pNode = pNode->m_pNext)
|
||||
{
|
||||
*pulStreamNum = pNode->ulStreamNum;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //--- This must be the last line in this file
|
2753
speech2/third_party/sapi5/include/sphelper.h
vendored
Normal file
2753
speech2/third_party/sapi5/include/sphelper.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
253
speech2/third_party/sapi5/include/spuihelp.h
vendored
Normal file
253
speech2/third_party/sapi5/include/spuihelp.h
vendored
Normal file
|
@ -0,0 +1,253 @@
|
|||
/*******************************************************************************
|
||||
* SPUIHelp.h *
|
||||
*------------*
|
||||
* Description:
|
||||
* This is the header file for user-interface helper functions. Note that
|
||||
* unlike SpHelper.H, this file requires the use of ATL.
|
||||
*-------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef SPUIHelp_h
|
||||
#define SPUIHelp_h
|
||||
|
||||
#ifndef __sapi_h__
|
||||
#include <sapi.h>
|
||||
#endif
|
||||
|
||||
#ifndef SPError_h
|
||||
#include <SPError.h>
|
||||
#endif
|
||||
|
||||
#ifndef SPDebug_h
|
||||
#include <SPDebug.h>
|
||||
#endif
|
||||
|
||||
#ifndef SPHelper_h
|
||||
#include <SPHelper.h>
|
||||
#endif
|
||||
|
||||
#ifndef __ATLBASE_H__
|
||||
#include <ATLBASE.h>
|
||||
#endif
|
||||
|
||||
#ifndef __ATLCONV_H__
|
||||
#include <ATLCONV.H>
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
*
|
||||
*
|
||||
********************************************************************* RAL ***/
|
||||
|
||||
//
|
||||
// Dont call this function directly. Use SpInitTokenComboBox or SpInitTokenListBox.
|
||||
//
|
||||
inline HRESULT SpInitTokenList(UINT MsgAddString, UINT MsgSetItemData, UINT MsgSetCurSel,
|
||||
HWND hwnd, const WCHAR * pszCatName,
|
||||
const WCHAR * pszRequiredAttrib, const WCHAR * pszOptionalAttrib)
|
||||
{
|
||||
HRESULT hr;
|
||||
ISpObjectToken * pToken; // NOTE: Not a CComPtr! Be Careful.
|
||||
CComPtr<IEnumSpObjectTokens> cpEnum;
|
||||
hr = SpEnumTokens(pszCatName, pszRequiredAttrib, pszOptionalAttrib, &cpEnum);
|
||||
if (hr == S_OK)
|
||||
{
|
||||
bool fSetDefault = false;
|
||||
while (cpEnum->Next(1, &pToken, NULL) == S_OK)
|
||||
{
|
||||
CSpDynamicString dstrDesc;
|
||||
hr = SpGetDescription(pToken, &dstrDesc);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
USES_CONVERSION;
|
||||
LRESULT i = ::SendMessage(hwnd, MsgAddString, 0, (LPARAM)W2T(dstrDesc));
|
||||
if (i == CB_ERR || i == CB_ERRSPACE) // Note: CB_ and LB_ errors are identical values...
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
::SendMessage(hwnd, MsgSetItemData, i, (LPARAM)pToken);
|
||||
if (!fSetDefault)
|
||||
{
|
||||
::SendMessage(hwnd, MsgSetCurSel, i, 0);
|
||||
fSetDefault = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (FAILED(hr))
|
||||
{
|
||||
pToken->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = SPERR_NO_MORE_ITEMS;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
inline HRESULT SpInitTokenComboBox(HWND hwnd, const WCHAR * pszCatName,
|
||||
const WCHAR * pszRequiredAttrib = NULL, const WCHAR * pszOptionalAttrib = NULL)
|
||||
{
|
||||
return SpInitTokenList(CB_ADDSTRING, CB_SETITEMDATA, CB_SETCURSEL, hwnd, pszCatName, pszRequiredAttrib, pszOptionalAttrib);
|
||||
}
|
||||
|
||||
inline HRESULT SpInitTokenListBox(HWND hwnd, const WCHAR * pszCatName,
|
||||
const WCHAR * pszRequiredAttrib = NULL, const WCHAR * pszOptionalAttrib = NULL)
|
||||
{
|
||||
return SpInitTokenList(LB_ADDSTRING, LB_SETITEMDATA, LB_SETCURSEL, hwnd, pszCatName, pszRequiredAttrib, pszOptionalAttrib);
|
||||
}
|
||||
|
||||
//
|
||||
// Dont call this function directly. Use SpDestoyTokenComboBox or SpDestroyTokenListBox.
|
||||
//
|
||||
inline void SpDestroyTokenList(UINT MsgGetCount, UINT MsgGetItemData, HWND hwnd)
|
||||
{
|
||||
LRESULT c = ::SendMessage(hwnd, MsgGetCount, 0, 0);
|
||||
for (LRESULT i = 0; i < c; i++)
|
||||
{
|
||||
IUnknown * pUnkObj = (IUnknown *)::SendMessage(hwnd, MsgGetItemData, i, 0);
|
||||
if (pUnkObj)
|
||||
{
|
||||
pUnkObj->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void SpDestroyTokenComboBox(HWND hwnd)
|
||||
{
|
||||
SpDestroyTokenList(CB_GETCOUNT, CB_GETITEMDATA, hwnd);
|
||||
}
|
||||
|
||||
inline void SpDestroyTokenListBox(HWND hwnd)
|
||||
{
|
||||
SpDestroyTokenList(LB_GETCOUNT, LB_GETITEMDATA, hwnd);
|
||||
}
|
||||
|
||||
|
||||
inline ISpObjectToken * SpGetComboBoxToken(HWND hwnd, WPARAM Index)
|
||||
{
|
||||
return (ISpObjectToken *)::SendMessage(hwnd, CB_GETITEMDATA, Index, 0);
|
||||
}
|
||||
|
||||
inline ISpObjectToken * SpGetListBoxToken(HWND hwnd, WPARAM Index)
|
||||
{
|
||||
return (ISpObjectToken *)::SendMessage(hwnd, LB_GETITEMDATA, Index, 0);
|
||||
}
|
||||
|
||||
inline ISpObjectToken * SpGetCurSelComboBoxToken(HWND hwnd)
|
||||
{
|
||||
LRESULT i = ::SendMessage(hwnd, CB_GETCURSEL, 0, 0);
|
||||
return (i == CB_ERR) ? NULL : SpGetComboBoxToken(hwnd, i);
|
||||
}
|
||||
|
||||
inline ISpObjectToken * SpGetCurSelListBoxToken(HWND hwnd)
|
||||
{
|
||||
LRESULT i = ::SendMessage(hwnd, LB_GETCURSEL, 0, 0);
|
||||
return (i == LB_ERR) ? NULL : SpGetListBoxToken(hwnd, i);
|
||||
}
|
||||
|
||||
//
|
||||
// Don't call this directly. Use SpUpdateCurSelComboBoxToken or SpUpdateCurSelListBoxToken
|
||||
//
|
||||
inline HRESULT SpUpdateCurSelToken(UINT MsgDelString, UINT MsgInsertString, UINT MsgGetItemData, UINT MsgSetItemData, UINT MsgGetCurSel, UINT MsgSetCurSel,
|
||||
HWND hwnd)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
LRESULT i = ::SendMessage(hwnd, MsgGetCurSel, 0, 0);
|
||||
if (i != CB_ERR)
|
||||
{
|
||||
ISpObjectToken * pToken = (ISpObjectToken *)::SendMessage(hwnd, MsgGetItemData, i, 0);
|
||||
CSpDynamicString dstrDesc;
|
||||
hr = SpGetDescription(pToken, &dstrDesc);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
USES_CONVERSION;
|
||||
::SendMessage(hwnd, MsgDelString, i, 0);
|
||||
::SendMessage(hwnd, MsgInsertString, i, (LPARAM)W2T(dstrDesc));
|
||||
::SendMessage(hwnd, MsgSetItemData, i, (LPARAM)pToken);
|
||||
::SendMessage(hwnd, MsgSetCurSel, i, 0);
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
inline HRESULT SpUpdateCurSelComboBoxToken(HWND hwnd)
|
||||
{
|
||||
return SpUpdateCurSelToken(CB_DELETESTRING, CB_INSERTSTRING, CB_GETITEMDATA, CB_SETITEMDATA, CB_GETCURSEL, CB_SETCURSEL, hwnd);
|
||||
}
|
||||
|
||||
inline HRESULT SpUpdateCurSelListBoxToken(HWND hwnd)
|
||||
{
|
||||
return SpUpdateCurSelToken(LB_DELETESTRING, LB_INSERTSTRING, LB_GETITEMDATA, LB_SETITEMDATA, LB_GETCURSEL, LB_SETCURSEL, hwnd);
|
||||
}
|
||||
|
||||
inline HRESULT SpAddTokenToList(UINT MsgAddString, UINT MsgSetItemData, UINT MsgSetCurSel, HWND hwnd, ISpObjectToken * pToken)
|
||||
{
|
||||
CSpDynamicString dstrDesc;
|
||||
HRESULT hr = SpGetDescription(pToken, &dstrDesc);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
USES_CONVERSION;
|
||||
LRESULT i = ::SendMessage(hwnd, MsgAddString, 0, (LPARAM)W2T(dstrDesc));
|
||||
if (i == CB_ERR || i == CB_ERRSPACE) // Note: CB_ and LB_ errors are identical values...
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
::SendMessage(hwnd, MsgSetItemData, i, (LPARAM)pToken);
|
||||
::SendMessage(hwnd, MsgSetCurSel, i, 0);
|
||||
pToken->AddRef();
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
inline HRESULT SpAddTokenToComboBox(HWND hwnd, ISpObjectToken * pToken)
|
||||
{
|
||||
return SpAddTokenToList(CB_ADDSTRING, CB_SETITEMDATA, CB_SETCURSEL, hwnd, pToken);
|
||||
}
|
||||
|
||||
inline HRESULT SpAddTokenToListBox(HWND hwnd, ISpObjectToken * pToken)
|
||||
{
|
||||
return SpAddTokenToList(LB_ADDSTRING, LB_SETITEMDATA, LB_SETCURSEL, hwnd, pToken);
|
||||
}
|
||||
|
||||
|
||||
inline HRESULT SpDeleteCurSelToken(UINT MsgGetCurSel, UINT MsgSetCurSel, UINT MsgGetItemData, UINT MsgDeleteString, HWND hwnd)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
LRESULT i = ::SendMessage(hwnd, MsgGetCurSel, 0, 0);
|
||||
if (i == CB_ERR)
|
||||
{
|
||||
hr = S_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ISpObjectToken * pToken = (ISpObjectToken *)::SendMessage(hwnd, MsgGetItemData, i, 0);
|
||||
if (pToken)
|
||||
{
|
||||
pToken->Release();
|
||||
}
|
||||
::SendMessage(hwnd, MsgDeleteString, i, 0);
|
||||
::SendMessage(hwnd, MsgSetCurSel, i, 0);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
inline HRESULT SpDeleteCurSelComboBoxToken(HWND hwnd)
|
||||
{
|
||||
return SpDeleteCurSelToken(CB_GETCURSEL, CB_SETCURSEL, CB_GETITEMDATA, CB_DELETESTRING, hwnd);
|
||||
}
|
||||
|
||||
inline HRESULT SpDeleteCurSelListBoxToken(HWND hwnd)
|
||||
{
|
||||
return SpDeleteCurSelToken(LB_GETCURSEL, CB_SETCURSEL, LB_GETITEMDATA, LB_DELETESTRING, hwnd);
|
||||
}
|
||||
|
||||
#endif /* #ifndef SPUIHelp_h -- This must be the last line in the file */
|
BIN
speech2/third_party/sapi5/lib/i386/sapi.lib
vendored
Normal file
BIN
speech2/third_party/sapi5/lib/i386/sapi.lib
vendored
Normal file
Binary file not shown.
Loading…
Reference in a new issue