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
|
# ccls/clangd
|
||||||
## files generated by popular Visual Studio add-ons.
|
.cache/
|
||||||
##
|
**/bin/
|
||||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
**/obj/
|
||||||
|
|
||||||
# User-specific files
|
# on your own machine, please.
|
||||||
*.rsuser
|
/speech2/compile_commands.json
|
||||||
*.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
|
|
||||||
|
|
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
|
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
|
## Running
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -27,4 +35,4 @@ Content-Type: application/json
|
||||||
{"text":"Lorem ipsum doler sit amet...","voice":"Microsoft Sam"}
|
{"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 Sdk="Microsoft.NET.Sdk">
|
||||||
<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>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<!-- Older VS generated one for us; we're just using that one.
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
Unless we wanna use the generated one?? -->
|
||||||
<ProjectGuid>{BF824074-4C4E-4DE1-8DCA-F022682B00E1}</ProjectGuid>
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<RootNamespace>SAPIServer</RootNamespace>
|
<TargetFrameworks>net40</TargetFrameworks>
|
||||||
<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>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<ItemGroup>
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<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" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Speech" />
|
<Reference Include="System.Speech" />
|
||||||
|
@ -62,23 +19,5 @@
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<Compile Include="HTTPServer.cs" />
|
</Project>
|
||||||
<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>
|
|
||||||
|
|
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