Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
4e5e6ea90a | |||
d5d32ed86d | |||
c4f5affecd | |||
7855fd04a2 | |||
493b799954 | |||
cfbaf18f66 | |||
d2905c03eb | |||
d10eb1305d | |||
70fc7c26a0 |
291
AMBuildScript
291
AMBuildScript
@ -12,7 +12,7 @@ class SDK(object):
|
||||
self.define = name
|
||||
self.platform = platform
|
||||
self.name = dir
|
||||
self.path = None
|
||||
self.path = None # Actual path
|
||||
|
||||
WinOnly = ['windows']
|
||||
WinLinux = ['windows', 'linux']
|
||||
@ -111,140 +111,169 @@ class ExtensionConfig(object):
|
||||
cxx = builder.DetectCompilers()
|
||||
|
||||
if cxx.like('gcc'):
|
||||
cxx.defines += [
|
||||
'stricmp=strcasecmp',
|
||||
'_stricmp=strcasecmp',
|
||||
'_snprintf=snprintf',
|
||||
'_vsnprintf=vsnprintf',
|
||||
'HAVE_STDINT_H',
|
||||
'GNUC',
|
||||
]
|
||||
cxx.cflags += [
|
||||
'-pipe',
|
||||
'-fno-strict-aliasing',
|
||||
'-Wall',
|
||||
# '-Werror',
|
||||
'-Wno-unused',
|
||||
'-Wno-switch',
|
||||
'-Wno-array-bounds',
|
||||
'-msse',
|
||||
'-m32',
|
||||
]
|
||||
cxx.cxxflags += [
|
||||
'-std=c++11',
|
||||
]
|
||||
|
||||
have_gcc = cxx.vendor == 'gcc'
|
||||
have_clang = cxx.vendor == 'clang'
|
||||
if have_clang or (have_gcc and cxx.version >= '4'):
|
||||
cxx.cflags += ['-fvisibility=hidden']
|
||||
cxx.cxxflags += ['-fvisibility-inlines-hidden']
|
||||
if have_clang or (have_gcc and cxx.version >= '4.6'):
|
||||
cxx.cflags += ['-Wno-narrowing']
|
||||
if (have_gcc and cxx.version >= '4.7') or (have_clang and cxx.version >= '3'):
|
||||
cxx.cxxflags += ['-Wno-delete-non-virtual-dtor']
|
||||
if have_gcc and cxx.version >= '4.8':
|
||||
cxx.cflags += ['-Wno-unused-result']
|
||||
if have_clang:
|
||||
cxx.cxxflags += ['-Wno-implicit-exception-spec-mismatch']
|
||||
if cxx.version >= 'apple-clang-5.1' or cxx.version >= 'clang-3.4':
|
||||
cxx.cxxflags += ['-Wno-deprecated-register']
|
||||
else:
|
||||
cxx.cxxflags += ['-Wno-deprecated']
|
||||
cxx.cflags += ['-Wno-sometimes-uninitialized']
|
||||
|
||||
cxx.linkflags += ['-m32']
|
||||
cxx.cxxflags += [
|
||||
'-fno-exceptions',
|
||||
'-fno-threadsafe-statics',
|
||||
'-Wno-non-virtual-dtor',
|
||||
'-Wno-overloaded-virtual',
|
||||
]
|
||||
|
||||
if have_gcc:
|
||||
cxx.cflags += ['-mfpmath=sse']
|
||||
self.configure_gcc(cxx)
|
||||
elif cxx.vendor == 'msvc':
|
||||
if builder.options.debug == '1':
|
||||
cxx.cflags += ['/MTd']
|
||||
cxx.linkflags += ['/NODEFAULTLIB:libcmt']
|
||||
else:
|
||||
cxx.cflags += ['/MT']
|
||||
cxx.defines += [
|
||||
'_CRT_SECURE_NO_DEPRECATE',
|
||||
'_CRT_SECURE_NO_WARNINGS',
|
||||
'_CRT_NONSTDC_NO_DEPRECATE',
|
||||
'_ITERATOR_DEBUG_LEVEL=0',
|
||||
]
|
||||
cxx.cflags += [
|
||||
'/W3',
|
||||
]
|
||||
cxx.cxxflags += [
|
||||
'/EHsc',
|
||||
'/GR-',
|
||||
'/TP',
|
||||
]
|
||||
cxx.linkflags += [
|
||||
'/MACHINE:X86',
|
||||
'kernel32.lib',
|
||||
'user32.lib',
|
||||
'gdi32.lib',
|
||||
'winspool.lib',
|
||||
'comdlg32.lib',
|
||||
'advapi32.lib',
|
||||
'shell32.lib',
|
||||
'ole32.lib',
|
||||
'oleaut32.lib',
|
||||
'uuid.lib',
|
||||
'odbc32.lib',
|
||||
'odbccp32.lib',
|
||||
]
|
||||
self.configure_msvc(cxx)
|
||||
|
||||
# Optimization
|
||||
# Optimizaiton
|
||||
if builder.options.opt == '1':
|
||||
cxx.defines += ['NDEBUG']
|
||||
if cxx.like('gcc'):
|
||||
cxx.cflags += ['-O3']
|
||||
elif cxx.like('msvc'):
|
||||
cxx.cflags += ['/Ox', '/Zo']
|
||||
cxx.linkflags += ['/OPT:ICF', '/OPT:REF']
|
||||
|
||||
# Debugging
|
||||
if builder.options.debug == '1':
|
||||
cxx.defines += ['DEBUG', '_DEBUG']
|
||||
if cxx.like('msvc'):
|
||||
cxx.cflags += ['/Od', '/RTC1']
|
||||
|
||||
# This needs to be after our optimization flags which could otherwise disable it.
|
||||
if cxx.vendor == 'msvc':
|
||||
# Don't omit the frame pointer.
|
||||
cxx.cflags += ['/Oy-']
|
||||
|
||||
# Platform-specifics
|
||||
if builder.target_platform == 'linux':
|
||||
cxx.defines += ['_LINUX', 'POSIX']
|
||||
cxx.linkflags += ['-lm']
|
||||
if cxx.vendor == 'gcc':
|
||||
cxx.linkflags += ['-static-libgcc']
|
||||
elif cxx.vendor == 'clang':
|
||||
cxx.linkflags += ['-lgcc_eh']
|
||||
self.configure_linux(cxx)
|
||||
elif builder.target_platform == 'mac':
|
||||
cxx.defines += ['OSX', '_OSX', 'POSIX']
|
||||
cxx.cflags += ['-mmacosx-version-min=10.5']
|
||||
cxx.linkflags += [
|
||||
'-mmacosx-version-min=10.5',
|
||||
'-arch', 'i386',
|
||||
'-lstdc++',
|
||||
'-stdlib=libstdc++',
|
||||
]
|
||||
cxx.cxxflags += ['-stdlib=libstdc++']
|
||||
self.configure_mac(cxx)
|
||||
elif builder.target_platform == 'windows':
|
||||
cxx.defines += ['WIN32', '_WINDOWS']
|
||||
self.configure_windows(cxx)
|
||||
|
||||
# Finish up.
|
||||
cxx.includes += [
|
||||
os.path.join(self.sm_root, 'public'),
|
||||
]
|
||||
|
||||
|
||||
def configure_gcc(self, cxx):
|
||||
cxx.defines += [
|
||||
'stricmp=strcasecmp',
|
||||
'_stricmp=strcasecmp',
|
||||
'_snprintf=snprintf',
|
||||
'_vsnprintf=vsnprintf',
|
||||
'HAVE_STDINT_H',
|
||||
'GNUC',
|
||||
]
|
||||
cxx.cflags += [
|
||||
'-pipe',
|
||||
'-fno-strict-aliasing',
|
||||
'-Wall',
|
||||
# '-Werror',
|
||||
'-Wno-unused',
|
||||
'-Wno-switch',
|
||||
'-Wno-array-bounds',
|
||||
'-msse',
|
||||
'-m32',
|
||||
'-fvisibility=hidden',
|
||||
]
|
||||
cxx.cxxflags += [
|
||||
'-std=c++14',
|
||||
'-fno-exceptions',
|
||||
'-fno-threadsafe-statics',
|
||||
'-Wno-non-virtual-dtor',
|
||||
'-Wno-overloaded-virtual',
|
||||
'-fvisibility-inlines-hidden',
|
||||
]
|
||||
cxx.linkflags += ['-m32']
|
||||
|
||||
have_gcc = cxx.vendor == 'gcc'
|
||||
have_clang = cxx.vendor == 'clang'
|
||||
if cxx.version >= 'clang-3.6':
|
||||
cxx.cxxflags += ['-Wno-inconsistent-missing-override']
|
||||
if have_clang or (cxx.version >= 'gcc-4.6'):
|
||||
cxx.cflags += ['-Wno-narrowing']
|
||||
if have_clang or (cxx.version >= 'gcc-4.7'):
|
||||
cxx.cxxflags += ['-Wno-delete-non-virtual-dtor']
|
||||
if cxx.version >= 'gcc-4.8':
|
||||
cxx.cflags += ['-Wno-unused-result']
|
||||
|
||||
if have_clang:
|
||||
cxx.cxxflags += ['-Wno-implicit-exception-spec-mismatch']
|
||||
if cxx.version >= 'apple-clang-5.1' or cxx.version >= 'clang-3.4':
|
||||
cxx.cxxflags += ['-Wno-deprecated-register']
|
||||
else:
|
||||
cxx.cxxflags += ['-Wno-deprecated']
|
||||
cxx.cflags += ['-Wno-sometimes-uninitialized']
|
||||
|
||||
if have_gcc:
|
||||
cxx.cflags += ['-mfpmath=sse']
|
||||
|
||||
if builder.options.opt == '1':
|
||||
cxx.cflags += ['-O3']
|
||||
|
||||
def configure_msvc(self, cxx):
|
||||
if builder.options.debug == '1':
|
||||
cxx.cflags += ['/MTd']
|
||||
cxx.linkflags += ['/NODEFAULTLIB:libcmt']
|
||||
else:
|
||||
cxx.cflags += ['/MT']
|
||||
cxx.defines += [
|
||||
'_CRT_SECURE_NO_DEPRECATE',
|
||||
'_CRT_SECURE_NO_WARNINGS',
|
||||
'_CRT_NONSTDC_NO_DEPRECATE',
|
||||
'_ITERATOR_DEBUG_LEVEL=0',
|
||||
]
|
||||
cxx.cflags += [
|
||||
'/W3',
|
||||
]
|
||||
cxx.cxxflags += [
|
||||
'/EHsc',
|
||||
'/GR-',
|
||||
'/TP',
|
||||
]
|
||||
cxx.linkflags += [
|
||||
'/MACHINE:X86',
|
||||
'kernel32.lib',
|
||||
'user32.lib',
|
||||
'gdi32.lib',
|
||||
'winspool.lib',
|
||||
'comdlg32.lib',
|
||||
'advapi32.lib',
|
||||
'shell32.lib',
|
||||
'ole32.lib',
|
||||
'oleaut32.lib',
|
||||
'uuid.lib',
|
||||
'odbc32.lib',
|
||||
'odbccp32.lib',
|
||||
]
|
||||
|
||||
if builder.options.opt == '1':
|
||||
cxx.cflags += ['/Ox', '/Zo']
|
||||
cxx.linkflags += ['/OPT:ICF', '/OPT:REF']
|
||||
|
||||
if builder.options.debug == '1':
|
||||
cxx.cflags += ['/Od', '/RTC1']
|
||||
|
||||
# This needs to be after our optimization flags which could otherwise disable it.
|
||||
# Don't omit the frame pointer.
|
||||
cxx.cflags += ['/Oy-']
|
||||
|
||||
def configure_linux(self, cxx):
|
||||
cxx.defines += ['_LINUX', 'POSIX']
|
||||
cxx.linkflags += ['-Wl,--exclude-libs,ALL', '-lm']
|
||||
if cxx.vendor == 'gcc':
|
||||
cxx.linkflags += ['-static-libgcc']
|
||||
elif cxx.vendor == 'clang':
|
||||
cxx.linkflags += ['-lgcc_eh']
|
||||
cxx.linkflags += ['-static-libstdc++']
|
||||
|
||||
def configure_mac(self, cxx):
|
||||
cxx.defines += ['OSX', '_OSX', 'POSIX']
|
||||
cxx.cflags += ['-mmacosx-version-min=10.5']
|
||||
cxx.linkflags += [
|
||||
'-mmacosx-version-min=10.5',
|
||||
'-arch', 'i386',
|
||||
'-lstdc++',
|
||||
'-stdlib=libstdc++',
|
||||
]
|
||||
cxx.cxxflags += ['-stdlib=libstdc++']
|
||||
|
||||
def configure_windows(self, cxx):
|
||||
cxx.defines += ['WIN32', '_WINDOWS']
|
||||
|
||||
def ConfigureForExtension(self, context, compiler):
|
||||
compiler.cxxincludes += [
|
||||
os.path.join(context.currentSourcePath),
|
||||
os.path.join(context.currentSourcePath, 'sdk'),
|
||||
os.path.join(self.sm_root, 'public'),
|
||||
os.path.join(self.sm_root, 'public', 'extensions'),
|
||||
os.path.join(self.sm_root, 'sourcepawn', 'include'),
|
||||
os.path.join(self.sm_root, 'public', 'amtl', 'amtl'),
|
||||
os.path.join(self.sm_root, 'public', 'amtl'),
|
||||
]
|
||||
return compiler
|
||||
|
||||
def ConfigureForHL2(self, binary, sdk):
|
||||
compiler = binary.compiler
|
||||
|
||||
@ -294,10 +323,10 @@ class ExtensionConfig(object):
|
||||
|
||||
# For everything after Swarm, this needs to be defined for entity networking
|
||||
# to work properly with sendprop value changes.
|
||||
if sdk.name in ['blade', 'insurgency', 'csgo', 'dota']:
|
||||
if sdk.name in ['blade', 'insurgency', 'doi', 'csgo']:
|
||||
compiler.defines += ['NETWORK_VARS_ENABLED']
|
||||
|
||||
if sdk.name in ['css', 'hl2dm', 'dods', 'sdk2013', 'bms', 'tf2', 'l4d', 'nucleardawn', 'l4d2', 'dota']:
|
||||
if sdk.name in ['css', 'hl2dm', 'dods', 'sdk2013', 'bms', 'tf2', 'l4d', 'nucleardawn', 'l4d2']:
|
||||
if builder.target_platform in ['linux', 'mac']:
|
||||
compiler.defines += ['NO_HOOK_MALLOC', 'NO_MALLOC_OVERRIDE']
|
||||
|
||||
@ -332,14 +361,14 @@ class ExtensionConfig(object):
|
||||
compiler.Dep(os.path.join(lib_folder, 'mathlib_i486.a'))
|
||||
]
|
||||
|
||||
if sdk.name in ['blade', 'insurgency', 'csgo', 'dota']:
|
||||
if sdk.name in ['blade', 'insurgency', 'doi', 'csgo']:
|
||||
compiler.postlink += [compiler.Dep(os.path.join(lib_folder, 'interfaces_i486.a'))]
|
||||
|
||||
dynamic_libs = []
|
||||
if builder.target_platform == 'linux':
|
||||
if sdk.name in ['css', 'hl2dm', 'dods', 'tf2', 'sdk2013', 'bms', 'nucleardawn', 'l4d2']:
|
||||
if sdk.name in ['css', 'hl2dm', 'dods', 'tf2', 'sdk2013', 'bms', 'nucleardawn', 'l4d2', 'insurgency', 'doi']:
|
||||
dynamic_libs = ['libtier0_srv.so', 'libvstdlib_srv.so']
|
||||
elif sdk.name in ['l4d', 'blade', 'insurgency', 'csgo', 'dota']:
|
||||
elif sdk.name in ['l4d', 'blade', 'insurgency', 'doi', 'csgo']:
|
||||
dynamic_libs = ['libtier0.so', 'libvstdlib.so']
|
||||
else:
|
||||
dynamic_libs = ['tier0_i486.so', 'vstdlib_i486.so']
|
||||
@ -348,7 +377,7 @@ class ExtensionConfig(object):
|
||||
dynamic_libs = ['libtier0.dylib', 'libvstdlib.dylib']
|
||||
elif builder.target_platform == 'windows':
|
||||
libs = ['tier0', 'tier1', 'vstdlib', 'mathlib']
|
||||
if sdk.name in ['swarm', 'blade', 'insurgency', 'csgo', 'dota']:
|
||||
if sdk.name in ['swarm', 'blade', 'insurgency', 'doi', 'csgo']:
|
||||
libs.append('interfaces')
|
||||
for lib in libs:
|
||||
lib_path = os.path.join(sdk.path, 'lib', 'public', lib) + '.lib'
|
||||
@ -369,22 +398,16 @@ class ExtensionConfig(object):
|
||||
|
||||
return binary
|
||||
|
||||
def ConfigureForExtension(self, context, compiler):
|
||||
compiler.cxxincludes += [
|
||||
os.path.join(context.currentSourcePath),
|
||||
os.path.join(context.currentSourcePath, 'sdk'),
|
||||
os.path.join(self.sm_root, 'public'),
|
||||
os.path.join(self.sm_root, 'public', 'extensions'),
|
||||
os.path.join(self.sm_root, 'sourcepawn', 'include'),
|
||||
os.path.join(self.sm_root, 'public', 'amtl', 'include'),
|
||||
]
|
||||
return compiler
|
||||
def HL2Library(self, context, name, sdk):
|
||||
binary = context.compiler.Library(name)
|
||||
self.ConfigureForExtension(context, binary.compiler)
|
||||
return self.ConfigureForHL2(binary, sdk)
|
||||
|
||||
def HL2Project(self, context, name):
|
||||
project = context.compiler.LibraryProject(name)
|
||||
self.ConfigureForExtension(context, project.compiler)
|
||||
return project
|
||||
|
||||
|
||||
def HL2Config(self, project, name, sdk):
|
||||
binary = project.Configure(name, '{0} - {1}'.format(self.tag, sdk.name))
|
||||
return self.ConfigureForHL2(binary, sdk)
|
||||
|
15
AMBuilder
15
AMBuilder
@ -10,18 +10,25 @@ project = SM.HL2Project(builder, projectName + '.ext')
|
||||
project.sources += [
|
||||
'extension.cpp',
|
||||
'ringbuffer.cpp',
|
||||
'../../public/smsdk_ext.cpp'
|
||||
'../../public/smsdk_ext.cpp',
|
||||
'../../public/CDetour/detours.cpp',
|
||||
'../../public/asm/asm.c',
|
||||
'../../public/libudis86/decode.c',
|
||||
'../../public/libudis86/itab.c',
|
||||
'../../public/libudis86/syn-att.c',
|
||||
'../../public/libudis86/syn-intel.c',
|
||||
'../../public/libudis86/syn.c',
|
||||
'../../public/libudis86/udis86.c',
|
||||
]
|
||||
|
||||
for sdk_name in SM.sdks:
|
||||
sdk = SM.sdks[sdk_name]
|
||||
binary = SM.HL2Config(project, projectName + '.ext', sdk)
|
||||
binary.compiler.cxxincludes += [
|
||||
os.path.join(SM.sm_root, 'public', 'extensions'),
|
||||
os.path.join(builder.sourcePath, 'silk')
|
||||
os.path.join(builder.sourcePath, 'celt')
|
||||
]
|
||||
binary.compiler.linkflags += [
|
||||
os.path.join(builder.sourcePath, 'silk', 'libSKP_SILK_SDK.a')
|
||||
os.path.join(builder.sourcePath, 'celt', 'libcelt0.a')
|
||||
]
|
||||
|
||||
SM.extensions += builder.Add(project)
|
||||
|
325
celt/celt.h
Normal file
325
celt/celt.h
Normal file
@ -0,0 +1,325 @@
|
||||
/* Copyright (c) 2007-2008 CSIRO
|
||||
Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||
Copyright (c) 2008 Gregory Maxwell
|
||||
Written by Jean-Marc Valin and Gregory Maxwell */
|
||||
/**
|
||||
@file celt.h
|
||||
@brief Contains all the functions for encoding and decoding audio
|
||||
*/
|
||||
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CELT_H
|
||||
#define CELT_H
|
||||
|
||||
#include "celt_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && defined(CELT_BUILD)
|
||||
#define EXPORT __attribute__ ((visibility ("default")))
|
||||
#elif defined(WIN32)
|
||||
#define EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define EXPORT
|
||||
#endif
|
||||
|
||||
#define _celt_check_int(x) (((void)((x) == (celt_int32)0)), (celt_int32)(x))
|
||||
#define _celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr)))
|
||||
#define _celt_check_int_ptr(ptr) ((ptr) + ((ptr) - (int*)(ptr)))
|
||||
|
||||
/* Error codes */
|
||||
/** No error */
|
||||
#define CELT_OK 0
|
||||
/** An (or more) invalid argument (e.g. out of range) */
|
||||
#define CELT_BAD_ARG -1
|
||||
/** The mode struct passed is invalid */
|
||||
#define CELT_BUFFER_TOO_SMALL -2
|
||||
/** An internal error was detected */
|
||||
#define CELT_INTERNAL_ERROR -3
|
||||
/** The data passed (e.g. compressed data to decoder) is corrupted */
|
||||
#define CELT_CORRUPTED_DATA -4
|
||||
/** Invalid/unsupported request number */
|
||||
#define CELT_UNIMPLEMENTED -5
|
||||
/** An encoder or decoder structure is invalid or already freed */
|
||||
#define CELT_INVALID_STATE -6
|
||||
/** Memory allocation has failed */
|
||||
#define CELT_ALLOC_FAIL -7
|
||||
|
||||
|
||||
/* Encoder/decoder Requests */
|
||||
|
||||
#define CELT_SET_COMPLEXITY_REQUEST 2
|
||||
/** Controls the complexity from 0-10 (int) */
|
||||
#define CELT_SET_COMPLEXITY(x) CELT_SET_COMPLEXITY_REQUEST, _celt_check_int(x)
|
||||
|
||||
#define CELT_SET_PREDICTION_REQUEST 4
|
||||
/** Controls the use of interframe prediction.
|
||||
0=Independent frames
|
||||
1=Short term interframe prediction allowed
|
||||
2=Long term prediction allowed
|
||||
*/
|
||||
#define CELT_SET_PREDICTION(x) CELT_SET_PREDICTION_REQUEST, _celt_check_int(x)
|
||||
|
||||
#define CELT_SET_BITRATE_REQUEST 6
|
||||
/** Set the target VBR rate in bits per second(int); 0=CBR (default) */
|
||||
#define CELT_SET_BITRATE(x) CELT_SET_BITRATE_REQUEST, _celt_check_int(x)
|
||||
|
||||
#define CELT_RESET_STATE_REQUEST 8
|
||||
/** Reset the encoder/decoder memories to zero*/
|
||||
#define CELT_RESET_STATE CELT_RESET_STATE_REQUEST
|
||||
|
||||
#define CELT_SET_VBR_CONSTRAINT_REQUEST 10
|
||||
#define CELT_SET_VBR_CONSTRAINT(x) CELT_SET_VBR_CONSTRAINT_REQUEST, _celt_check_int(x)
|
||||
|
||||
#define CELT_SET_VBR_REQUEST 12
|
||||
#define CELT_SET_VBR(x) CELT_SET_VBR_REQUEST, _celt_check_int(x)
|
||||
|
||||
#define CELT_SET_INPUT_CLIPPING_REQUEST 14
|
||||
#define CELT_SET_INPUT_CLIPPING(x) CELT_SET_INPUT_CLIPPING_REQUEST, _celt_check_int(x)
|
||||
|
||||
#define CELT_GET_AND_CLEAR_ERROR_REQUEST 15
|
||||
#define CELT_GET_AND_CLEAR_ERROR(x) CELT_GET_AND_CLEAR_ERROR_REQUEST, _celt_check_int_ptr(x)
|
||||
|
||||
#define CELT_GET_LOOKAHEAD_REQUEST 17
|
||||
#define CELT_GET_LOOKAHEAD(x) CELT_GET_LOOKAHEAD_REQUEST, _celt_check_int_ptr(x)
|
||||
|
||||
#define CELT_SET_CHANNELS_REQUEST 18
|
||||
#define CELT_SET_CHANNELS(x) CELT_SET_CHANNELS_REQUEST, _celt_check_int(x)
|
||||
|
||||
#define CELT_SET_LOSS_PERC_REQUEST 20
|
||||
#define CELT_SET_LOSS_PERC(x) CELT_SET_LOSS_PERC_REQUEST, _celt_check_int(x)
|
||||
|
||||
/* Internal */
|
||||
#define CELT_SET_START_BAND_REQUEST 10000
|
||||
#define CELT_SET_START_BAND(x) CELT_SET_START_BAND_REQUEST, _celt_check_int(x)
|
||||
|
||||
#define CELT_SET_END_BAND_REQUEST 10001
|
||||
#define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, _celt_check_int(x)
|
||||
|
||||
|
||||
|
||||
/** Contains the state of an encoder. One encoder state is needed
|
||||
for each stream. It is initialised once at the beginning of the
|
||||
stream. Do *not* re-initialise the state for every frame.
|
||||
@brief Encoder state
|
||||
*/
|
||||
typedef struct CELTEncoder CELTEncoder;
|
||||
|
||||
/** State of the decoder. One decoder state is needed for each stream.
|
||||
It is initialised once at the beginning of the stream. Do *not*
|
||||
re-initialise the state for every frame */
|
||||
typedef struct CELTDecoder CELTDecoder;
|
||||
|
||||
/** The mode contains all the information necessary to create an
|
||||
encoder. Both the encoder and decoder need to be initialised
|
||||
with exactly the same mode, otherwise the quality will be very
|
||||
bad */
|
||||
typedef struct CELTMode CELTMode;
|
||||
|
||||
|
||||
/** \defgroup codec Encoding and decoding */
|
||||
/* @{ */
|
||||
|
||||
/* Mode calls */
|
||||
|
||||
/** Creates a new mode struct. This will be passed to an encoder or
|
||||
decoder. The mode MUST NOT BE DESTROYED until the encoders and
|
||||
decoders that use it are destroyed as well.
|
||||
@param Fs Sampling rate (32000 to 96000 Hz)
|
||||
@param frame_size Number of samples (per channel) to encode in each
|
||||
packet (even values; 64 - 512)
|
||||
@param error Returned error code (if NULL, no error will be returned)
|
||||
@return A newly created mode
|
||||
*/
|
||||
EXPORT CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error);
|
||||
|
||||
/** Destroys a mode struct. Only call this after all encoders and
|
||||
decoders using this mode are destroyed as well.
|
||||
@param mode Mode to be destroyed
|
||||
*/
|
||||
EXPORT void celt_mode_destroy(CELTMode *mode);
|
||||
|
||||
/* Encoder stuff */
|
||||
|
||||
EXPORT int celt_encoder_get_size(int channels);
|
||||
|
||||
EXPORT int celt_encoder_get_size_custom(const CELTMode *mode, int channels);
|
||||
|
||||
/** Creates a new encoder state. Each stream needs its own encoder
|
||||
state (can't be shared across simultaneous streams).
|
||||
@param channels Number of channels
|
||||
@param error Returns an error code
|
||||
@return Newly created encoder state.
|
||||
*/
|
||||
EXPORT CELTEncoder *celt_encoder_create(int sampling_rate, int channels, int *error);
|
||||
|
||||
/** Creates a new encoder state. Each stream needs its own encoder
|
||||
state (can't be shared across simultaneous streams).
|
||||
@param mode Contains all the information about the characteristics of
|
||||
* the stream (must be the same characteristics as used for the
|
||||
* decoder)
|
||||
@param channels Number of channels
|
||||
@param error Returns an error code
|
||||
@return Newly created encoder state.
|
||||
*/
|
||||
EXPORT CELTEncoder *celt_encoder_create_custom(const CELTMode *mode, int channels, int *error);
|
||||
|
||||
EXPORT CELTEncoder *celt_encoder_init(CELTEncoder *st, int sampling_rate, int channels, int *error);
|
||||
|
||||
EXPORT CELTEncoder *celt_encoder_init_custom(CELTEncoder *st, const CELTMode *mode, int channels, int *error);
|
||||
|
||||
/** Destroys a an encoder state.
|
||||
@param st Encoder state to be destroyed
|
||||
*/
|
||||
EXPORT void celt_encoder_destroy(CELTEncoder *st);
|
||||
|
||||
/** Encodes a frame of audio.
|
||||
@param st Encoder state
|
||||
@param pcm PCM audio in float format, with a normal range of ±1.0.
|
||||
* Samples with a range beyond ±1.0 are supported but will
|
||||
* be clipped by decoders using the integer API and should
|
||||
* only be used if it is known that the far end supports
|
||||
* extended dynmaic range. There must be exactly
|
||||
* frame_size samples per channel.
|
||||
@param compressed The compressed data is written here. This may not alias pcm or
|
||||
* optional_synthesis.
|
||||
@param nbCompressedBytes Maximum number of bytes to use for compressing the frame
|
||||
* (can change from one frame to another)
|
||||
@return Number of bytes written to "compressed". Will be the same as
|
||||
* "nbCompressedBytes" unless the stream is VBR and will never be larger.
|
||||
* If negative, an error has occurred (see error codes). It is IMPORTANT that
|
||||
* the length returned be somehow transmitted to the decoder. Otherwise, no
|
||||
* decoding is possible.
|
||||
*/
|
||||
EXPORT int celt_encode_float(CELTEncoder *st, const float *pcm, int frame_size, unsigned char *compressed, int maxCompressedBytes);
|
||||
|
||||
/** Encodes a frame of audio.
|
||||
@param st Encoder state
|
||||
@param pcm PCM audio in signed 16-bit format (native endian). There must be
|
||||
* exactly frame_size samples per channel.
|
||||
@param compressed The compressed data is written here. This may not alias pcm or
|
||||
* optional_synthesis.
|
||||
@param nbCompressedBytes Maximum number of bytes to use for compressing the frame
|
||||
* (can change from one frame to another)
|
||||
@return Number of bytes written to "compressed". Will be the same as
|
||||
* "nbCompressedBytes" unless the stream is VBR and will never be larger.
|
||||
* If negative, an error has occurred (see error codes). It is IMPORTANT that
|
||||
* the length returned be somehow transmitted to the decoder. Otherwise, no
|
||||
* decoding is possible.
|
||||
*/
|
||||
EXPORT int celt_encode(CELTEncoder *st, const celt_int16 *pcm, int frame_size, unsigned char *compressed, int maxCompressedBytes);
|
||||
|
||||
/** Query and set encoder parameters
|
||||
@param st Encoder state
|
||||
@param request Parameter to change or query
|
||||
@param value Pointer to a 32-bit int value
|
||||
@return Error code
|
||||
*/
|
||||
EXPORT int celt_encoder_ctl(CELTEncoder * st, int request, ...);
|
||||
|
||||
/* Decoder stuff */
|
||||
|
||||
EXPORT int celt_decoder_get_size(int channels);
|
||||
|
||||
EXPORT int celt_decoder_get_size_custom(const CELTMode *mode, int channels);
|
||||
|
||||
/** Creates a new decoder state. Each stream needs its own decoder state (can't
|
||||
be shared across simultaneous streams).
|
||||
@param mode Contains all the information about the characteristics of the
|
||||
stream (must be the same characteristics as used for the encoder)
|
||||
@param channels Number of channels
|
||||
@param error Returns an error code
|
||||
@return Newly created decoder state.
|
||||
*/
|
||||
EXPORT CELTDecoder *celt_decoder_create(int sampling_rate, int channels, int *error);
|
||||
|
||||
/** Creates a new decoder state. Each stream needs its own decoder state (can't
|
||||
be shared across simultaneous streams).
|
||||
@param mode Contains all the information about the characteristics of the
|
||||
stream (must be the same characteristics as used for the encoder)
|
||||
@param channels Number of channels
|
||||
@param error Returns an error code
|
||||
@return Newly created decoder state.
|
||||
*/
|
||||
EXPORT CELTDecoder *celt_decoder_create_custom(const CELTMode *mode, int channels, int *error);
|
||||
|
||||
EXPORT CELTDecoder *celt_decoder_init(CELTDecoder *st, int sampling_rate, int channels, int *error);
|
||||
|
||||
EXPORT CELTDecoder *celt_decoder_init_custom(CELTDecoder *st, const CELTMode *mode, int channels, int *error);
|
||||
|
||||
/** Destroys a a decoder state.
|
||||
@param st Decoder state to be destroyed
|
||||
*/
|
||||
EXPORT void celt_decoder_destroy(CELTDecoder *st);
|
||||
|
||||
/** Decodes a frame of audio.
|
||||
@param st Decoder state
|
||||
@param data Compressed data produced by an encoder
|
||||
@param len Number of bytes to read from "data". This MUST be exactly the number
|
||||
of bytes returned by the encoder. Using a larger value WILL NOT WORK.
|
||||
@param pcm One frame (frame_size samples per channel) of decoded PCM will be
|
||||
returned here in float format.
|
||||
@return Error code.
|
||||
*/
|
||||
EXPORT int celt_decode_float(CELTDecoder *st, const unsigned char *data, int len, float *pcm, int frame_size);
|
||||
|
||||
/** Decodes a frame of audio.
|
||||
@param st Decoder state
|
||||
@param data Compressed data produced by an encoder
|
||||
@param len Number of bytes to read from "data". This MUST be exactly the number
|
||||
of bytes returned by the encoder. Using a larger value WILL NOT WORK.
|
||||
@param pcm One frame (frame_size samples per channel) of decoded PCM will be
|
||||
returned here in 16-bit PCM format (native endian).
|
||||
@return Error code.
|
||||
*/
|
||||
EXPORT int celt_decode(CELTDecoder *st, const unsigned char *data, int len, celt_int16 *pcm, int frame_size);
|
||||
|
||||
/** Query and set decoder parameters
|
||||
@param st Decoder state
|
||||
@param request Parameter to change or query
|
||||
@param value Pointer to a 32-bit int value
|
||||
@return Error code
|
||||
*/
|
||||
EXPORT int celt_decoder_ctl(CELTDecoder * st, int request, ...);
|
||||
|
||||
|
||||
/** Returns the English string that corresponds to an error code
|
||||
* @param error Error code (negative for an error, 0 for success
|
||||
* @return Constant string (must NOT be freed)
|
||||
*/
|
||||
EXPORT const char *celt_strerror(int error);
|
||||
|
||||
/* @} */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*CELT_H */
|
66
celt/celt_header.h
Normal file
66
celt/celt_header.h
Normal file
@ -0,0 +1,66 @@
|
||||
/* Copyright (c) 2007 CSIRO
|
||||
Copyright (c) 2007-2008 Xiph.Org Foundation
|
||||
Written by Jean-Marc Valin */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef CELT_HEADER_H
|
||||
#define CELT_HEADER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "celt.h"
|
||||
#include "celt_types.h"
|
||||
|
||||
/** Header data to be used for Ogg files (or possibly other encapsulation)
|
||||
@brief Header data
|
||||
*/
|
||||
typedef struct {
|
||||
char codec_id[8]; /**< MUST be "CELT " (four spaces) */
|
||||
char codec_version[20]; /**< Version used (as string) */
|
||||
celt_int32 version_id; /**< Version id (negative for until stream is frozen) */
|
||||
celt_int32 header_size; /**< Size of this header */
|
||||
celt_int32 sample_rate; /**< Sampling rate of the original audio */
|
||||
celt_int32 nb_channels; /**< Number of channels */
|
||||
celt_int32 frame_size; /**< Samples per frame (per channel) */
|
||||
celt_int32 overlap; /**< Overlapping samples (per channel) */
|
||||
celt_int32 bytes_per_packet; /**< Number of bytes per compressed packet (0 if unknown) */
|
||||
celt_int32 extra_headers; /**< Number of additional headers that follow this header */
|
||||
} CELTHeader;
|
||||
|
||||
/** Creates a basic header struct */
|
||||
EXPORT int celt_header_init(CELTHeader *header, const CELTMode *m, int frame_size, int channels);
|
||||
|
||||
EXPORT int celt_header_to_packet(const CELTHeader *header, unsigned char *packet, celt_uint32 size);
|
||||
|
||||
EXPORT int celt_header_from_packet(const unsigned char *packet, celt_uint32 size, CELTHeader *header);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CELT_HEADER_H */
|
151
celt/celt_types.h
Normal file
151
celt/celt_types.h
Normal file
@ -0,0 +1,151 @@
|
||||
/* (C) COPYRIGHT 1994-2002 Xiph.Org Foundation */
|
||||
/* Modified by Jean-Marc Valin */
|
||||
/*
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/* celt_types.h taken from libogg */
|
||||
|
||||
/**
|
||||
@file celt_types.h
|
||||
@brief CELT types
|
||||
*/
|
||||
#ifndef _CELT_TYPES_H
|
||||
#define _CELT_TYPES_H
|
||||
|
||||
/* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */
|
||||
#if (defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H))
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int16_t celt_int16;
|
||||
typedef uint16_t celt_uint16;
|
||||
typedef int32_t celt_int32;
|
||||
typedef uint32_t celt_uint32;
|
||||
#elif defined(_WIN32)
|
||||
|
||||
# if defined(__CYGWIN__)
|
||||
# include <_G_config.h>
|
||||
typedef _G_int32_t celt_int32;
|
||||
typedef _G_uint32_t celt_uint32;
|
||||
typedef _G_int16 celt_int16;
|
||||
typedef _G_uint16 celt_uint16;
|
||||
# elif defined(__MINGW32__)
|
||||
typedef short celt_int16;
|
||||
typedef unsigned short celt_uint16;
|
||||
typedef int celt_int32;
|
||||
typedef unsigned int celt_uint32;
|
||||
# elif defined(__MWERKS__)
|
||||
typedef int celt_int32;
|
||||
typedef unsigned int celt_uint32;
|
||||
typedef short celt_int16;
|
||||
typedef unsigned short celt_uint16;
|
||||
# else
|
||||
/* MSVC/Borland */
|
||||
typedef __int32 celt_int32;
|
||||
typedef unsigned __int32 celt_uint32;
|
||||
typedef __int16 celt_int16;
|
||||
typedef unsigned __int16 celt_uint16;
|
||||
# endif
|
||||
|
||||
#elif defined(__MACOS__)
|
||||
|
||||
# include <sys/types.h>
|
||||
typedef SInt16 celt_int16;
|
||||
typedef UInt16 celt_uint16;
|
||||
typedef SInt32 celt_int32;
|
||||
typedef UInt32 celt_uint32;
|
||||
|
||||
#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */
|
||||
|
||||
# include <sys/types.h>
|
||||
typedef int16_t celt_int16;
|
||||
typedef u_int16_t celt_uint16;
|
||||
typedef int32_t celt_int32;
|
||||
typedef u_int32_t celt_uint32;
|
||||
|
||||
#elif defined(__BEOS__)
|
||||
|
||||
/* Be */
|
||||
# include <inttypes.h>
|
||||
typedef int16 celt_int16;
|
||||
typedef u_int16 celt_uint16;
|
||||
typedef int32_t celt_int32;
|
||||
typedef u_int32_t celt_uint32;
|
||||
|
||||
#elif defined (__EMX__)
|
||||
|
||||
/* OS/2 GCC */
|
||||
typedef short celt_int16;
|
||||
typedef unsigned short celt_uint16;
|
||||
typedef int celt_int32;
|
||||
typedef unsigned int celt_uint32;
|
||||
|
||||
#elif defined (DJGPP)
|
||||
|
||||
/* DJGPP */
|
||||
typedef short celt_int16;
|
||||
typedef unsigned short celt_uint16;
|
||||
typedef int celt_int32;
|
||||
typedef unsigned int celt_uint32;
|
||||
|
||||
#elif defined(R5900)
|
||||
|
||||
/* PS2 EE */
|
||||
typedef int celt_int32;
|
||||
typedef unsigned celt_uint32;
|
||||
typedef short celt_int16;
|
||||
typedef unsigned short celt_uint16;
|
||||
|
||||
#elif defined(__SYMBIAN32__)
|
||||
|
||||
/* Symbian GCC */
|
||||
typedef signed short celt_int16;
|
||||
typedef unsigned short celt_uint16;
|
||||
typedef signed int celt_int32;
|
||||
typedef unsigned int celt_uint32;
|
||||
|
||||
#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X)
|
||||
|
||||
typedef short celt_int16;
|
||||
typedef unsigned short celt_uint16;
|
||||
typedef long celt_int32;
|
||||
typedef unsigned long celt_uint32;
|
||||
|
||||
#elif defined(CONFIG_TI_C6X)
|
||||
|
||||
typedef short celt_int16;
|
||||
typedef unsigned short celt_uint16;
|
||||
typedef int celt_int32;
|
||||
typedef unsigned int celt_uint32;
|
||||
|
||||
#else
|
||||
|
||||
/* Give up, take a reasonable guess */
|
||||
typedef short celt_int16;
|
||||
typedef unsigned short celt_uint16;
|
||||
typedef int celt_int32;
|
||||
typedef unsigned int celt_uint32;
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _CELT_TYPES_H */
|
BIN
celt/libcelt0.a
Normal file
BIN
celt/libcelt0.a
Normal file
Binary file not shown.
496
extension.cpp
496
extension.cpp
@ -43,8 +43,17 @@
|
||||
#include <iserver.h>
|
||||
#include <ISDKTools.h>
|
||||
|
||||
#include "CDetour/detours.h"
|
||||
#include "extension.h"
|
||||
|
||||
// voice packets are sent over unreliable netchannel
|
||||
//#define NET_MAX_DATAGRAM_PAYLOAD 4000 // = maximum unreliable payload size
|
||||
// voice packetsize = 64 | netchannel overflows at >4000 bytes
|
||||
// with 22050 samplerate and 512 frames per packet -> 23.22ms per packet
|
||||
// SVC_VoiceData overhead = 5 bytes
|
||||
// sensible limit of 8 packets per frame = 552 bytes -> 185.76ms of voice data per frame
|
||||
#define NET_MAX_VOICE_BYTES_FRAME (8 * (5 + 64))
|
||||
|
||||
ConVar g_SmVoiceAddr("sm_voice_addr", "127.0.0.1", FCVAR_PROTECTED, "Voice server listen ip address.");
|
||||
ConVar g_SmVoicePort("sm_voice_port", "27020", FCVAR_PROTECTED, "Voice server listen port.", true, 1025.0, true, 65535.0);
|
||||
|
||||
@ -55,74 +64,40 @@ ConVar g_SmVoicePort("sm_voice_port", "27020", FCVAR_PROTECTED, "Voice server li
|
||||
|
||||
template <typename T> inline T min(T a, T b) { return a<b?a:b; }
|
||||
|
||||
/**
|
||||
* Polynomial: 0x04C11DB7
|
||||
*/
|
||||
const unsigned int CRCTable[256] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
|
||||
|
||||
unsigned int UTIL_CRC32(const void *pdata, size_t data_length)
|
||||
{
|
||||
unsigned char *data = (unsigned char *)pdata;
|
||||
unsigned int crc = 0xFFFFFFFF;
|
||||
unsigned char c;
|
||||
|
||||
for(size_t i = 0; i < data_length; i++, data++)
|
||||
{
|
||||
c = (unsigned char)((crc ^ *data) & 0xFF);
|
||||
crc = CRCTable[c] ^ (crc >> 8);
|
||||
}
|
||||
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
CVoice g_Interface;
|
||||
SMEXT_LINK(&g_Interface);
|
||||
|
||||
CGlobalVars *gpGlobals = NULL;
|
||||
ISDKTools *g_pSDKTools = NULL;
|
||||
SH_DECL_MANUALHOOK0(GetPlayerSlot, 0, 0, 0, int); // IClient::GetPlayerSlot
|
||||
IServer *iserver = NULL;
|
||||
|
||||
double g_fLastVoiceData[SM_MAXPLAYERS + 1];
|
||||
int g_aFrameVoiceBytes[SM_MAXPLAYERS + 1];
|
||||
|
||||
DETOUR_DECL_STATIC4(SV_BroadcastVoiceData, void, IClient *, pClient, int, nBytes, char *, data, int64, xuid)
|
||||
{
|
||||
if(g_Interface.OnBroadcastVoiceData(pClient, nBytes, data))
|
||||
DETOUR_STATIC_CALL(SV_BroadcastVoiceData)(pClient, nBytes, data, xuid);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
DETOUR_DECL_STATIC2(SV_BroadcastVoiceData_LTCG, void, char *, data, int64, xuid)
|
||||
{
|
||||
IClient *pClient = NULL;
|
||||
int nBytes = 0;
|
||||
|
||||
__asm mov pClient, ecx;
|
||||
__asm mov nBytes, edx;
|
||||
|
||||
bool ret = g_Interface.OnBroadcastVoiceData(pClient, nBytes, data);
|
||||
|
||||
__asm mov ecx, pClient;
|
||||
__asm mov edx, nBytes;
|
||||
|
||||
if(ret)
|
||||
DETOUR_STATIC_CALL(SV_BroadcastVoiceData_LTCG)(data, xuid);
|
||||
}
|
||||
#endif
|
||||
|
||||
double getTime()
|
||||
{
|
||||
@ -151,8 +126,10 @@ CVoice::CVoice()
|
||||
|
||||
m_AvailableTime = 0.0;
|
||||
|
||||
m_Silk_EncoderState = NULL;
|
||||
m_pMode = NULL;
|
||||
m_pCodec = NULL;
|
||||
|
||||
m_VoiceDetour = NULL;
|
||||
m_SV_BroadcastVoiceData = NULL;
|
||||
}
|
||||
|
||||
@ -175,47 +152,39 @@ bool CVoice::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
}
|
||||
|
||||
int engineVersion = g_SMAPI->GetSourceEngineBuild();
|
||||
int offsPlayerSlot = 0;
|
||||
void *adrVoiceData = NULL;
|
||||
|
||||
switch (engineVersion)
|
||||
{
|
||||
case SOURCE_ENGINE_CSGO:
|
||||
#ifdef _WIN32
|
||||
m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\x81\xEC\xD0\x00\x00\x00\x53\x56\x57", 12);
|
||||
offsPlayerSlot = 15;
|
||||
adrVoiceData = memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\x81\xEC\xD0\x00\x00\x00\x53\x56\x57", 12);
|
||||
#else
|
||||
m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx");
|
||||
offsPlayerSlot = 16;
|
||||
adrVoiceData = memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case SOURCE_ENGINE_LEFT4DEAD2:
|
||||
#ifdef _WIN32
|
||||
m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\x83\xEC\x70\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\xFC\xA1\x2A\x2A\x2A\x2A\x53\x56", 23);
|
||||
offsPlayerSlot = 14;
|
||||
adrVoiceData = memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\x83\xEC\x70\xA1\x2A\x2A\x2A\x2A\x33\xC5\x89\x45\xFC\xA1\x2A\x2A\x2A\x2A\x53\x56", 23);
|
||||
#else
|
||||
m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx");
|
||||
offsPlayerSlot = 15;
|
||||
adrVoiceData = memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case SOURCE_ENGINE_NUCLEARDAWN:
|
||||
#ifdef _WIN32
|
||||
m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x83\xEC\x58\x57\x33\xFF", 14);
|
||||
offsPlayerSlot = 14;
|
||||
adrVoiceData = memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x83\xEC\x58\x57\x33\xFF", 14);
|
||||
#else
|
||||
m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx");
|
||||
offsPlayerSlot = 15;
|
||||
adrVoiceData = memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case SOURCE_ENGINE_INSURGENCY:
|
||||
#ifdef _WIN32
|
||||
m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\x83\xEC\x74\x68\x2A\x2A\x2A\x2A\x8D\x4D\xE4\xE8", 15);
|
||||
offsPlayerSlot = 14;
|
||||
adrVoiceData = memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\x83\xEC\x74\x68\x2A\x2A\x2A\x2A\x8D\x4D\xE4\xE8", 15);
|
||||
#else
|
||||
m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx");
|
||||
offsPlayerSlot = 15;
|
||||
adrVoiceData = memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx");
|
||||
#endif
|
||||
break;
|
||||
|
||||
@ -225,11 +194,9 @@ bool CVoice::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
case SOURCE_ENGINE_DODS:
|
||||
case SOURCE_ENGINE_SDK2013:
|
||||
#ifdef _WIN32
|
||||
m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x83\xEC\x50\x83\x78\x30", 14);
|
||||
offsPlayerSlot = 14;
|
||||
adrVoiceData = memutils->FindPattern(pEngineSo, "\x55\x8B\xEC\xA1\x2A\x2A\x2A\x2A\x83\xEC\x50\x83\x78\x30", 14);
|
||||
#else
|
||||
m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx");
|
||||
offsPlayerSlot = 15;
|
||||
adrVoiceData = memutils->ResolveSymbol(pEngineSo, "_Z21SV_BroadcastVoiceDataP7IClientiPcx");
|
||||
#endif
|
||||
break;
|
||||
|
||||
@ -240,101 +207,66 @@ bool CVoice::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
}
|
||||
dlclose(pEngineSo);
|
||||
|
||||
m_SV_BroadcastVoiceData = (t_SV_BroadcastVoiceData)adrVoiceData;
|
||||
if(!m_SV_BroadcastVoiceData)
|
||||
{
|
||||
g_SMAPI->Format(error, maxlength, "SV_BroadcastVoiceData sigscan failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
SH_MANUALHOOK_RECONFIGURE(GetPlayerSlot, offsPlayerSlot, 0, 0);
|
||||
// Setup voice detour.
|
||||
CDetourManager::Init(g_pSM->GetScriptingEngine(), NULL);
|
||||
|
||||
// Init tcp server
|
||||
m_ListenSocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(m_ListenSocket < 0)
|
||||
#ifdef _WIN32
|
||||
if (engineVersion == SOURCE_ENGINE_CSGO || engineVersion == SOURCE_ENGINE_INSURGENCY)
|
||||
{
|
||||
g_SMAPI->Format(error, maxlength, "Failed creating socket.");
|
||||
SDK_OnUnload();
|
||||
m_VoiceDetour = DETOUR_CREATE_STATIC(SV_BroadcastVoiceData_LTCG, adrVoiceData);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_VoiceDetour = DETOUR_CREATE_STATIC(SV_BroadcastVoiceData, adrVoiceData);
|
||||
}
|
||||
#else
|
||||
m_VoiceDetour = DETOUR_CREATE_STATIC(SV_BroadcastVoiceData, adrVoiceData);
|
||||
#endif
|
||||
|
||||
if (!m_VoiceDetour)
|
||||
{
|
||||
g_SMAPI->Format(error, maxlength, "SV_BroadcastVoiceData detour failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
int yes = 1;
|
||||
if(setsockopt(m_ListenSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0)
|
||||
{
|
||||
g_SMAPI->Format(error, maxlength, "Failed setting SO_REUSEADDR on socket.");
|
||||
SDK_OnUnload();
|
||||
return false;
|
||||
}
|
||||
|
||||
engine->ServerCommand("exec sourcemod/extension.Voice.cfg\n");
|
||||
engine->ServerExecute();
|
||||
|
||||
sockaddr_in bindAddr;
|
||||
memset(&bindAddr, 0, sizeof(bindAddr));
|
||||
bindAddr.sin_family = AF_INET;
|
||||
inet_aton(g_SmVoiceAddr.GetString(), &bindAddr.sin_addr);
|
||||
bindAddr.sin_port = htons(g_SmVoicePort.GetInt());
|
||||
|
||||
smutils->LogMessage(myself, "Binding to %s:%d!\n", g_SmVoiceAddr.GetString(), g_SmVoicePort.GetInt());
|
||||
|
||||
if(bind(m_ListenSocket, (sockaddr *)&bindAddr, sizeof(sockaddr_in)) < 0)
|
||||
{
|
||||
g_SMAPI->Format(error, maxlength, "Failed binding to socket (%d '%s').", errno, strerror(errno));
|
||||
SDK_OnUnload();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(listen(m_ListenSocket, MAX_CLIENTS) < 0)
|
||||
{
|
||||
g_SMAPI->Format(error, maxlength, "Failed listening on socket.");
|
||||
SDK_OnUnload();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_aPollFds[0].fd = m_ListenSocket;
|
||||
m_aPollFds[0].events = POLLIN;
|
||||
m_PollFds++;
|
||||
m_VoiceDetour->EnableDetour();
|
||||
|
||||
// Encoder settings
|
||||
m_EncoderSettings.InputSampleRate_kHz = 48; // 8, 12, 16, 24, 32, 44.1, 48
|
||||
m_EncoderSettings.OutputSampleRate_kHz = 16; // 8, 12, 16, 24
|
||||
m_EncoderSettings.TargetBitRate_Kbps = 100; // 6 - 40
|
||||
m_EncoderSettings.PacketSize_ms = 20; // 20, 40, 60, 80, 100
|
||||
m_EncoderSettings.FrameSize_ms = 20; //
|
||||
m_EncoderSettings.PacketLoss_perc = 0; // 0 - 100
|
||||
m_EncoderSettings.Complexity = 2; // 0 - 2
|
||||
m_EncoderSettings.InBandFEC = 0; // 0, 1
|
||||
m_EncoderSettings.DTX = 0; // 0, 1
|
||||
m_EncoderSettings.SampleRate_Hz = 22050;
|
||||
m_EncoderSettings.TargetBitRate_Kbps = 64;
|
||||
m_EncoderSettings.FrameSize = 512; // samples
|
||||
m_EncoderSettings.PacketSize = 64;
|
||||
m_EncoderSettings.Complexity = 10; // 0 - 10
|
||||
m_EncoderSettings.FrameTime = (double)m_EncoderSettings.FrameSize / (double)m_EncoderSettings.SampleRate_Hz;
|
||||
|
||||
// Init SILK encoder
|
||||
int encoderSize;
|
||||
SKP_Silk_SDK_Get_Encoder_Size(&encoderSize);
|
||||
|
||||
m_Silk_EncoderState = malloc(encoderSize);
|
||||
if(!m_Silk_EncoderState)
|
||||
// Init CELT encoder
|
||||
int theError;
|
||||
m_pMode = celt_mode_create(m_EncoderSettings.SampleRate_Hz, m_EncoderSettings.FrameSize, &theError);
|
||||
if(!m_pMode)
|
||||
{
|
||||
g_SMAPI->Format(error, maxlength, "Failed to malloc %d bytes for silk encoder.", encoderSize);
|
||||
g_SMAPI->Format(error, maxlength, "celt_mode_create error: %d", theError);
|
||||
SDK_OnUnload();
|
||||
return false;
|
||||
}
|
||||
|
||||
int retEnc = SKP_Silk_SDK_InitEncoder(m_Silk_EncoderState, &m_Silk_EncoderControl);
|
||||
if(retEnc != SKP_SILK_NO_ERROR)
|
||||
m_pCodec = celt_encoder_create_custom(m_pMode, 1, &theError);
|
||||
if(!m_pCodec)
|
||||
{
|
||||
g_SMAPI->Format(error, maxlength, "Silk encoder initialization failed with: %d", retEnc);
|
||||
g_SMAPI->Format(error, maxlength, "celt_encoder_create_custom error: %d", theError);
|
||||
SDK_OnUnload();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Silk_EncoderControl.API_sampleRate = m_EncoderSettings.InputSampleRate_kHz * 1000;
|
||||
m_Silk_EncoderControl.maxInternalSampleRate = m_EncoderSettings.OutputSampleRate_kHz * 1000;
|
||||
m_Silk_EncoderControl.bitRate = m_EncoderSettings.TargetBitRate_Kbps * 1000;
|
||||
m_Silk_EncoderControl.packetSize = m_EncoderSettings.PacketSize_ms * m_EncoderSettings.InputSampleRate_kHz;
|
||||
m_Silk_EncoderControl.packetLossPercentage = m_EncoderSettings.PacketLoss_perc;
|
||||
m_Silk_EncoderControl.complexity = m_EncoderSettings.Complexity;
|
||||
m_Silk_EncoderControl.useInBandFEC = m_EncoderSettings.InBandFEC;
|
||||
m_Silk_EncoderControl.useDTX = m_EncoderSettings.DTX;
|
||||
|
||||
smutils->AddGameFrameHook(::OnGameFrame);
|
||||
celt_encoder_ctl(m_pCodec, CELT_RESET_STATE_REQUEST, NULL);
|
||||
celt_encoder_ctl(m_pCodec, CELT_SET_BITRATE(m_EncoderSettings.TargetBitRate_Kbps * 1000));
|
||||
celt_encoder_ctl(m_pCodec, CELT_SET_COMPLEXITY(m_EncoderSettings.Complexity));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -342,6 +274,7 @@ bool CVoice::SDK_OnLoad(char *error, size_t maxlength, bool late)
|
||||
bool CVoice::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool late)
|
||||
{
|
||||
GET_V_IFACE_CURRENT(GetEngineFactory, g_pCVar, ICvar, CVAR_INTERFACE_VERSION);
|
||||
gpGlobals = ismm->GetCGlobals();
|
||||
ConVar_Register(0, this);
|
||||
|
||||
return true;
|
||||
@ -353,17 +286,128 @@ bool CVoice::RegisterConCommandBase(ConCommandBase *pVar)
|
||||
return META_REGCVAR(pVar);
|
||||
}
|
||||
|
||||
cell_t IsClientTalking(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
int client = params[1];
|
||||
|
||||
if(client < 1 || client > SM_MAXPLAYERS)
|
||||
{
|
||||
return pContext->ThrowNativeError("Client index %d is invalid", client);
|
||||
}
|
||||
|
||||
double d = gpGlobals->curtime - g_fLastVoiceData[client];
|
||||
|
||||
if(d < 0) // mapchange
|
||||
return false;
|
||||
|
||||
if(d > 0.33)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const sp_nativeinfo_t MyNatives[] =
|
||||
{
|
||||
{ "IsClientTalking", IsClientTalking },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static void ListenSocketAction(void *pData)
|
||||
{
|
||||
CVoice *pThis = (CVoice *)pData;
|
||||
pThis->ListenSocket();
|
||||
}
|
||||
|
||||
void CVoice::SDK_OnAllLoaded()
|
||||
{
|
||||
sharesys->AddNatives(myself, MyNatives);
|
||||
sharesys->RegisterLibrary(myself, "Voice");
|
||||
|
||||
SM_GET_LATE_IFACE(SDKTOOLS, g_pSDKTools);
|
||||
if(g_pSDKTools == NULL)
|
||||
{
|
||||
smutils->LogError(myself, "SDKTools interface not found");
|
||||
SDK_OnUnload();
|
||||
return;
|
||||
}
|
||||
|
||||
iserver = g_pSDKTools->GetIServer();
|
||||
if(iserver == NULL)
|
||||
{
|
||||
smutils->LogError(myself, "Failed to get IServer interface from SDKTools!");
|
||||
SDK_OnUnload();
|
||||
return;
|
||||
}
|
||||
|
||||
// Init tcp server
|
||||
m_ListenSocket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(m_ListenSocket < 0)
|
||||
{
|
||||
smutils->LogError(myself, "Failed creating socket.");
|
||||
SDK_OnUnload();
|
||||
return;
|
||||
}
|
||||
|
||||
int yes = 1;
|
||||
if(setsockopt(m_ListenSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0)
|
||||
{
|
||||
smutils->LogError(myself, "Failed setting SO_REUSEADDR on socket.");
|
||||
SDK_OnUnload();
|
||||
return;
|
||||
}
|
||||
|
||||
// This doesn't seem to work right away ...
|
||||
engine->ServerCommand("exec sourcemod/extension.Voice.cfg\n");
|
||||
engine->ServerExecute();
|
||||
|
||||
// ... delay starting listen server to next frame
|
||||
smutils->AddFrameAction(ListenSocketAction, this);
|
||||
}
|
||||
|
||||
void CVoice::ListenSocket()
|
||||
{
|
||||
if(m_PollFds > 0)
|
||||
return;
|
||||
|
||||
sockaddr_in bindAddr;
|
||||
memset(&bindAddr, 0, sizeof(bindAddr));
|
||||
bindAddr.sin_family = AF_INET;
|
||||
inet_aton(g_SmVoiceAddr.GetString(), &bindAddr.sin_addr);
|
||||
bindAddr.sin_port = htons(g_SmVoicePort.GetInt());
|
||||
|
||||
smutils->LogMessage(myself, "Binding to %s:%d!\n", g_SmVoiceAddr.GetString(), g_SmVoicePort.GetInt());
|
||||
|
||||
if(bind(m_ListenSocket, (sockaddr *)&bindAddr, sizeof(sockaddr_in)) < 0)
|
||||
{
|
||||
smutils->LogError(myself, "Failed binding to socket (%d '%s').", errno, strerror(errno));
|
||||
SDK_OnUnload();
|
||||
return;
|
||||
}
|
||||
|
||||
if(listen(m_ListenSocket, MAX_CLIENTS) < 0)
|
||||
{
|
||||
smutils->LogError(myself, "Failed listening on socket.");
|
||||
SDK_OnUnload();
|
||||
return;
|
||||
}
|
||||
|
||||
m_aPollFds[0].fd = m_ListenSocket;
|
||||
m_aPollFds[0].events = POLLIN;
|
||||
m_PollFds++;
|
||||
|
||||
smutils->AddGameFrameHook(::OnGameFrame);
|
||||
}
|
||||
|
||||
void CVoice::SDK_OnUnload()
|
||||
{
|
||||
smutils->RemoveGameFrameHook(::OnGameFrame);
|
||||
|
||||
if(m_VoiceDetour)
|
||||
{
|
||||
m_VoiceDetour->Destroy();
|
||||
m_VoiceDetour = NULL;
|
||||
}
|
||||
|
||||
if(m_ListenSocket != -1)
|
||||
{
|
||||
close(m_ListenSocket);
|
||||
@ -379,17 +423,40 @@ void CVoice::SDK_OnUnload()
|
||||
}
|
||||
}
|
||||
|
||||
if(m_Silk_EncoderState)
|
||||
{
|
||||
free(m_Silk_EncoderState);
|
||||
m_Silk_EncoderState = NULL;
|
||||
}
|
||||
if(m_pCodec)
|
||||
celt_encoder_destroy(m_pCodec);
|
||||
|
||||
if(m_pMode)
|
||||
celt_mode_destroy(m_pMode);
|
||||
}
|
||||
|
||||
void CVoice::OnGameFrame(bool simulating)
|
||||
{
|
||||
HandleNetwork();
|
||||
HandleVoiceData();
|
||||
|
||||
// Reset per-client voice byte counter to 0 every frame.
|
||||
memset(g_aFrameVoiceBytes, 0, sizeof(g_aFrameVoiceBytes));
|
||||
}
|
||||
|
||||
bool CVoice::OnBroadcastVoiceData(IClient *pClient, int nBytes, char *data)
|
||||
{
|
||||
// Reject empty packets
|
||||
if(nBytes < 1)
|
||||
return false;
|
||||
|
||||
int client = pClient->GetPlayerSlot() + 1;
|
||||
|
||||
// Reject voice packet if we'd send more than NET_MAX_VOICE_BYTES_FRAME voice bytes from this client in the current frame.
|
||||
// 5 = SVC_VoiceData header/overhead
|
||||
g_aFrameVoiceBytes[client] += 5 + nBytes;
|
||||
|
||||
if(g_aFrameVoiceBytes[client] > NET_MAX_VOICE_BYTES_FRAME)
|
||||
return false;
|
||||
|
||||
g_fLastVoiceData[client] = gpGlobals->curtime;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CVoice::HandleNetwork()
|
||||
@ -424,13 +491,14 @@ void CVoice::HandleNetwork()
|
||||
m_aClients[Client].m_LastLength = 0;
|
||||
m_aClients[Client].m_LastValidData = 0.0;
|
||||
m_aClients[Client].m_New = true;
|
||||
m_aClients[Client].m_UnEven = false;
|
||||
|
||||
m_aPollFds[m_PollFds].fd = Socket;
|
||||
m_aPollFds[m_PollFds].events = POLLIN | POLLHUP;
|
||||
m_aPollFds[m_PollFds].revents = 0;
|
||||
m_PollFds++;
|
||||
|
||||
smutils->LogMessage(myself, "Client %d connected!\n", Client);
|
||||
//smutils->LogMessage(myself, "Client %d connected!\n", Client);
|
||||
}
|
||||
}
|
||||
|
||||
@ -456,7 +524,7 @@ void CVoice::HandleNetwork()
|
||||
pClient->m_Socket = -1;
|
||||
m_aPollFds[PollFds].fd = -1;
|
||||
CompressPollFds = true;
|
||||
smutils->LogMessage(myself, "Client %d disconnected!(2)\n", Client);
|
||||
//smutils->LogMessage(myself, "Client %d disconnected!(2)\n", Client);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -481,7 +549,16 @@ void CVoice::HandleNetwork()
|
||||
if(min(BytesAvailable, sizeof(aBuf)) > m_Buffer.CurrentFree() * sizeof(int16_t))
|
||||
continue;
|
||||
|
||||
ssize_t Bytes = recv(pClient->m_Socket, aBuf, sizeof(aBuf), 0);
|
||||
// Edge case: previously received data is uneven and last recv'd byte has to be prepended
|
||||
int Shift = 0;
|
||||
if(pClient->m_UnEven)
|
||||
{
|
||||
Shift = 1;
|
||||
aBuf[0] = pClient->m_Remainder;
|
||||
pClient->m_UnEven = false;
|
||||
}
|
||||
|
||||
ssize_t Bytes = recv(pClient->m_Socket, &aBuf[Shift], sizeof(aBuf) - Shift, 0);
|
||||
|
||||
if(Bytes <= 0)
|
||||
{
|
||||
@ -489,10 +566,21 @@ void CVoice::HandleNetwork()
|
||||
pClient->m_Socket = -1;
|
||||
m_aPollFds[PollFds].fd = -1;
|
||||
CompressPollFds = true;
|
||||
smutils->LogMessage(myself, "Client %d disconnected!(1)\n", Client);
|
||||
//smutils->LogMessage(myself, "Client %d disconnected!(1)\n", Client);
|
||||
continue;
|
||||
}
|
||||
|
||||
Bytes += Shift;
|
||||
|
||||
// Edge case: data received is uneven (can't be divided by two)
|
||||
// store last byte, drop it here and prepend it right before the next recv
|
||||
if(Bytes & 1)
|
||||
{
|
||||
pClient->m_UnEven = true;
|
||||
pClient->m_Remainder = aBuf[Bytes - 1];
|
||||
Bytes -= 1;
|
||||
}
|
||||
|
||||
// Got data!
|
||||
OnDataReceived(pClient, (int16_t *)aBuf, Bytes / sizeof(int16_t));
|
||||
|
||||
@ -550,21 +638,12 @@ void CVoice::OnDataReceived(CClient *pClient, int16_t *pData, size_t Samples)
|
||||
pClient->m_LastValidData = getTime();
|
||||
}
|
||||
|
||||
struct SteamVoiceHeader
|
||||
{
|
||||
uint32_t iSteamAccountID : 32;
|
||||
uint32_t iSteamCommunity : 32;
|
||||
uint32_t nPayload1 : 8;
|
||||
uint32_t iSampleRate : 16;
|
||||
uint32_t nPayload2 : 8;
|
||||
uint32_t iDataLength : 16;
|
||||
};
|
||||
|
||||
void CVoice::HandleVoiceData()
|
||||
{
|
||||
int SamplesPerFrame = m_EncoderSettings.FrameSize_ms * m_EncoderSettings.InputSampleRate_kHz;
|
||||
int SamplesPerFrame = m_EncoderSettings.FrameSize;
|
||||
int PacketSize = m_EncoderSettings.PacketSize;
|
||||
int FramesAvailable = m_Buffer.TotalLength() / SamplesPerFrame;
|
||||
float TimeAvailable = (float)m_Buffer.TotalLength() / (m_EncoderSettings.InputSampleRate_kHz * 1000.0);
|
||||
float TimeAvailable = (float)m_Buffer.TotalLength() / (float)m_EncoderSettings.SampleRate_Hz;
|
||||
|
||||
if(!FramesAvailable)
|
||||
return;
|
||||
@ -581,24 +660,10 @@ void CVoice::HandleVoiceData()
|
||||
FramesAvailable = min(FramesAvailable, 5);
|
||||
|
||||
// 0 = SourceTV
|
||||
IClient *pClient = g_pSDKTools->GetIServer()->GetClient(0);
|
||||
IClient *pClient = iserver->GetClient(0);
|
||||
if(!pClient)
|
||||
return;
|
||||
|
||||
SteamVoiceHeader Header;
|
||||
size_t HeaderSize = 14;
|
||||
|
||||
Header.iSteamAccountID = 1; // Steam Account ID
|
||||
Header.iSteamCommunity = 0x01100001; // Steam Community ID part: 0x01100001 << 32
|
||||
Header.nPayload1 = 11; // nPayLoad | Type 11 = Samplerate
|
||||
Header.iSampleRate = m_EncoderSettings.OutputSampleRate_kHz * 1000; // Samplerate
|
||||
Header.nPayload2 = 4; // nPayLoad | Type 4 = Silk Frames
|
||||
Header.iDataLength = 0; // Silk Frames total length
|
||||
|
||||
// Header + Frames + CRC32
|
||||
unsigned char aFinal[HeaderSize + 8192 + sizeof(uint32_t)];
|
||||
size_t FinalSize = HeaderSize;
|
||||
|
||||
for(int Frame = 0; Frame < FramesAvailable; Frame++)
|
||||
{
|
||||
// Get data into buffer from ringbuffer.
|
||||
@ -610,29 +675,22 @@ void CVoice::HandleVoiceData()
|
||||
|
||||
if(!m_Buffer.Pop(aBuffer, SamplesPerFrame))
|
||||
{
|
||||
smutils->LogError(myself, "Buffer pop failed!!! Samples: %u, Length: %u\n", SamplesPerFrame, m_Buffer.TotalLength());
|
||||
printf("Buffer pop failed!!! Samples: %u, Length: %u\n", SamplesPerFrame, m_Buffer.TotalLength());
|
||||
return;
|
||||
}
|
||||
|
||||
// Frame Size
|
||||
int16_t *pFrameSize = (int16_t *)(&aFinal[FinalSize]);
|
||||
FinalSize += sizeof(int16_t);
|
||||
Header.iDataLength += sizeof(int16_t);
|
||||
*pFrameSize = sizeof(aFinal) - HeaderSize - sizeof(uint32_t) - FinalSize;
|
||||
|
||||
// Encode it!
|
||||
int Ret = SKP_Silk_SDK_Encode(m_Silk_EncoderState, &m_Silk_EncoderControl, aBuffer,
|
||||
SamplesPerFrame, &aFinal[FinalSize], pFrameSize);
|
||||
unsigned char aFinal[PacketSize];
|
||||
size_t FinalSize = 0;
|
||||
|
||||
if(Ret)
|
||||
FinalSize = celt_encode(m_pCodec, aBuffer, SamplesPerFrame, aFinal, sizeof(aFinal));
|
||||
|
||||
if(FinalSize <= 0)
|
||||
{
|
||||
smutils->LogError(myself, "SKP_Silk_SDK_Encode returned %d\n", Ret);
|
||||
smutils->LogError(myself, "Compress returned %d\n", FinalSize);
|
||||
return;
|
||||
}
|
||||
|
||||
FinalSize += *pFrameSize;
|
||||
Header.iDataLength += *pFrameSize;
|
||||
|
||||
// Check for buffer underruns
|
||||
for(int Client = 0; Client < MAX_CLIENTS; Client++)
|
||||
{
|
||||
@ -649,24 +707,24 @@ void CVoice::HandleVoiceData()
|
||||
pClient->m_LastLength = m_Buffer.CurrentLength();
|
||||
}
|
||||
}
|
||||
|
||||
BroadcastVoiceData(pClient, FinalSize, aFinal);
|
||||
}
|
||||
|
||||
// Header
|
||||
memcpy(aFinal, &Header, HeaderSize);
|
||||
|
||||
// CRC32
|
||||
*(uint32_t *)(&aFinal[FinalSize]) = UTIL_CRC32(aFinal, FinalSize);
|
||||
FinalSize += sizeof(uint32_t);
|
||||
|
||||
SV_BroadcastVoiceData(pClient, FinalSize, aFinal);
|
||||
|
||||
if(m_AvailableTime < getTime())
|
||||
m_AvailableTime = getTime();
|
||||
|
||||
m_AvailableTime += (double)FramesAvailable * ((double)m_EncoderSettings.FrameSize_ms / 1000.0);
|
||||
m_AvailableTime += (double)FramesAvailable * m_EncoderSettings.FrameTime;
|
||||
}
|
||||
|
||||
void CVoice::SV_BroadcastVoiceData(IClient *pClient, int nBytes, unsigned char *pData)
|
||||
void CVoice::BroadcastVoiceData(IClient *pClient, int nBytes, unsigned char *pData)
|
||||
{
|
||||
m_SV_BroadcastVoiceData(pClient, nBytes, pData, 0);
|
||||
#ifdef _WIN32
|
||||
__asm mov ecx, pClient;
|
||||
__asm mov edx, nBytes;
|
||||
|
||||
DETOUR_STATIC_CALL(SV_BroadcastVoiceData_LTCG)((char *)pData, 0);
|
||||
#else
|
||||
DETOUR_STATIC_CALL(SV_BroadcastVoiceData)(pClient, nBytes, (char *)pData, 0);
|
||||
#endif
|
||||
}
|
||||
|
31
extension.h
31
extension.h
@ -32,8 +32,9 @@
|
||||
#ifndef _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
#define _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
|
||||
#include <poll.h>
|
||||
#include "smsdk_ext.h"
|
||||
#include <SKP_Silk_SDK_API.h>
|
||||
#include "celt_header.h"
|
||||
#include "ringbuffer.h"
|
||||
|
||||
/**
|
||||
@ -49,6 +50,7 @@ typedef __int64 int64;
|
||||
typedef long long int64;
|
||||
#endif
|
||||
|
||||
class CDetour;
|
||||
class IClient;
|
||||
typedef void (*t_SV_BroadcastVoiceData)(IClient *, int, unsigned char *, int64);
|
||||
|
||||
@ -135,6 +137,9 @@ public: // IConCommandBaseAccessor
|
||||
public:
|
||||
CVoice();
|
||||
void OnGameFrame(bool simulating);
|
||||
bool OnBroadcastVoiceData(IClient *pClient, int nBytes, char *data);
|
||||
|
||||
void ListenSocket();
|
||||
|
||||
private:
|
||||
int m_ListenSocket;
|
||||
@ -146,6 +151,8 @@ private:
|
||||
size_t m_LastLength;
|
||||
double m_LastValidData;
|
||||
bool m_New;
|
||||
bool m_UnEven;
|
||||
unsigned char m_Remainder;
|
||||
} m_aClients[MAX_CLIENTS];
|
||||
|
||||
struct pollfd m_aPollFds[1 + MAX_CLIENTS];
|
||||
@ -157,26 +164,24 @@ private:
|
||||
|
||||
struct CEncoderSettings
|
||||
{
|
||||
SKP_int InputSampleRate_kHz;
|
||||
SKP_int OutputSampleRate_kHz;
|
||||
SKP_int TargetBitRate_Kbps;
|
||||
SKP_int PacketSize_ms;
|
||||
SKP_int FrameSize_ms;
|
||||
SKP_int PacketLoss_perc;
|
||||
SKP_int Complexity;
|
||||
SKP_int InBandFEC;
|
||||
SKP_int DTX;
|
||||
celt_int32 SampleRate_Hz;
|
||||
celt_int32 TargetBitRate_Kbps;
|
||||
celt_int32 FrameSize;
|
||||
celt_int32 PacketSize;
|
||||
celt_int32 Complexity;
|
||||
double FrameTime;
|
||||
} m_EncoderSettings;
|
||||
|
||||
void *m_Silk_EncoderState;
|
||||
SKP_SILK_SDK_EncControlStruct m_Silk_EncoderControl;
|
||||
CELTMode *m_pMode;
|
||||
CELTEncoder *m_pCodec;
|
||||
|
||||
t_SV_BroadcastVoiceData m_SV_BroadcastVoiceData;
|
||||
CDetour *m_VoiceDetour;
|
||||
|
||||
void HandleNetwork();
|
||||
void OnDataReceived(CClient *pClient, int16_t *pData, size_t Samples);
|
||||
void HandleVoiceData();
|
||||
void SV_BroadcastVoiceData(IClient *pClient, int nBytes, unsigned char *pData);
|
||||
void BroadcastVoiceData(IClient *pClient, int nBytes, unsigned char *pData);
|
||||
};
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
|
Binary file not shown.
@ -1,152 +0,0 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, (subject to the limitations in the disclaimer below)
|
||||
are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of Skype Limited, nor the names of specific
|
||||
contributors, may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SKP_SILK_SDK_API_H
|
||||
#define SKP_SILK_SDK_API_H
|
||||
|
||||
#include "SKP_Silk_control.h"
|
||||
#include "SKP_Silk_typedef.h"
|
||||
#include "SKP_Silk_errors.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define SILK_MAX_FRAMES_PER_PACKET 5
|
||||
|
||||
/* Struct for TOC (Table of Contents) */
|
||||
typedef struct {
|
||||
SKP_int framesInPacket; /* Number of 20 ms frames in packet */
|
||||
SKP_int fs_kHz; /* Sampling frequency in packet */
|
||||
SKP_int inbandLBRR; /* Does packet contain LBRR information */
|
||||
SKP_int corrupt; /* Packet is corrupt */
|
||||
SKP_int vadFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* VAD flag for each frame in packet */
|
||||
SKP_int sigtypeFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* Signal type for each frame in packet */
|
||||
} SKP_Silk_TOC_struct;
|
||||
|
||||
/****************************************/
|
||||
/* Encoder functions */
|
||||
/****************************************/
|
||||
|
||||
/***********************************************/
|
||||
/* Get size in bytes of the Silk encoder state */
|
||||
/***********************************************/
|
||||
SKP_int SKP_Silk_SDK_Get_Encoder_Size(
|
||||
SKP_int32 *encSizeBytes /* O: Number of bytes in SILK encoder state */
|
||||
);
|
||||
|
||||
/*************************/
|
||||
/* Init or reset encoder */
|
||||
/*************************/
|
||||
SKP_int SKP_Silk_SDK_InitEncoder(
|
||||
void *encState, /* I/O: State */
|
||||
SKP_SILK_SDK_EncControlStruct *encStatus /* O: Encoder Status */
|
||||
);
|
||||
|
||||
/***************************************/
|
||||
/* Read control structure from encoder */
|
||||
/***************************************/
|
||||
SKP_int SKP_Silk_SDK_QueryEncoder(
|
||||
const void *encState, /* I: State */
|
||||
SKP_SILK_SDK_EncControlStruct *encStatus /* O: Encoder Status */
|
||||
);
|
||||
|
||||
/**************************/
|
||||
/* Encode frame with Silk */
|
||||
/**************************/
|
||||
SKP_int SKP_Silk_SDK_Encode(
|
||||
void *encState, /* I/O: State */
|
||||
const SKP_SILK_SDK_EncControlStruct *encControl, /* I: Control status */
|
||||
const SKP_int16 *samplesIn, /* I: Speech sample input vector */
|
||||
SKP_int nSamplesIn, /* I: Number of samples in input vector */
|
||||
SKP_uint8 *outData, /* O: Encoded output vector */
|
||||
SKP_int16 *nBytesOut /* I/O: Number of bytes in outData (input: Max bytes) */
|
||||
);
|
||||
|
||||
/****************************************/
|
||||
/* Decoder functions */
|
||||
/****************************************/
|
||||
|
||||
/***********************************************/
|
||||
/* Get size in bytes of the Silk decoder state */
|
||||
/***********************************************/
|
||||
SKP_int SKP_Silk_SDK_Get_Decoder_Size(
|
||||
SKP_int32 *decSizeBytes /* O: Number of bytes in SILK decoder state */
|
||||
);
|
||||
|
||||
/*************************/
|
||||
/* Init or Reset decoder */
|
||||
/*************************/
|
||||
SKP_int SKP_Silk_SDK_InitDecoder(
|
||||
void *decState /* I/O: State */
|
||||
);
|
||||
|
||||
/******************/
|
||||
/* Decode a frame */
|
||||
/******************/
|
||||
SKP_int SKP_Silk_SDK_Decode(
|
||||
void* decState, /* I/O: State */
|
||||
SKP_SILK_SDK_DecControlStruct* decControl, /* I/O: Control Structure */
|
||||
SKP_int lostFlag, /* I: 0: no loss, 1 loss */
|
||||
const SKP_uint8 *inData, /* I: Encoded input vector */
|
||||
const SKP_int nBytesIn, /* I: Number of input bytes */
|
||||
SKP_int16 *samplesOut, /* O: Decoded output speech vector */
|
||||
SKP_int16 *nSamplesOut /* I/O: Number of samples (vector/decoded) */
|
||||
);
|
||||
|
||||
/***************************************************************/
|
||||
/* Find Low Bit Rate Redundancy (LBRR) information in a packet */
|
||||
/***************************************************************/
|
||||
void SKP_Silk_SDK_search_for_LBRR(
|
||||
const SKP_uint8 *inData, /* I: Encoded input vector */
|
||||
const SKP_int nBytesIn, /* I: Number of input Bytes */
|
||||
SKP_int lost_offset, /* I: Offset from lost packet */
|
||||
SKP_uint8 *LBRRData, /* O: LBRR payload */
|
||||
SKP_int16 *nLBRRBytes /* O: Number of LBRR Bytes */
|
||||
);
|
||||
|
||||
/**************************************/
|
||||
/* Get table of contents for a packet */
|
||||
/**************************************/
|
||||
void SKP_Silk_SDK_get_TOC(
|
||||
const SKP_uint8 *inData, /* I: Encoded input vector */
|
||||
const SKP_int nBytesIn, /* I: Number of input bytes */
|
||||
SKP_Silk_TOC_struct *Silk_TOC /* O: Table of contents */
|
||||
);
|
||||
|
||||
/**************************/
|
||||
/* Get the version number */
|
||||
/**************************/
|
||||
/* Return a pointer to string specifying the version */
|
||||
const char *SKP_Silk_SDK_get_version();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,91 +0,0 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, (subject to the limitations in the disclaimer below)
|
||||
are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of Skype Limited, nor the names of specific
|
||||
contributors, may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SKP_SILK_CONTROL_H
|
||||
#define SKP_SILK_CONTROL_H
|
||||
|
||||
#include "SKP_Silk_typedef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/***********************************************/
|
||||
/* Structure for controlling encoder operation */
|
||||
/***********************************************/
|
||||
typedef struct {
|
||||
/* I: Input signal sampling rate in Hertz; 8000/12000/16000/24000 */
|
||||
SKP_int32 API_sampleRate;
|
||||
|
||||
/* I: Maximum internal sampling rate in Hertz; 8000/12000/16000/24000 */
|
||||
SKP_int32 maxInternalSampleRate;
|
||||
|
||||
/* I: Number of samples per packet; must be equivalent of 20, 40, 60, 80 or 100 ms */
|
||||
SKP_int packetSize;
|
||||
|
||||
/* I: Bitrate during active speech in bits/second; internally limited */
|
||||
SKP_int32 bitRate;
|
||||
|
||||
/* I: Uplink packet loss in percent (0-100) */
|
||||
SKP_int packetLossPercentage;
|
||||
|
||||
/* I: Complexity mode; 0 is lowest; 1 is medium and 2 is highest complexity */
|
||||
SKP_int complexity;
|
||||
|
||||
/* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */
|
||||
SKP_int useInBandFEC;
|
||||
|
||||
/* I: Flag to enable discontinuous transmission (DTX); 0/1 */
|
||||
SKP_int useDTX;
|
||||
} SKP_SILK_SDK_EncControlStruct;
|
||||
|
||||
/**************************************************************************/
|
||||
/* Structure for controlling decoder operation and reading decoder status */
|
||||
/**************************************************************************/
|
||||
typedef struct {
|
||||
/* I: Output signal sampling rate in Hertz; 8000/12000/16000/24000 */
|
||||
SKP_int32 API_sampleRate;
|
||||
|
||||
/* O: Number of samples per frame */
|
||||
SKP_int frameSize;
|
||||
|
||||
/* O: Frames per packet 1, 2, 3, 4, 5 */
|
||||
SKP_int framesPerPacket;
|
||||
|
||||
/* O: Flag to indicate that the decoder has remaining payloads internally */
|
||||
SKP_int moreInternalDecoderFrames;
|
||||
|
||||
/* O: Distance between main payload and redundant payload in packets */
|
||||
SKP_int inBandFECOffset;
|
||||
} SKP_SILK_SDK_DecControlStruct;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,89 +0,0 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, (subject to the limitations in the disclaimer below)
|
||||
are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of Skype Limited, nor the names of specific
|
||||
contributors, may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef SKP_SILK_ERRORS_H
|
||||
#define SKP_SILK_ERRORS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/******************/
|
||||
/* Error messages */
|
||||
/******************/
|
||||
#define SKP_SILK_NO_ERROR 0
|
||||
|
||||
/**************************/
|
||||
/* Encoder error messages */
|
||||
/**************************/
|
||||
|
||||
/* Input length is not a multiplum of 10 ms, or length is longer than the packet length */
|
||||
#define SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES -1
|
||||
|
||||
/* Sampling frequency not 8000, 12000, 16000 or 24000 Hertz */
|
||||
#define SKP_SILK_ENC_FS_NOT_SUPPORTED -2
|
||||
|
||||
/* Packet size not 20, 40, 60, 80 or 100 ms */
|
||||
#define SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED -3
|
||||
|
||||
/* Allocated payload buffer too short */
|
||||
#define SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT -4
|
||||
|
||||
/* Loss rate not between 0 and 100 percent */
|
||||
#define SKP_SILK_ENC_INVALID_LOSS_RATE -5
|
||||
|
||||
/* Complexity setting not valid, use 0, 1 or 2 */
|
||||
#define SKP_SILK_ENC_INVALID_COMPLEXITY_SETTING -6
|
||||
|
||||
/* Inband FEC setting not valid, use 0 or 1 */
|
||||
#define SKP_SILK_ENC_INVALID_INBAND_FEC_SETTING -7
|
||||
|
||||
/* DTX setting not valid, use 0 or 1 */
|
||||
#define SKP_SILK_ENC_INVALID_DTX_SETTING -8
|
||||
|
||||
/* Internal encoder error */
|
||||
#define SKP_SILK_ENC_INTERNAL_ERROR -9
|
||||
|
||||
/**************************/
|
||||
/* Decoder error messages */
|
||||
/**************************/
|
||||
|
||||
/* Output sampling frequency lower than internal decoded sampling frequency */
|
||||
#define SKP_SILK_DEC_INVALID_SAMPLING_FREQUENCY -10
|
||||
|
||||
/* Payload size exceeded the maximum allowed 1024 bytes */
|
||||
#define SKP_SILK_DEC_PAYLOAD_TOO_LARGE -11
|
||||
|
||||
/* Payload has bit errors */
|
||||
#define SKP_SILK_DEC_PAYLOAD_ERROR -12
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,107 +0,0 @@
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006-2012, Skype Limited. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, (subject to the limitations in the disclaimer below)
|
||||
are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of Skype Limited, nor the names of specific
|
||||
contributors, may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
|
||||
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef _SKP_SILK_API_TYPDEF_H_
|
||||
#define _SKP_SILK_API_TYPDEF_H_
|
||||
|
||||
#ifndef SKP_USE_DOUBLE_PRECISION_FLOATS
|
||||
#define SKP_USE_DOUBLE_PRECISION_FLOATS 0
|
||||
#endif
|
||||
|
||||
#include <float.h>
|
||||
#if defined( __GNUC__ )
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#define SKP_int int /* used for counters etc; at least 16 bits */
|
||||
#ifdef __GNUC__
|
||||
# define SKP_int64 int64_t
|
||||
#else
|
||||
# define SKP_int64 long long
|
||||
#endif
|
||||
#define SKP_int32 int
|
||||
#define SKP_int16 short
|
||||
#define SKP_int8 signed char
|
||||
|
||||
#define SKP_uint unsigned int /* used for counters etc; at least 16 bits */
|
||||
#ifdef __GNUC__
|
||||
# define SKP_uint64 uint64_t
|
||||
#else
|
||||
# define SKP_uint64 unsigned long long
|
||||
#endif
|
||||
#define SKP_uint32 unsigned int
|
||||
#define SKP_uint16 unsigned short
|
||||
#define SKP_uint8 unsigned char
|
||||
|
||||
#define SKP_int_ptr_size intptr_t
|
||||
|
||||
#if SKP_USE_DOUBLE_PRECISION_FLOATS
|
||||
# define SKP_float double
|
||||
# define SKP_float_MAX DBL_MAX
|
||||
#else
|
||||
# define SKP_float float
|
||||
# define SKP_float_MAX FLT_MAX
|
||||
#endif
|
||||
|
||||
#define SKP_INLINE static __inline
|
||||
|
||||
#ifdef _WIN32
|
||||
# define SKP_STR_CASEINSENSITIVE_COMPARE(x, y) _stricmp(x, y)
|
||||
#else
|
||||
# define SKP_STR_CASEINSENSITIVE_COMPARE(x, y) strcasecmp(x, y)
|
||||
#endif
|
||||
|
||||
#define SKP_int64_MAX ((SKP_int64)0x7FFFFFFFFFFFFFFFLL) /* 2^63 - 1 */
|
||||
#define SKP_int64_MIN ((SKP_int64)0x8000000000000000LL) /* -2^63 */
|
||||
#define SKP_int32_MAX 0x7FFFFFFF /* 2^31 - 1 = 2147483647*/
|
||||
#define SKP_int32_MIN ((SKP_int32)0x80000000) /* -2^31 = -2147483648*/
|
||||
#define SKP_int16_MAX 0x7FFF /* 2^15 - 1 = 32767*/
|
||||
#define SKP_int16_MIN ((SKP_int16)0x8000) /* -2^15 = -32768*/
|
||||
#define SKP_int8_MAX 0x7F /* 2^7 - 1 = 127*/
|
||||
#define SKP_int8_MIN ((SKP_int8)0x80) /* -2^7 = -128*/
|
||||
|
||||
#define SKP_uint32_MAX 0xFFFFFFFF /* 2^32 - 1 = 4294967295 */
|
||||
#define SKP_uint32_MIN 0x00000000
|
||||
#define SKP_uint16_MAX 0xFFFF /* 2^16 - 1 = 65535 */
|
||||
#define SKP_uint16_MIN 0x0000
|
||||
#define SKP_uint8_MAX 0xFF /* 2^8 - 1 = 255 */
|
||||
#define SKP_uint8_MIN 0x00
|
||||
|
||||
#define SKP_TRUE 1
|
||||
#define SKP_FALSE 0
|
||||
|
||||
/* assertions */
|
||||
#if (defined _WIN32 && !defined _WINCE && !defined(__GNUC__) && !defined(NO_ASSERTS))
|
||||
# ifndef SKP_assert
|
||||
# include <crtdbg.h> /* ASSERTE() */
|
||||
# define SKP_assert(COND) _ASSERTE(COND)
|
||||
# endif
|
||||
#else
|
||||
# define SKP_assert(COND)
|
||||
#endif
|
||||
|
||||
#endif
|
Binary file not shown.
@ -40,7 +40,7 @@
|
||||
/* Basic information exposed publicly */
|
||||
#define SMEXT_CONF_NAME "Voice"
|
||||
#define SMEXT_CONF_DESCRIPTION "Inject voice data over existing clients"
|
||||
#define SMEXT_CONF_VERSION "1.0"
|
||||
#define SMEXT_CONF_VERSION "1.1"
|
||||
#define SMEXT_CONF_AUTHOR "BotoX"
|
||||
#define SMEXT_CONF_URL ""
|
||||
#define SMEXT_CONF_LOGTAG "VOICE"
|
||||
@ -61,7 +61,7 @@
|
||||
/** Enable interfaces you want to use here by uncommenting lines */
|
||||
//#define SMEXT_ENABLE_FORWARDSYS
|
||||
//#define SMEXT_ENABLE_HANDLESYS
|
||||
//#define SMEXT_ENABLE_PLAYERHELPERS
|
||||
#define SMEXT_ENABLE_PLAYERHELPERS
|
||||
//#define SMEXT_ENABLE_DBMANAGER
|
||||
#define SMEXT_ENABLE_GAMECONF
|
||||
#define SMEXT_ENABLE_MEMUTILS
|
||||
|
@ -1,68 +0,0 @@
|
||||
//--------------------------------------
|
||||
//--- 010 Editor v6.0.3 Binary Template
|
||||
//
|
||||
// File:
|
||||
// Author:
|
||||
// Revision:
|
||||
// Purpose:
|
||||
//--------------------------------------
|
||||
|
||||
// CClientAudio::DecompressVoice
|
||||
local int64 crcLength = FileSize() - sizeof(uint32);
|
||||
|
||||
uint64 steamId;
|
||||
|
||||
FSeek(crcLength);
|
||||
uint32 crc;
|
||||
|
||||
local int64 crc_calc = Checksum(CHECKSUM_CRC32, 0, crcLength);
|
||||
if (crc != crc_calc) {
|
||||
Warning("CRC mismatch!");
|
||||
return;
|
||||
}
|
||||
|
||||
// CVoiceDecoder::ProcessVoicePayload
|
||||
FSeek(sizeof(uint64));
|
||||
|
||||
while (FTell() < crcLength) {
|
||||
char payloadType;
|
||||
|
||||
switch (payloadType) {
|
||||
default:
|
||||
Warning("Unhandled payload!");
|
||||
return;
|
||||
case 11: // Sample Rate
|
||||
short sampleRate;
|
||||
break;
|
||||
case 10: // Unknown / Unused
|
||||
char unk1;
|
||||
char unk2;
|
||||
break;
|
||||
case 1: // Unknown Codec???
|
||||
case 2: // Speex Data (Unsupported)
|
||||
case 3: // Uncompressed Data
|
||||
case 4: // SILK Data
|
||||
short dataLength;
|
||||
char data[dataLength];
|
||||
break;
|
||||
case 0: // Silence
|
||||
short numSamples;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// CVoiceDecoder::AddIncomingData
|
||||
FSeek(startof(data));
|
||||
|
||||
// VoiceEncoder_SILK::Decompress
|
||||
|
||||
// chunkLength == -1 means ResetState
|
||||
|
||||
while ((FTell() - startof(data)) < dataLength) {
|
||||
struct Chunk {
|
||||
short chunkLength;
|
||||
if (chunkLength != -1) {
|
||||
char chunk[chunkLength];
|
||||
}
|
||||
} chunk;
|
||||
}
|
Reference in New Issue
Block a user