120 lines
2.6 KiB
Go
120 lines
2.6 KiB
Go
|
package whisper
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"syscall"
|
||
|
"unsafe"
|
||
|
|
||
|
"golang.org/x/sys/windows"
|
||
|
)
|
||
|
|
||
|
// External - Go version of the struct
|
||
|
type Model struct {
|
||
|
cStruct *_IModel
|
||
|
setup *sModelSetup
|
||
|
}
|
||
|
|
||
|
// Internal - C Version of the structs
|
||
|
type _IModel struct {
|
||
|
lpVtbl *IModelVtbl
|
||
|
}
|
||
|
|
||
|
// https://github.com/Const-me/Whisper/blob/master/Whisper/API/iContext.cl.h
|
||
|
type IModelVtbl struct {
|
||
|
QueryInterface uintptr
|
||
|
AddRef uintptr
|
||
|
Release uintptr
|
||
|
|
||
|
createContext uintptr //( iContext** pp ) = 0;
|
||
|
tokenize uintptr /* HRESULT __stdcall tokenize( const char* text, pfnDecodedTokens pfn, void* pv ); */
|
||
|
isMultilingual uintptr //() = 0;
|
||
|
getSpecialTokens uintptr //( SpecialTokens& rdi ) = 0;
|
||
|
stringFromToken uintptr //( whisper_token token ) = 0;
|
||
|
clone uintptr //( iModel** rdi ) = 0;
|
||
|
}
|
||
|
|
||
|
func NewModel(setup *sModelSetup, cstruct *_IModel) *Model {
|
||
|
this := Model{}
|
||
|
this.setup = setup
|
||
|
this.cStruct = cstruct
|
||
|
return &this
|
||
|
}
|
||
|
|
||
|
func (this *Model) AddRef() int32 {
|
||
|
ret, _, _ := syscall.Syscall(
|
||
|
this.cStruct.lpVtbl.AddRef,
|
||
|
1,
|
||
|
uintptr(unsafe.Pointer(this.cStruct)),
|
||
|
0,
|
||
|
0)
|
||
|
return int32(ret)
|
||
|
}
|
||
|
|
||
|
func (this *Model) Release() int32 {
|
||
|
ret, _, _ := syscall.Syscall(
|
||
|
this.cStruct.lpVtbl.Release,
|
||
|
1,
|
||
|
uintptr(unsafe.Pointer(this.cStruct)),
|
||
|
0,
|
||
|
0)
|
||
|
return int32(ret)
|
||
|
}
|
||
|
|
||
|
func (this *Model) CreateContext() (*IContext, error) {
|
||
|
var context *IContext
|
||
|
|
||
|
/*
|
||
|
ret, _, err := syscall.Syscall(
|
||
|
this.cStruct.lpVtbl.createContext,
|
||
|
2, // Why was this 1, rather than 2 ?? 1 seemed to work fine
|
||
|
uintptr(unsafe.Pointer(this.cStruct)),
|
||
|
uintptr(unsafe.Pointer(&context)),
|
||
|
0)*/
|
||
|
ret, _, err := syscall.SyscallN(
|
||
|
this.cStruct.lpVtbl.createContext,
|
||
|
uintptr(unsafe.Pointer(this.cStruct)),
|
||
|
uintptr(unsafe.Pointer(&context)))
|
||
|
|
||
|
if windows.Handle(ret) != windows.S_OK {
|
||
|
fmt.Printf("createContext failed: %w", err.Error())
|
||
|
}
|
||
|
|
||
|
if windows.Handle(ret) != windows.S_OK {
|
||
|
return nil, fmt.Errorf("loadModel failed: %w", err)
|
||
|
}
|
||
|
|
||
|
return context, nil
|
||
|
}
|
||
|
|
||
|
func (this *Model) IsMultilingual() bool {
|
||
|
ret, _, _ := syscall.SyscallN(
|
||
|
this.cStruct.lpVtbl.isMultilingual,
|
||
|
uintptr(unsafe.Pointer(this.cStruct)),
|
||
|
)
|
||
|
|
||
|
return bool(windows.Handle(ret) == windows.S_OK)
|
||
|
}
|
||
|
|
||
|
func (this *Model) Clone() (*_IModel, error) {
|
||
|
|
||
|
if this.setup.isFlagSet(gmf_Cloneable) {
|
||
|
return nil, errors.New("Model is not cloneable")
|
||
|
}
|
||
|
//this.Cloneable ?
|
||
|
|
||
|
var modelptr *_IModel
|
||
|
|
||
|
ret, _, _ := syscall.SyscallN(
|
||
|
this.cStruct.lpVtbl.clone,
|
||
|
uintptr(unsafe.Pointer(this.cStruct)),
|
||
|
uintptr(unsafe.Pointer(&modelptr)),
|
||
|
)
|
||
|
|
||
|
if windows.Handle(ret) == windows.S_OK {
|
||
|
return modelptr, nil
|
||
|
} else {
|
||
|
return nil, errors.New("Model.Clone() failed : " + syscall.Errno(ret).Error())
|
||
|
}
|
||
|
}
|