Compare commits
8 Commits
opus
...
CeltOpusTr
| Author | SHA1 | Date | |
|---|---|---|---|
| 984f3804cf | |||
| 37c1a4d1b6 | |||
| ddad8421e7 | |||
| 718284e7dd | |||
| 009962f120 | |||
| a02af1a297 | |||
| 7d46e3b9eb | |||
| 2184fd917a |
@ -36,10 +36,12 @@ for sdk_name in SM.sdks:
|
||||
|
||||
binary.compiler.cxxincludes += [
|
||||
os.path.join(SM.sm_root, 'public', 'extensions'),
|
||||
os.path.join(builder.sourcePath, 'opus')
|
||||
os.path.join(builder.sourcePath, 'opus'),
|
||||
os.path.join(builder.sourcePath, 'celt')
|
||||
]
|
||||
binary.compiler.linkflags += [
|
||||
os.path.join(builder.sourcePath, 'opus', 'libopus.a')
|
||||
os.path.join(builder.sourcePath, 'opus', 'libopus.a'),
|
||||
os.path.join(builder.sourcePath, 'celt', 'libcelt0_patched.a')
|
||||
]
|
||||
|
||||
SM.extensions += builder.Add(project)
|
||||
|
||||
15
README.md
Normal file
15
README.md
Normal file
@ -0,0 +1,15 @@
|
||||
This new branch is used for allowing both nosteamers and linux users to communicate at the same time.
|
||||
|
||||
Nosteamers are stuck with CELT codec as they dont support steam/opus.
|
||||
|
||||
Linux users are stuck with steam as they dont support celt without manually fixing the .so file.
|
||||
|
||||
This branch discards BroadCastVoiceData for instead creating our own SendNetMsg using SVC_VoiceData
|
||||
|
||||
that enables us to take opus packets, decode to raw pcm and encode with celt.
|
||||
|
||||
that enables us to take celt packets, decode to raw pcm and encode with opus.
|
||||
|
||||
currently does the support for nosteamers to hear steam voice chat still have to be improved, but steam users can hear nosteam users very fine.
|
||||
|
||||
the sourcemod plugin used for stubbing nosteamers with SVC_VoiceInit: https://git.unloze.com/UNLOZE/sm-plugins/src/branch/master/CELT_VOICE
|
||||
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/celt_work/bands.o
Normal file
BIN
celt/celt_work/bands.o
Normal file
Binary file not shown.
BIN
celt/celt_work/celt.o
Normal file
BIN
celt/celt_work/celt.o
Normal file
Binary file not shown.
BIN
celt/celt_work/cwrs.o
Normal file
BIN
celt/celt_work/cwrs.o
Normal file
Binary file not shown.
BIN
celt/celt_work/entcode.o
Normal file
BIN
celt/celt_work/entcode.o
Normal file
Binary file not shown.
BIN
celt/celt_work/entdec.o
Normal file
BIN
celt/celt_work/entdec.o
Normal file
Binary file not shown.
BIN
celt/celt_work/entenc.o
Normal file
BIN
celt/celt_work/entenc.o
Normal file
Binary file not shown.
BIN
celt/celt_work/header.o
Normal file
BIN
celt/celt_work/header.o
Normal file
Binary file not shown.
BIN
celt/celt_work/kiss_fft.o
Normal file
BIN
celt/celt_work/kiss_fft.o
Normal file
Binary file not shown.
BIN
celt/celt_work/laplace.o
Normal file
BIN
celt/celt_work/laplace.o
Normal file
Binary file not shown.
BIN
celt/celt_work/mathops.o
Normal file
BIN
celt/celt_work/mathops.o
Normal file
Binary file not shown.
BIN
celt/celt_work/mdct.o
Normal file
BIN
celt/celt_work/mdct.o
Normal file
Binary file not shown.
BIN
celt/celt_work/modes.o
Normal file
BIN
celt/celt_work/modes.o
Normal file
Binary file not shown.
BIN
celt/celt_work/pitch.o
Normal file
BIN
celt/celt_work/pitch.o
Normal file
Binary file not shown.
BIN
celt/celt_work/plc.o
Normal file
BIN
celt/celt_work/plc.o
Normal file
Binary file not shown.
BIN
celt/celt_work/quant_bands.o
Normal file
BIN
celt/celt_work/quant_bands.o
Normal file
Binary file not shown.
BIN
celt/celt_work/rate.o
Normal file
BIN
celt/celt_work/rate.o
Normal file
Binary file not shown.
BIN
celt/celt_work/vq.o
Normal file
BIN
celt/celt_work/vq.o
Normal file
Binary file not shown.
BIN
celt/libcelt0.a
Normal file
BIN
celt/libcelt0.a
Normal file
Binary file not shown.
BIN
celt/libcelt0_patched.a
Normal file
BIN
celt/libcelt0_patched.a
Normal file
Binary file not shown.
1080
extension.cpp
1080
extension.cpp
File diff suppressed because it is too large
Load Diff
57
extension.h
57
extension.h
@ -34,6 +34,7 @@
|
||||
|
||||
#include <poll.h>
|
||||
#include "smsdk_ext.h"
|
||||
#include "celt_header.h"
|
||||
#include "ringbuffer.h"
|
||||
|
||||
/**
|
||||
@ -136,9 +137,13 @@ public: // IConCommandBaseAccessor
|
||||
public:
|
||||
CVoice();
|
||||
void OnGameFrame(bool simulating);
|
||||
bool OnBroadcastVoiceData(IClient *pClient, int nBytes, char *data);
|
||||
bool OnBroadcastVoiceData(IClient *pClient, int nBytes, char *data);
|
||||
|
||||
void ListenSocket();
|
||||
void PushPlayerVoiceData(int playerSlot, int nBytes, char *data);
|
||||
void BroadcastVoiceDataTorchlightCelt(IClient *pClient, int16_t *pPCM, int nSamples);
|
||||
void TranscodeNoSteamToSteam(int playerSlot, int nBytes, char *data);
|
||||
void HandlePlayerVoiceData(int playerSlot);
|
||||
|
||||
private:
|
||||
int m_ListenSocket;
|
||||
@ -161,16 +166,60 @@ private:
|
||||
|
||||
OpusEncoder *m_OpusEncoder;
|
||||
|
||||
double m_AvailableTime;
|
||||
// Torchlight transcode state (48000 Hz stereo -> 22050 Hz mono -> CELT)
|
||||
OpusDecoder *m_TorchlightOpusDecoder;
|
||||
int16_t m_torchMonoAccum[4096];
|
||||
int m_torchMonoAccumLen;
|
||||
int m_torchResampleAccum;
|
||||
|
||||
// Player transcode state (24000 Hz mono -> 22050 Hz mono -> CELT)
|
||||
OpusDecoder *m_PlayerOpusDecoder[SM_MAXPLAYERS + 1];
|
||||
|
||||
double m_AvailableTime;
|
||||
double m_playerAvailableTime[SM_MAXPLAYERS + 1];
|
||||
|
||||
// NoSteam->Steam transcode state per player
|
||||
CRingBuffer m_nosteamOpusPCMBuffer[SM_MAXPLAYERS + 1];
|
||||
int m_nosteamResampleAccum[SM_MAXPLAYERS + 1];
|
||||
OpusEncoder *m_nosteamOpusEncoder[SM_MAXPLAYERS + 1];
|
||||
int16_t m_nosteamLastSample[SM_MAXPLAYERS + 1];
|
||||
|
||||
// CELT encoder (shared by both paths, same output format)
|
||||
struct CEncoderSettings
|
||||
{
|
||||
int32_t SampleRate_Hz;
|
||||
int32_t TargetBitRate_Kbps;
|
||||
int32_t FrameSize;
|
||||
int32_t PacketSize;
|
||||
int32_t Complexity;
|
||||
double FrameTime;
|
||||
} m_CeltEncoderSettings;
|
||||
|
||||
CELTMode *m_pCeltMode;
|
||||
CELTEncoder *m_pCeltCodec;
|
||||
|
||||
CELTMode *m_pCeltModePlayer;
|
||||
CELTEncoder *m_pCeltCodecPlayer[SM_MAXPLAYERS + 1];
|
||||
|
||||
CELTDecoder *m_pCeltDecoder[SM_MAXPLAYERS + 1];
|
||||
|
||||
CRingBuffer m_playerVoiceBuffer[SM_MAXPLAYERS + 1];
|
||||
|
||||
t_SV_BroadcastVoiceData m_SV_BroadcastVoiceData;
|
||||
CDetour *m_VoiceDetour;
|
||||
CDetour *m_ProcessVoiceDataDetour;
|
||||
|
||||
uint16_t m_nosteamSeqNum[SM_MAXPLAYERS + 1];
|
||||
|
||||
double m_nosteamAvailableTime[SM_MAXPLAYERS + 1];
|
||||
|
||||
int m_TorchlightSeqNum;
|
||||
|
||||
void HandleNetwork();
|
||||
void OnDataReceived(CClient *pClient, int16_t *pData, size_t Samples);
|
||||
void HandleVoiceData();
|
||||
void BroadcastVoiceData(IClient *pClient, int nBytes, unsigned char *pData);
|
||||
void HandleVoiceDataTorchlight();
|
||||
void HandleNoSteamVoiceData();
|
||||
void BroadcastVoiceData(IClient *pClient, int nBytes, unsigned char *pData);
|
||||
};
|
||||
|
||||
#endif // _INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_
|
||||
|
||||
195
inetmessage.h
Normal file
195
inetmessage.h
Normal file
@ -0,0 +1,195 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: INetMessage interface
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef INETMESSAGE_FRAEVEN_H
|
||||
#define INETMESSAGE_FRAEVEN_H
|
||||
|
||||
#include "smsdk_ext.h"
|
||||
#include "bitbuf.h"
|
||||
#include "inetchannelinfo.h"
|
||||
|
||||
class INetMsgHandler;
|
||||
class INetMessage;
|
||||
class INetChannel;
|
||||
|
||||
// typedef bool (INetMsgHandler::*PROCESSFUNCPTR)(INetMessage*);
|
||||
// #define CASTPROCPTR( fn ) static_cast <bool (INetMsgHandler::*)(INetMessage*)> (fn)
|
||||
|
||||
class INetMessage
|
||||
{
|
||||
public:
|
||||
virtual ~INetMessage() {};
|
||||
|
||||
// Use these to setup who can hear whose voice.
|
||||
// Pass in client indices (which are their ent indices - 1).
|
||||
|
||||
virtual void SetNetChannel(INetChannel * netchan) = 0; // netchannel this message is from/for
|
||||
virtual void SetReliable( bool state ) = 0; // set to true if it's a reliable message
|
||||
|
||||
virtual bool Process( void ) = 0; // calles the recently set handler to process this message
|
||||
|
||||
virtual bool ReadFromBuffer( bf_read &buffer ) = 0; // returns true if parsing was OK
|
||||
virtual bool WriteToBuffer( bf_write &buffer ) = 0; // returns true if writing was OK
|
||||
|
||||
virtual bool IsReliable( void ) const = 0; // true, if message needs reliable handling
|
||||
|
||||
virtual int GetType( void ) const = 0; // returns module specific header tag eg svc_serverinfo
|
||||
virtual int GetGroup( void ) const = 0; // returns net message group of this message
|
||||
virtual const char *GetName( void ) const = 0; // returns network message name, eg "svc_serverinfo"
|
||||
virtual INetChannel *GetNetChannel( void ) const = 0;
|
||||
virtual const char *ToString( void ) const = 0; // returns a human readable string about message content
|
||||
};
|
||||
|
||||
class CNetMessage : public INetMessage
|
||||
{
|
||||
public:
|
||||
CNetMessage() { m_bReliable = true;
|
||||
m_NetChannel = NULL; }
|
||||
|
||||
virtual ~CNetMessage() {};
|
||||
|
||||
virtual int GetGroup() const { return INetChannelInfo::GENERIC; }
|
||||
INetChannel *GetNetChannel() const { return m_NetChannel; }
|
||||
|
||||
virtual void SetReliable( bool state) {m_bReliable = state;};
|
||||
virtual bool IsReliable() const { return m_bReliable; };
|
||||
virtual void SetNetChannel(INetChannel * netchan) { m_NetChannel = netchan; }
|
||||
virtual bool Process() { return false; }; // no handler set
|
||||
|
||||
protected:
|
||||
bool m_bReliable; // true if message should be send reliable
|
||||
INetChannel *m_NetChannel; // netchannel this message is from/for
|
||||
};
|
||||
|
||||
#define svc_VoiceData 15
|
||||
|
||||
#define DECLARE_BASE_MESSAGE( msgtype ) \
|
||||
public: \
|
||||
bool ReadFromBuffer( bf_read &buffer ); \
|
||||
bool WriteToBuffer( bf_write &buffer ); \
|
||||
const char *ToString() const; \
|
||||
int GetType() const { return msgtype; } \
|
||||
const char *GetName() const { return #msgtype;}\
|
||||
|
||||
#define DECLARE_SVC_MESSAGE( name ) \
|
||||
DECLARE_BASE_MESSAGE( svc_##name ); \
|
||||
IServerMessageHandler *m_pMessageHandler;\
|
||||
bool Process() { return m_pMessageHandler->Process##name( this ); }\
|
||||
|
||||
class SVC_VoiceData : public CNetMessage
|
||||
{
|
||||
DECLARE_SVC_MESSAGE( VoiceData );
|
||||
|
||||
int GetGroup() const { return INetChannelInfo::VOICE; }
|
||||
|
||||
SVC_VoiceData() { m_bReliable = false; }
|
||||
|
||||
public:
|
||||
int m_nFromClient; // client who has spoken
|
||||
bool m_bProximity;
|
||||
int m_nLength; // data length in bits
|
||||
uint64 m_xuid; // X360 player ID
|
||||
|
||||
bf_read m_DataIn;
|
||||
void *m_DataOut;
|
||||
};
|
||||
|
||||
#define NETMSG_TYPE_BITS 6
|
||||
|
||||
bool SVC_VoiceData::WriteToBuffer( bf_write &buffer )
|
||||
{
|
||||
buffer.WriteUBitLong( GetType(), NETMSG_TYPE_BITS );
|
||||
buffer.WriteByte( m_nFromClient );
|
||||
buffer.WriteByte( m_bProximity );
|
||||
buffer.WriteWord( m_nLength );
|
||||
|
||||
return buffer.WriteBits( m_DataOut, m_nLength );
|
||||
}
|
||||
|
||||
bool SVC_VoiceData::ReadFromBuffer( bf_read &buffer )
|
||||
{
|
||||
// VPROF( "SVC_VoiceData::ReadFromBuffer" );
|
||||
|
||||
m_nFromClient = buffer.ReadByte();
|
||||
m_bProximity = !!buffer.ReadByte();
|
||||
m_nLength = buffer.ReadWord();
|
||||
|
||||
// if ( IsX360() )
|
||||
// {
|
||||
// m_xuid = buffer.ReadLongLong();
|
||||
// }
|
||||
|
||||
m_DataIn = buffer;
|
||||
return buffer.SeekRelative( m_nLength );
|
||||
}
|
||||
|
||||
const char *SVC_VoiceData::ToString(void) const
|
||||
{
|
||||
// Q_snprintf(s_text, sizeof(s_text), "%s: client %i, bytes %i", GetName(), m_nFromClient, Bits2Bytes(m_nLength) );
|
||||
// return s_text;
|
||||
return "idc";
|
||||
}
|
||||
|
||||
#define svc_VoiceInit 14
|
||||
|
||||
class SVC_VoiceInit : public CNetMessage
|
||||
{
|
||||
DECLARE_SVC_MESSAGE( VoiceInit );
|
||||
|
||||
int GetGroup() const { return INetChannelInfo::SIGNON; }
|
||||
|
||||
SVC_VoiceInit() : m_nSampleRate(0)
|
||||
{
|
||||
m_bReliable = true;
|
||||
memset(m_szVoiceCodec, 0, sizeof(m_szVoiceCodec));
|
||||
}
|
||||
|
||||
SVC_VoiceInit(const char *pCodec, int nSampleRate) : m_nSampleRate(nSampleRate)
|
||||
{
|
||||
m_bReliable = true;
|
||||
Q_strncpy(m_szVoiceCodec, pCodec ? pCodec : "", sizeof(m_szVoiceCodec));
|
||||
}
|
||||
|
||||
public:
|
||||
char m_szVoiceCodec[MAX_PATH];
|
||||
int m_nSampleRate;
|
||||
};
|
||||
|
||||
bool SVC_VoiceInit::WriteToBuffer(bf_write &buffer)
|
||||
{
|
||||
buffer.WriteUBitLong(GetType(), NETMSG_TYPE_BITS);
|
||||
buffer.WriteString(m_szVoiceCodec);
|
||||
buffer.WriteShort(m_nSampleRate);
|
||||
return !buffer.IsOverflowed();
|
||||
}
|
||||
|
||||
bool SVC_VoiceInit::ReadFromBuffer(bf_read &buffer)
|
||||
{
|
||||
buffer.ReadString(m_szVoiceCodec, sizeof(m_szVoiceCodec));
|
||||
m_nSampleRate = buffer.ReadShort();
|
||||
return !buffer.IsOverflowed();
|
||||
}
|
||||
|
||||
const char *SVC_VoiceInit::ToString() const
|
||||
{
|
||||
return "SVC_VoiceInit";
|
||||
}
|
||||
|
||||
#define clc_VoiceData 10
|
||||
|
||||
//objdump -d /home/gameservers/css_dev/bin/engine_srv.so | grep -A 15 "_ZN11CGameClient16ProcessVoiceDataEP13CLC_VoiceData"
|
||||
class CLC_VoiceData
|
||||
{
|
||||
public:
|
||||
uint8_t _pad[20]; // vtable + CNetMessage base fields + padding up to m_nLength (20 offset)
|
||||
int m_nLength;
|
||||
bf_read m_DataIn;
|
||||
bf_write m_DataOut;
|
||||
uint64 m_xuid;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -65,7 +65,7 @@ void CRingBuffer::Mix(int16_t *pData, size_t Samples)
|
||||
}
|
||||
}
|
||||
|
||||
bool CRingBuffer::Push(int16_t *pData, size_t Samples)
|
||||
bool CRingBuffer::PushTorch(int16_t *pData, size_t Samples)
|
||||
{
|
||||
if(Samples > CurrentFree())
|
||||
return false;
|
||||
@ -127,6 +127,34 @@ bool CRingBuffer::Push(int16_t *pData, size_t Samples)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRingBuffer::Push(int16_t *pData, size_t Samples)
|
||||
{
|
||||
if(Samples > CurrentFree())
|
||||
return false; // Safely drop if buffer overflows, preventing distortion
|
||||
|
||||
if(m_WriteIndex + Samples > m_BufferSize)
|
||||
{
|
||||
size_t TowardsEnd = m_BufferSize - m_WriteIndex;
|
||||
memcpy(&m_aBuffer[m_WriteIndex], pData, TowardsEnd * sizeof(*m_aBuffer));
|
||||
m_WriteIndex = 0;
|
||||
|
||||
size_t Left = Samples - TowardsEnd;
|
||||
memcpy(m_aBuffer, &pData[TowardsEnd], Left * sizeof(*m_aBuffer));
|
||||
m_WriteIndex = Left;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&m_aBuffer[m_WriteIndex], pData, Samples * sizeof(*m_aBuffer));
|
||||
m_WriteIndex += Samples;
|
||||
}
|
||||
|
||||
if(m_WriteIndex == m_BufferSize)
|
||||
m_WriteIndex = 0;
|
||||
|
||||
m_Length += Samples;
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t CRingBuffer::TotalLength()
|
||||
{
|
||||
return m_Length;
|
||||
|
||||
@ -12,6 +12,7 @@ public:
|
||||
|
||||
bool Pop(int16_t *pData, size_t Samples);
|
||||
bool Push(int16_t *pData, size_t BufLen);
|
||||
bool PushTorch(int16_t *pData, size_t BufLen);
|
||||
|
||||
size_t TotalLength();
|
||||
size_t TotalFree();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user