whisper-api-server/pkg/whisper/MediaFoundation.go
2023-10-04 01:09:38 +03:00

223 lines
5.2 KiB
Go

package whisper
import (
"errors"
"fmt"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
// https://github.com/Const-me/Whisper/blob/843a2a6ca6ea47c5ac4889a281badfc808d0ea01/Whisper/API/IMediaFoundation.h
type IMediaFoundation struct {
lpVtbl *IMediaFoundationVtbl
}
type IMediaFoundationVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
loadAudioFile uintptr // ( LPCTSTR path, bool stereo, iAudioBuffer** pp ) const;
openAudioFile uintptr // ( LPCTSTR path, bool stereo, iAudioReader** pp );
loadAudioFileData uintptr // ( const void* data, uint64_t size, bool stereo, iAudioReader** pp ); HRESULT
listCaptureDevices uintptr // ( pfnFoundCaptureDevices pfn, void* pv );
openCaptureDevice uintptr // ( LPCTSTR endpoint, const sCaptureParams& captureParams, iAudioCapture** pp );
}
func (this *IMediaFoundation) AddRef() int32 {
ret, _, _ := syscall.Syscall(
this.lpVtbl.AddRef,
1,
uintptr(unsafe.Pointer(this)),
0,
0)
return int32(ret)
}
func (this *IMediaFoundation) Release() int32 {
ret, _, _ := syscall.Syscall(
this.lpVtbl.Release,
1,
uintptr(unsafe.Pointer(this)),
0,
0)
return int32(ret)
}
// ( LPCTSTR path, bool stereo, iAudioBuffer** pp ) const;
func (this *IMediaFoundation) LoadAudioFile(file string, stereo bool) (*iAudioBuffer, error) {
var buffer *iAudioBuffer
UTFFileName, _ := windows.UTF16PtrFromString(file)
ret, _, _ := syscall.SyscallN(
this.lpVtbl.loadAudioFile,
uintptr(unsafe.Pointer(this)),
uintptr(unsafe.Pointer(UTFFileName)),
uintptr(1), // Todo ... Stereo !
uintptr(unsafe.Pointer(&buffer)))
if windows.Handle(ret) != windows.S_OK {
fmt.Printf("loadAudioFile failed: %s\n", syscall.Errno(ret).Error())
return nil, syscall.Errno(ret)
}
return buffer, nil
}
func (this *IMediaFoundation) OpenAudioFile(file string, stereo bool) (*iAudioReader, error) {
var buffer *iAudioReader
UTFFileName, _ := windows.UTF16PtrFromString(file)
ret, _, _ := syscall.SyscallN(
this.lpVtbl.openAudioFile,
uintptr(unsafe.Pointer(this)),
uintptr(unsafe.Pointer(UTFFileName)),
uintptr(1), // Todo ... Stereo !
uintptr(unsafe.Pointer(&buffer)))
if windows.Handle(ret) != windows.S_OK {
fmt.Printf("openAudioFile failed: %s\n", syscall.Errno(ret).Error())
return nil, syscall.Errno(ret)
}
return buffer, nil
}
func (this *IMediaFoundation) LoadAudioFileData(inbuffer *[]byte, stereo bool) (*iAudioReader, error) {
var reader *iAudioReader
// loadAudioFileData( const void* data, uint64_t size, bool stereo, iAudioReader** pp );
ret, _, _ := syscall.SyscallN(
this.lpVtbl.loadAudioFileData,
uintptr(unsafe.Pointer(this)),
uintptr(unsafe.Pointer(&(*inbuffer)[0])),
uintptr(uint64(len(*inbuffer))),
uintptr(1), // Todo ... Stereo !
uintptr(unsafe.Pointer(&reader)))
if windows.Handle(ret) != windows.S_OK {
fmt.Printf("LoadAudioFileData failed: %s\n", syscall.Errno(ret).Error())
return nil, syscall.Errno(ret)
}
return reader, nil
}
// ************************************************************
type iAudioBuffer struct {
lpVtbl *iAudioBufferVtbl
}
type iAudioBufferVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
countSamples uintptr // returns uint32_t
getPcmMono uintptr // returns float*
getPcmStereo uintptr // returns float*
getTime uintptr // ( int64_t& rdi )
}
func (this *iAudioBuffer) AddRef() int32 {
ret, _, _ := syscall.SyscallN(
this.lpVtbl.AddRef,
uintptr(unsafe.Pointer(this)),
)
return int32(ret)
}
func (this *iAudioBuffer) Release() int32 {
ret, _, _ := syscall.SyscallN(
this.lpVtbl.Release,
uintptr(unsafe.Pointer(this)),
)
return int32(ret)
}
func (this *iAudioBuffer) CountSamples() (uint32, error) {
ret, _, err := syscall.SyscallN(
this.lpVtbl.countSamples,
uintptr(unsafe.Pointer(this)),
)
if err != 0 {
return 0, errors.New(err.Error())
}
return uint32(ret), nil
}
// ************************************************************
type iAudioReader struct {
lpVtbl *iAudioReaderVtbl
}
type iAudioReaderVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
getDuration uintptr // ( int64_t& rdi )
getReader uintptr // ( IMFSourceReader** pp )
requestedStereo uintptr // ()
}
func (this *iAudioReader) AddRef() int32 {
ret, _, _ := syscall.SyscallN(
this.lpVtbl.AddRef,
uintptr(unsafe.Pointer(this)),
)
return int32(ret)
}
func (this *iAudioReader) Release() int32 {
ret, _, _ := syscall.SyscallN(
this.lpVtbl.Release,
uintptr(unsafe.Pointer(this)),
)
return int32(ret)
}
func (this *iAudioReader) GetDuration() (uint64, error) {
var rdi int64
ret, _, _ := syscall.SyscallN(
this.lpVtbl.getDuration,
uintptr(unsafe.Pointer(this)),
uintptr(unsafe.Pointer(&rdi)),
)
if windows.Handle(ret) != windows.S_OK {
fmt.Printf("LoadAudioFileData failed: %s\n", syscall.Errno(ret).Error())
return 0, syscall.Errno(ret)
}
return uint64(rdi), nil
}
// ************************************************************
type iAudioCapture struct {
lpVtbl *iAudioCaptureVtbl
}
type iAudioCaptureVtbl struct {
QueryInterface uintptr
AddRef uintptr
Release uintptr
getReader uintptr // ( IMFSourceReader** pp )
getParams uintptr // returns sCaptureParams&
}