more binding fuckery
i'm going to switch the build to clang-cl. To test, I've added EXE build support back to the speech2 C++ buildsystem and I'm going to replace the current mingw command lines for clang-cl in the next commit. Because we only need XP SP3 compatibility, we won't need any compat library stuff, but I may still alter his libc++ fork if MSVC CRT ends up blowing too many chunks.
This commit is contained in:
parent
126566c3cf
commit
d95d305734
7 changed files with 78 additions and 36 deletions
2
Justfile
2
Justfile
|
@ -1,6 +1,6 @@
|
||||||
build:
|
build:
|
||||||
dotnet build -c Release
|
dotnet build -c Release
|
||||||
make -C speech2 -j$(nproc)
|
make -C speech2 CONFIG=Release -j$(nproc)
|
||||||
|
|
||||||
cp speech2/bin/x86/Release/speech2.dll SAPIServer/bin/Release/net40/windows-x86
|
cp speech2/bin/x86/Release/speech2.dll SAPIServer/bin/Release/net40/windows-x86
|
||||||
cp /usr/i686-w64-mingw32/bin/libgcc_s_dw2-1.dll SAPIServer/bin/Release/net40/windows-x86/
|
cp /usr/i686-w64-mingw32/bin/libgcc_s_dw2-1.dll SAPIServer/bin/Release/net40/windows-x86/
|
||||||
|
|
|
@ -36,16 +36,18 @@ namespace SAPIServer {
|
||||||
|
|
||||||
// Speech2 DLL API. Sync with c++ code.
|
// Speech2 DLL API. Sync with c++ code.
|
||||||
internal class SpeechDLL {
|
internal class SpeechDLL {
|
||||||
[DllImport("speech2.dll")]
|
private const string Speech2DLL = "speech2.dll";
|
||||||
|
|
||||||
|
[DllImport(Speech2DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern IntPtr speech2_create_api(EngineType type);
|
public static extern IntPtr speech2_create_api(EngineType type);
|
||||||
|
|
||||||
[DllImport("speech2.dll")]
|
[DllImport(Speech2DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void speech2_destroy_api(IntPtr pAPI);
|
public static extern void speech2_destroy_api(IntPtr pAPI);
|
||||||
|
|
||||||
[DllImport("speech2.dll")]
|
[DllImport(Speech2DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern int speech2_api_get_voiceinfo_count(IntPtr pAPI);
|
public static extern int speech2_api_get_voiceinfo_count(IntPtr pAPI);
|
||||||
|
|
||||||
[DllImport("speech2.dll")]
|
[DllImport(Speech2DLL, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern IntPtr speech2_api_get_voiceinfo_index(IntPtr pAPI, int index);
|
public static extern IntPtr speech2_api_get_voiceinfo_index(IntPtr pAPI, int index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,35 +2,26 @@ include build/arch.mk
|
||||||
include build/configs.mk
|
include build/configs.mk
|
||||||
|
|
||||||
NAME = speech2
|
NAME = speech2
|
||||||
|
TYPE = dll
|
||||||
BINDIR = bin/$(ARCH)/$(CONFIG)
|
|
||||||
OBJDIR = obj/$(ARCH)/$(CONFIG)
|
|
||||||
|
|
||||||
# Any C++ file in src/ is automatically picked up.
|
# Any C++ file in src/ is automatically picked up.
|
||||||
CXXSRCS = $(wildcard src/*.cpp) $(wildcard src/*/*.cpp)
|
CXXSRCS = $(wildcard src/*.cpp) $(wildcard src/*/*.cpp)
|
||||||
VPATH = $(dir $(CXXSRCS))
|
|
||||||
OBJS = $(addprefix $(OBJDIR)/,$(notdir $(CXXSRCS:.cpp=.o)))
|
|
||||||
|
|
||||||
.PHONY: all dumpinfo clean matrix
|
.PHONY: all clean matrix
|
||||||
|
|
||||||
all: $(BINDIR)/$(NAME).dll
|
|
||||||
|
|
||||||
# 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
|
include build/rules.mk
|
||||||
|
|
||||||
|
all: $(BUILD_PRODUCT)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
echo -e "\e[91mCleaning... \e[0m"
|
echo -e "\e[91mCleaning... \e[0m"
|
||||||
rm -rf $(BINDIR)/ $(OBJS)
|
rm -rf $(BINDIR)/ $(OBJS)
|
||||||
|
|
||||||
|
# A fun make trick. This allows for verbose compilation if desired.
|
||||||
|
# Set V=1 or anything, and it'll be verbose.
|
||||||
$V.SILENT:
|
$V.SILENT:
|
||||||
|
|
||||||
# Include dependency files.
|
# Include dependency files generated by compilation.
|
||||||
|
# `make clean` keeps them so we can reuse, however they can
|
||||||
|
# still optionally be blown away.
|
||||||
-include $(OBJS:.o=.d)
|
-include $(OBJS:.o=.d)
|
||||||
|
|
|
@ -1,11 +1,21 @@
|
||||||
# Base compiler flags. Only change if you *explicitly* know what you're doing.
|
# Base compiler flags. Only change if you *explicitly* know what you're doing.
|
||||||
BASE_CCFLAGS = -MMD -fvisibility=hidden -std=gnu17 -fpermissive -fno-pic -fno-pie -fno-ident -msse -Iinclude -Isrc -D_UCRT -D_WIN32_WINNT=0x0501
|
|
||||||
BASE_CXXFLAGS = -MMD -fvisibility=hidden -std=c++20 -fpermissive -fno-pic -fno-pie -fno-ident -msse -Iinclude -Isrc -Ithird_party -D_UCRT -D_WIN32_WINNT=0x0501
|
#ifeq ($(VCDIR),)
|
||||||
BASE_LDFLAGS = -Wl,--subsystem=windows -fvisibility=hidden -shared -lkernel32 -lshell32 -luser32 -luuid -lole32
|
#$(error Please set VCDIR in your environment to )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
# _UCRT define forces mingw not to define its stupid wrappers.
|
||||||
|
BASE_FLAGS = -MMD -fvisibility=hidden -fpermissive -fno-pic -fno-pie -fno-ident -msse -Iinclude -Isrc -Ithird_party -D_UCRT -D_WIN32_WINNT=0x0501
|
||||||
|
|
||||||
|
BASE_CCFLAGS = $(BASE_FLAGS) -std=gnu17
|
||||||
|
BASE_CXXFLAGS = $(BASE_FLAGS) -std=c++20
|
||||||
|
BASE_LDFLAGS_SHARED = -Wl,--subsystem=windows -fvisibility=hidden -shared
|
||||||
|
BASE_LDFLAGS = -lkernel32 -lshell32 -luser32 -luuid -lole32
|
||||||
|
|
||||||
Release_Valid = yes
|
Release_Valid = yes
|
||||||
Release_CCFLAGS = -O3 -ffast-math -fomit-frame-pointer -DNDEBUG
|
Release_CCFLAGS = -O3 -DNDEBUG
|
||||||
Release_CXXFLAGS = -O3 -ffast-math -fomit-frame-pointer -DNDEBUG
|
Release_CXXFLAGS = -O3 -DNDEBUG
|
||||||
Release_LDFLAGS = -s
|
Release_LDFLAGS = -s
|
||||||
|
|
||||||
Debug_Valid = yes
|
Debug_Valid = yes
|
||||||
|
@ -21,3 +31,7 @@ endif
|
||||||
ifneq ($($(CONFIG)_Valid),yes)
|
ifneq ($($(CONFIG)_Valid),yes)
|
||||||
$(error Please select a valid configuration)
|
$(error Please select a valid configuration)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# define the directories used for output products here.
|
||||||
|
BINDIR = bin/$(ARCH)/$(CONFIG)
|
||||||
|
OBJDIR = obj/$(ARCH)/$(CONFIG)
|
||||||
|
|
|
@ -1,6 +1,24 @@
|
||||||
|
|
||||||
|
# TODO: Handle C sources and deduplicate.
|
||||||
|
VPATH = $(dir $(CXXSRCS))
|
||||||
|
OBJS = $(addprefix $(OBJDIR)/,$(notdir $(CXXSRCS:.cpp=.o)))
|
||||||
|
|
||||||
|
# Build types
|
||||||
|
ifeq ($(TYPE),dll)
|
||||||
|
BUILD_PRODUCT = $(BINDIR)/$(NAME).dll
|
||||||
|
|
||||||
$(BINDIR)/$(NAME).dll: $(BINDIR)/ $(OBJDIR)/ $(OBJS)
|
$(BINDIR)/$(NAME).dll: $(BINDIR)/ $(OBJDIR)/ $(OBJS)
|
||||||
echo -e "\e[92mLinking binary $@\e[0m"
|
echo -e "\e[92mLinking DLL $@\e[0m"
|
||||||
$(CXX) $(OBJS) $(BASE_LDFLAGS) $($(CONFIG)_LDFLAGS) -o $@
|
$(CXX) $(OBJS) $(BASE_LDFLAGS_SHARED) $(BASE_LDFLAGS) $($(CONFIG)_LDFLAGS) -o $@
|
||||||
|
else
|
||||||
|
ifeq ($(TYPE),exe)
|
||||||
|
BUILD_PRODUCT = $(BINDIR)/$(NAME).exe
|
||||||
|
|
||||||
|
$(BINDIR)/$(NAME).exe: $(BINDIR)/ $(OBJDIR)/ $(OBJS)
|
||||||
|
echo -e "\e[92mLinking EXE $@\e[0m"
|
||||||
|
$(CXX) $(OBJS) $(BASE_LDFLAGS_SHARED) $(BASE_LDFLAGS) $($(CONFIG)_LDFLAGS) -o $@
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
$(OBJDIR)/%.o: %.c
|
||||||
echo -e "\e[94mCompiling C source file $< ($@)\e[0m"
|
echo -e "\e[94mCompiling C source file $< ($@)\e[0m"
|
||||||
|
@ -17,3 +35,12 @@ $(OBJDIR)/%.o: %.S
|
||||||
$(OBJDIR)/%.o: %.rc
|
$(OBJDIR)/%.o: %.rc
|
||||||
echo -e "\e[94mCompiling Windows resource script $<\e[0m"
|
echo -e "\e[94mCompiling Windows resource script $<\e[0m"
|
||||||
$(WINDRES) -Iinclude $< -o $@
|
$(WINDRES) -Iinclude $< -o $@
|
||||||
|
|
||||||
|
# dir rules
|
||||||
|
$(BINDIR)/:
|
||||||
|
echo -e "\e[95mMKDIR $@\e[0m"
|
||||||
|
mkdir -p $(BINDIR)
|
||||||
|
|
||||||
|
$(OBJDIR)/:
|
||||||
|
echo -e "\e[95mMKDIR $@\e[0m"
|
||||||
|
mkdir -p $(OBJDIR)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include "speechapi.hpp"
|
#include "speechapi.hpp"
|
||||||
|
|
||||||
#define SP2_EXPORT __declspec(dllexport)
|
#define SP2_EXPORT __declspec(dllexport) __cdecl
|
||||||
|
|
||||||
// Engine type. Sync with C#
|
// Engine type. Sync with C#
|
||||||
enum class EngineType : int { ET_SAPI4, ET_SAPI5, ET_DECTALK };
|
enum class EngineType : int { ET_SAPI4, ET_SAPI5, ET_DECTALK };
|
||||||
|
@ -10,6 +10,9 @@ extern "C" {
|
||||||
|
|
||||||
SP2_EXPORT void* speech2_create_api(EngineType type) {
|
SP2_EXPORT void* speech2_create_api(EngineType type) {
|
||||||
ISpeechAPI* api = nullptr;
|
ISpeechAPI* api = nullptr;
|
||||||
|
|
||||||
|
printf("speech2_create_api(%d)\n", type);
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case EngineType::ET_SAPI4:
|
case EngineType::ET_SAPI4:
|
||||||
api = ISpeechAPI::CreateSapi4();
|
api = ISpeechAPI::CreateSapi4();
|
||||||
|
|
|
@ -19,7 +19,7 @@ struct SpeechAPI_SAPI4 : public ISpeechAPI {
|
||||||
HRESULT Initialize() override {
|
HRESULT Initialize() override {
|
||||||
HRESULT hRes;
|
HRESULT hRes;
|
||||||
|
|
||||||
printf("speech2: SpeechAPI_Sapi4::Initalize() begin\n");
|
printf("speech2: SpeechAPI_Sapi4::Initalize() begin: %p\n", this);
|
||||||
|
|
||||||
hRes = pEnum.CreateInstance(CLSID_TTSEnumerator, CLSCTX_INPROC);
|
hRes = pEnum.CreateInstance(CLSID_TTSEnumerator, CLSCTX_INPROC);
|
||||||
if(FAILED(hRes))
|
if(FAILED(hRes))
|
||||||
|
@ -34,18 +34,23 @@ struct SpeechAPI_SAPI4 : public ISpeechAPI {
|
||||||
EnumVoices();
|
EnumVoices();
|
||||||
|
|
||||||
|
|
||||||
printf("speech2: SpeechAPI_Sapi4::Initalize() filled out voices! Yay\n");
|
printf("speech2: SpeechAPI_Sapi4::Initalize() end\n");
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnumVoices() {
|
void EnumVoices() {
|
||||||
static TTSMODEINFO found {};
|
TTSMODEINFO found{};
|
||||||
|
DWORD piss = 0;
|
||||||
|
|
||||||
while(!pEnum->Next(1, &found, nullptr)) {
|
|
||||||
|
|
||||||
|
while(!pEnum->Next(1, &found, &piss)) {
|
||||||
//auto ptr = strdup(found.szModeName);
|
//auto ptr = strdup(found.szModeName);
|
||||||
printf("EnumVoices() voice %p\n", &found.szModeName);
|
printf("EnumVoices() voice %s\n", found.szModeName);
|
||||||
//voices.push_back(VoiceInfo { .guid = found.gModeID, .voiceName = ptr });
|
//voices.push_back(VoiceInfo { .guid = found.gModeID, .voiceName = ptr });
|
||||||
|
|
||||||
|
ZeroMemory(&found, sizeof(TTSMODEINFO));
|
||||||
}
|
}
|
||||||
|
|
||||||
pEnum->Reset();
|
pEnum->Reset();
|
||||||
|
|
Loading…
Reference in a new issue