diff options
author | Jean-Marc Valin <Jean-Marc.Valin@csiro.au> | 2007-05-04 09:11:18 +0400 |
---|---|---|
committer | Jean-Marc Valin <Jean-Marc.Valin@csiro.au> | 2008-05-19 08:53:14 +0400 |
commit | 3d7a6f0bd0a60145d8ac3a2f4037da623f407fba (patch) | |
tree | f90d32540ec3269ef8a405a2e97daaf2f83ffcab /include | |
parent | 6bd022014a21ecca9c27d6041397009a5933ac39 (diff) | |
parent | d2cddf7e2f3c1a75265c43cabaa391037c830745 (diff) |
Big update in the multi-channel AEC to bring it up-to-date with the single
channel AEC. Mainly this means:
1) dual-path adaptive filter
2) Adaptive (pseudo-proportional) learning rate for different taps
3) API change
4) Other minor details
Merge commit 'd2cddf7e2f3c1a75265c43cabaa391037c830745' into stereo
Conflicts:
include/speex/speex_echo.h
libspeex/mdf.c
libspeex/testecho.c
Diffstat (limited to 'include')
-rw-r--r-- | include/speex/Makefile.am | 3 | ||||
-rw-r--r-- | include/speex/speex.h | 34 | ||||
-rw-r--r-- | include/speex/speex_bits.h | 24 | ||||
-rw-r--r-- | include/speex/speex_callbacks.h | 10 | ||||
-rw-r--r-- | include/speex/speex_echo.h | 7 | ||||
-rw-r--r-- | include/speex/speex_header.h | 7 | ||||
-rw-r--r-- | include/speex/speex_jitter.h | 117 | ||||
-rw-r--r-- | include/speex/speex_noglobals.h | 60 | ||||
-rw-r--r-- | include/speex/speex_preprocess.h | 159 | ||||
-rw-r--r-- | include/speex/speex_resampler.h | 328 | ||||
-rw-r--r-- | include/speex/speex_stereo.h | 6 |
11 files changed, 573 insertions, 182 deletions
diff --git a/include/speex/Makefile.am b/include/speex/Makefile.am index f7b65fa..08cd88b 100644 --- a/include/speex/Makefile.am +++ b/include/speex/Makefile.am @@ -11,5 +11,6 @@ pkginclude_HEADERS = speex.h \ speex_stereo.h \ speex_preprocess.h \ speex_jitter.h \ - speex_echo.h + speex_echo.h \ + speex_resampler.h diff --git a/include/speex/speex.h b/include/speex/speex.h index 7f8afa6..f17fa19 100644 --- a/include/speex/speex.h +++ b/include/speex/speex.h @@ -35,6 +35,10 @@ #ifndef SPEEX_H #define SPEEX_H +/** @defgroup Codec Speex encoder and decoder + * This is the Speex codec itself. + * @{ + */ #include "speex/speex_bits.h" #include "speex/speex_types.h" @@ -151,20 +155,6 @@ extern "C" { /** Get status of input/output high-pass filtering */ #define SPEEX_GET_HIGHPASS 45 -/* Used internally, NOT TO BE USED in applications */ -/** Used internally*/ -#define SPEEX_GET_PI_GAIN 100 -/** Used internally*/ -#define SPEEX_GET_EXC 101 -/** Used internally*/ -#define SPEEX_GET_INNOV 102 -/** Used internally*/ -#define SPEEX_GET_DTX_STATUS 103 -/** Used internally*/ -#define SPEEX_SET_INNOVATION_SAVE 104 -/** Used internally*/ -#define SPEEX_SET_WIDEBAND 105 - /* Preserving compatibility:*/ /** Equivalent to SPEEX_SET_ENH */ @@ -307,7 +297,7 @@ typedef struct SpeexMode { * encode, you need one state per channel. * * @param mode The mode to use (either speex_nb_mode or speex_wb.mode) - * @return A newly created encoder + * @return A newly created encoder state or NULL if state allocation fails */ void *speex_encoder_init(const SpeexMode *mode); @@ -318,7 +308,9 @@ void speex_encoder_destroy(void *state); /** Uses an existing encoder state to encode one frame of speech pointed to by "in". The encoded bit-stream is saved in "bits". @param state Encoder state - @param in Frame that will be encoded with a +-2^15 range + @param in Frame that will be encoded with a +-2^15 range. This data MAY be + overwritten by the encoder and should be considered uninitialised + after the call. @param bits Bit-stream where the data will be written @return 0 if frame needs not be transmitted (DTX only), 1 otherwise */ @@ -338,7 +330,7 @@ int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits); * @param state Encoder state * @param request ioctl-type request (one of the SPEEX_* macros) * @param ptr Data exchanged to-from function - * @return 0 if no error, -1 if request in unknown + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter */ int speex_encoder_ctl(void *state, int request, void *ptr); @@ -349,7 +341,7 @@ int speex_encoder_ctl(void *state, int request, void *ptr); * decode, you need one state per channel. * * @param mode Speex mode (one of speex_nb_mode or speex_wb_mode) - * @return A newly created decoder state + * @return A newly created decoder state or NULL if state allocation fails */ void *speex_decoder_init(const SpeexMode *mode); @@ -384,7 +376,7 @@ int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out); * @param state Decoder state * @param request ioctl-type request (one of the SPEEX_* macros) * @param ptr Data exchanged to-from function - * @return 0 if no error, -1 if request in unknown + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter */ int speex_decoder_ctl(void *state, int request, void *ptr); @@ -394,12 +386,14 @@ int speex_decoder_ctl(void *state, int request, void *ptr); * @param mode Speex mode * @param request ioctl-type request (one of the SPEEX_* macros) * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter */ int speex_mode_query(const SpeexMode *mode, int request, void *ptr); /** Functions for controlling the behavior of libspeex * @param request ioctl-type request (one of the SPEEX_LIB_* macros) * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter */ int speex_lib_ctl(int request, void *ptr); @@ -427,5 +421,5 @@ const SpeexMode * speex_lib_get_mode (int mode); } #endif - +/** @}*/ #endif diff --git a/include/speex/speex_bits.h b/include/speex/speex_bits.h index b77202f..88334c4 100644 --- a/include/speex/speex_bits.h +++ b/include/speex/speex_bits.h @@ -35,6 +35,11 @@ #ifndef BITS_H #define BITS_H +/** @defgroup SpeexBits SpeexBits: Bit-stream manipulations + * This is the structure that holds the bit-stream when encoding or decoding + * with Speex. It allows some manipulations as well. + * @{ + */ #ifdef __cplusplus extern "C" { @@ -72,13 +77,20 @@ void speex_bits_rewind(SpeexBits *bits); void speex_bits_read_from(SpeexBits *bits, char *bytes, int len); /** Append bytes to the bit-stream + * * @param bits Bit-stream to operate on * @param bytes pointer to the bytes what will be appended * @param len Number of bytes of append */ void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len); -/** Write the content of a bit-stream to an area of memory */ +/** Write the content of a bit-stream to an area of memory + * + * @param bits Bit-stream to operate on + * @param bytes Memory location where to write the bits + * @param max_len Maximum number of bytes to write (i.e. size of the "bytes" buffer) + * @return Number of bytes written to the "bytes" buffer +*/ int speex_bits_write(SpeexBits *bits, char *bytes, int max_len); /** Like speex_bits_write, but writes only the complete bytes in the stream. Also removes the written bytes from the stream */ @@ -114,13 +126,19 @@ unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits); */ int speex_bits_nbytes(SpeexBits *bits); -/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position */ +/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position + * + * @param bits Bit-stream to operate on + * @param nbBits Number of bits to look for + * @return Value of the bits peeked, interpreted as unsigned + */ unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits); /** Get the value of the next bit in the stream, without modifying the * "cursor" position * * @param bits Bit-stream to operate on + * @return Value of the bit peeked (one bit only) */ int speex_bits_peek(SpeexBits *bits); @@ -134,6 +152,7 @@ void speex_bits_advance(SpeexBits *bits, int n); /** Returns the number of bits remaining to be read in a stream * * @param bits Bit-stream to operate on + * @return Number of bits that can still be read from the stream */ int speex_bits_remaining(SpeexBits *bits); @@ -148,4 +167,5 @@ void speex_bits_insert_terminator(SpeexBits *bits); } #endif +/* @} */ #endif diff --git a/include/speex/speex_callbacks.h b/include/speex/speex_callbacks.h index f6334f2..7892e2f 100644 --- a/include/speex/speex_callbacks.h +++ b/include/speex/speex_callbacks.h @@ -35,6 +35,9 @@ #ifndef SPEEX_CALLBACKS_H #define SPEEX_CALLBACKS_H +/** @defgroup SpeexCallbacks Various definitions for Speex callbacks supported by the decoder. + * @{ + */ #include "speex.h" @@ -110,13 +113,16 @@ int speex_default_user_handler(SpeexBits *bits, void *state, void *data); - +/** Standard handler for low mode request (change low mode, no questions asked) */ int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data); +/** Standard handler for VBR request (Set VBR, no questions asked) */ int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data); +/** Standard handler for enhancer request (Turn ehnancer on/off, no questions asked) */ int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data); +/** Standard handler for VBR quality request (Set VBR quality, no questions asked) */ int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data); @@ -124,5 +130,5 @@ int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *da } #endif - +/** @} */ #endif diff --git a/include/speex/speex_echo.h b/include/speex/speex_echo.h index 2bf8e3f..f5e4b89 100644 --- a/include/speex/speex_echo.h +++ b/include/speex/speex_echo.h @@ -55,16 +55,19 @@ struct SpeexEchoState_; typedef struct SpeexEchoState_ SpeexEchoState; /** Creates a new echo canceller state */ -SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length, int nb_mic, int nb_speakers); +SpeexEchoState *mc_echo_state_init(int frame_size, int filter_length, int nb_mic, int nb_speakers); /** Destroys an echo canceller state */ void mc_echo_state_destroy(SpeexEchoState *st); /** Performs echo cancellation a frame */ +void mc_echo_cancellation(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out); + +/** Performs echo cancellation a frame */ void mc_echo_cancel(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out, spx_int32_t *Yout); /** Perform echo cancellation using internal playback buffer */ -void mc_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out, spx_int32_t *Yout); +void mc_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out); /** Let the echo canceller know that a frame was just played */ void mc_echo_playback(SpeexEchoState *st, const spx_int16_t *play); diff --git a/include/speex/speex_header.h b/include/speex/speex_header.h index 32fb81f..5416459 100644 --- a/include/speex/speex_header.h +++ b/include/speex/speex_header.h @@ -36,6 +36,10 @@ #ifndef SPEEX_HEADER_H #define SPEEX_HEADER_H +/** @defgroup SpeexHeader SpeexHeader: Makes it easy to write/parse an Ogg/Speex header + * This is the Speex header for the Ogg encapsulation. You don't need that if you just use RTP. + * @{ + */ #include "speex/speex_types.h" @@ -45,6 +49,7 @@ extern "C" { struct SpeexMode; +/** Length of the Speex header identifier */ #define SPEEX_HEADER_STRING_LENGTH 8 /** Maximum number of characters for encoding the Speex version number in the header */ @@ -82,5 +87,5 @@ SpeexHeader *speex_packet_to_header(char *packet, int size); } #endif - +/** @} */ #endif diff --git a/include/speex/speex_jitter.h b/include/speex/speex_jitter.h index 34043b3..570e22b 100644 --- a/include/speex/speex_jitter.h +++ b/include/speex/speex_jitter.h @@ -35,6 +35,11 @@ #ifndef SPEEX_JITTER_H #define SPEEX_JITTER_H +/** @defgroup JitterBuffer JitterBuffer: Adaptive jitter buffer + * This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size + * to maintain good quality and low latency. + * @{ + */ #include "speex.h" #include "speex_bits.h" @@ -43,58 +48,128 @@ extern "C" { #endif +/** Generic adaptive jitter buffer state */ struct JitterBuffer_; +/** Generic adaptive jitter buffer state */ typedef struct JitterBuffer_ JitterBuffer; +/** Definition of an incoming packet */ typedef struct _JitterBufferPacket JitterBufferPacket; +/** Definition of an incoming packet */ struct _JitterBufferPacket { - char *data; - spx_uint32_t len; - spx_uint32_t timestamp; - spx_uint32_t span; + char *data; /**< Data bytes contained in the packet */ + spx_uint32_t len; /**< Length of the packet in bytes */ + spx_uint32_t timestamp; /**< Timestamp for the packet */ + spx_uint32_t span; /**< Time covered by the packet (same units as timestamp) */ }; - +/** Packet has been retrieved */ #define JITTER_BUFFER_OK 0 +/** Packet is missing */ #define JITTER_BUFFER_MISSING 1 +/** Packet is incomplete (does not cover the entive tick */ #define JITTER_BUFFER_INCOMPLETE 2 +/** There was an error in the jitter buffer */ #define JITTER_BUFFER_INTERNAL_ERROR -1 +/** Invalid argument */ #define JITTER_BUFFER_BAD_ARGUMENT -2 -/** Initialise jitter buffer */ + +/** Set minimum amount of extra buffering required (margin) */ +#define JITTER_BUFFER_SET_MARGIN 0 +/** Get minimum amount of extra buffering required (margin) */ +#define JITTER_BUFFER_GET_MARGIN 1 +/* JITTER_BUFFER_SET_AVALIABLE_COUNT wouldn't make sense */ +/** Get the amount of avaliable packets currently buffered */ +#define JITTER_BUFFER_GET_AVALIABLE_COUNT 3 + +#define JITTER_BUFFER_ADJUST_INTERPOLATE -1 +#define JITTER_BUFFER_ADJUST_OK 0 +#define JITTER_BUFFER_ADJUST_DROP 1 + +/** Initialises jitter buffer + * + * @param tick Number of samples per "tick", i.e. the time period of the elements that will be retrieved + * @return Newly created jitter buffer state + */ JitterBuffer *jitter_buffer_init(int tick); -/** Reset jitter buffer */ +/** Restores jitter buffer to its original state + * + * @param jitter Jitter buffer state + */ void jitter_buffer_reset(JitterBuffer *jitter); -/** Destroy jitter buffer */ +/** Destroys jitter buffer + * + * @param jitter Jitter buffer state + */ void jitter_buffer_destroy(JitterBuffer *jitter); -/** Put one packet into the jitter buffer */ +/** Put one packet into the jitter buffer + * + * @param jitter Jitter buffer state + * @param packet Incoming packet +*/ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet); -/** Get one packet from the jitter buffer */ -int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_uint32_t *current_timestamp); +/** Get one packet from the jitter buffer + * + * @param jitter Jitter buffer state + * @param packet Returned packet + * @param current_timestamp Timestamp for the returned packet +*/ +int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset); -/** Get pointer timestamp of jitter buffer */ +/** Get pointer timestamp of jitter buffer + * + * @param jitter Jitter buffer state +*/ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter); -/** Advance by one tick */ +/** Advance by one tick + * + * @param jitter Jitter buffer state +*/ void jitter_buffer_tick(JitterBuffer *jitter); +/** Used like the ioctl function to control the jitter buffer parameters + * + * @param jitter Jitter buffer state + * @param request ioctl-type request (one of the JITTER_BUFFER_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown +*/ +int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr); + +int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset); + +/* @} */ -/** Speex jitter-buffer state. */ +/** @defgroup SpeexJitter SpeexJitter: Adaptive jitter buffer specifically for Speex + * This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size + * to maintain good quality and low latency. This is a simplified version that works only + * with Speex, but is much easier to use. + * @{ +*/ + +/** Speex jitter-buffer state. Never use it directly! */ typedef struct SpeexJitter { - SpeexBits current_packet; /**< Current Speex packet */ - int valid_bits; /**< True if Speex bits are valid */ - JitterBuffer *packets; - void *dec; /**< Pointer to Speex decoder */ - int frame_size; /**< Frame size of Speex decoder */ + SpeexBits current_packet; /**< Current Speex packet */ + int valid_bits; /**< True if Speex bits are valid */ + JitterBuffer *packets; /**< Generic jitter buffer state */ + void *dec; /**< Pointer to Speex decoder */ + spx_int32_t frame_size; /**< Frame size of Speex decoder */ } SpeexJitter; -/** Initialise jitter buffer */ +/** Initialise jitter buffer + * + * @param jitter State of the Speex jitter buffer + * @param decoder Speex decoder to call + * @param sampling_rate Sampling rate used by the decoder +*/ void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate); /** Destroy jitter buffer */ @@ -113,5 +188,5 @@ int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter); } #endif - +/* @} */ #endif diff --git a/include/speex/speex_noglobals.h b/include/speex/speex_noglobals.h deleted file mode 100644 index 1d46993..0000000 --- a/include/speex/speex_noglobals.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (C) 2004 CSIRO Australia */ -/* Copyright (C) 2002 Jean-Marc Valin*/ -/** - @file speex_noglobals.h - @brief Dynamically allocates the different modes of the codec -*/ -/* - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 SPEEX_NOGLOBALS_H -#define SPEEX_NOGLOBALS_H - -/* See README.symbian in the Speex source distribution for information - * on using this API */ - -typedef struct SpeexMode SpeexMode; - -#ifdef __cplusplus -extern "C" { -#endif - -/** Instantiate a mode */ -const SpeexMode * speex_mode_new (int modeID); - -/** Destroy a mode */ -void speex_mode_destroy (const SpeexMode * mode); - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/include/speex/speex_preprocess.h b/include/speex/speex_preprocess.h index 5bb3a2c..59b0aab 100644 --- a/include/speex/speex_preprocess.h +++ b/include/speex/speex_preprocess.h @@ -1,8 +1,10 @@ /* Copyright (C) 2003 Epic Games Written by Jean-Marc Valin */ /** - @file speex_preprocess.h - @brief Speex preprocessor + * @file speex_preprocess.h + * @brief Speex preprocessor. The preprocess can do noise suppression, + * residual echo suppression (after using the echo canceller), automatic + * gain control (AGC) and voice activity detection (VAD). */ /* Redistribution and use in source and binary forms, with or without @@ -34,91 +36,61 @@ #ifndef SPEEX_PREPROCESS_H #define SPEEX_PREPROCESS_H +/** @defgroup SpeexPreprocessState SpeexPreprocessState: The Speex preprocessor + * This is the Speex preprocessor. The preprocess can do noise suppression, + * residual echo suppression (after using the echo canceller), automatic + * gain control (AGC) and voice activity detection (VAD). + * @{ + */ #include "speex/speex_types.h" #ifdef __cplusplus extern "C" { #endif + +/** State of the preprocessor (one per channel). Should never be accessed directly. */ +struct SpeexPreprocessState_; -struct drft_lookup; +/** State of the preprocessor (one per channel). Should never be accessed directly. */ +typedef struct SpeexPreprocessState_ SpeexPreprocessState; -/** Speex pre-processor state. */ -typedef struct SpeexPreprocessState { - int frame_size; /**< Number of samples processed each time */ - int ps_size; /**< Number of points in the power spectrum */ - int sampling_rate; /**< Sampling rate of the input/output */ - - /* parameters */ - int denoise_enabled; - int agc_enabled; - float agc_level; - int vad_enabled; - int dereverb_enabled; - float reverb_decay; - float reverb_level; - float speech_prob_start; - float speech_prob_continue; - - float *frame; /**< Processing frame (2*ps_size) */ - float *ps; /**< Current power spectrum */ - float *gain2; /**< Adjusted gains */ - float *window; /**< Analysis/Synthesis window */ - float *noise; /**< Noise estimate */ - float *reverb_estimate; /**< Estimate of reverb energy */ - float *old_ps; /**< Power spectrum for last frame */ - float *gain; /**< Ephraim Malah gain */ - float *prior; /**< A-priori SNR */ - float *post; /**< A-posteriori SNR */ - - float *S; /**< Smoothed power spectrum */ - float *Smin; /**< See Cohen paper */ - float *Stmp; /**< See Cohen paper */ - float *update_prob; /**< Propability of speech presence for noise update */ - - float *zeta; /**< Smoothed a priori SNR */ - float Zpeak; - float Zlast; - - float *loudness_weight; /**< Perceptual loudness curve */ - - float *echo_noise; - - float *noise_bands; - float *noise_bands2; - int noise_bandsN; - float *speech_bands; - float *speech_bands2; - int speech_bandsN; - - float *inbuf; /**< Input buffer (overlapped analysis) */ - float *outbuf; /**< Output buffer (for overlap and add) */ - - float speech_prob; - int last_speech; - float loudness; /**< loudness estimate */ - float loudness2; /**< loudness estimate */ - int nb_adapt; /**< Number of frames used for adaptation so far */ - int nb_loudness_adapt; /**< Number of frames used for loudness adaptation so far */ - int consec_noise; /**< Number of consecutive noise frames */ - int nb_preprocess; /**< Number of frames processed so far */ - struct drft_lookup *fft_lookup; /**< Lookup table for the FFT */ - -} SpeexPreprocessState; - -/** Creates a new preprocessing state */ + +/** Creates a new preprocessing state. You MUST create one state per channel processed. + * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms). Must be + * the same value as that used for the echo canceller for residual echo cancellation to work. + * @param sampling_rate Sampling rate used for the input. + * @return Newly created preprocessor state +*/ SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate); -/** Destroys a denoising state */ +/** Destroys a preprocessor state + * @param st Preprocessor state to destroy +*/ void speex_preprocess_state_destroy(SpeexPreprocessState *st); -/** Preprocess a frame */ +/** Preprocess a frame + * @param st Preprocessor state + * @param x Audio sample vector (in and out). Must be same size as specified in speex_preprocess_state_init(). + * @return Bool value for voice activity (1 for speech, 0 for noise/silence), ONLY if VAD turned on. +*/ +int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x); + +/** Preprocess a frame (deprecated, use speex_preprocess_run() instead)*/ int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo); -/** Preprocess a frame */ -void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo); +/** Update preprocessor state, but do not compute the output + * @param st Preprocessor state + * @param x Audio sample vector (in only). Must be same size as specified in speex_preprocess_state_init(). +*/ +void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x); -/** Used like the ioctl function to control the preprocessor parameters */ +/** Used like the ioctl function to control the preprocessor parameters + * @param st Preprocessor state + * @param request ioctl-type request (one of the SPEEX_PREPROCESS_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown +*/ int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr); @@ -158,14 +130,57 @@ int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr); /** Get preprocessor dereverb decay */ #define SPEEX_PREPROCESS_GET_DEREVERB_DECAY 13 +/** Set probability required for the VAD to go from silence to voice */ #define SPEEX_PREPROCESS_SET_PROB_START 14 +/** Get probability required for the VAD to go from silence to voice */ #define SPEEX_PREPROCESS_GET_PROB_START 15 +/** Set probability required for the VAD to stay in the voice state (integer percent) */ #define SPEEX_PREPROCESS_SET_PROB_CONTINUE 16 +/** Get probability required for the VAD to stay in the voice state (integer percent) */ #define SPEEX_PREPROCESS_GET_PROB_CONTINUE 17 +/** Set maximum attenuation of the noise in dB (negative number) */ +#define SPEEX_PREPROCESS_SET_NOISE_SUPPRESS 18 +/** Get maximum attenuation of the noise in dB (negative number) */ +#define SPEEX_PREPROCESS_GET_NOISE_SUPPRESS 19 + +/** Set maximum attenuation of the residual echo in dB (negative number) */ +#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS 20 +/** Get maximum attenuation of the residual echo in dB (negative number) */ +#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS 21 + +/** Set maximum attenuation of the residual echo in dB when near end is active (negative number) */ +#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE 22 +/** Get maximum attenuation of the residual echo in dB when near end is active (negative number) */ +#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE 23 + +/** Set the corresponding echo canceller state so that residual echo suppression can be performed (NULL for no residual echo suppression) */ +#define SPEEX_PREPROCESS_SET_ECHO_STATE 24 +/** Get the corresponding echo canceller state */ +#define SPEEX_PREPROCESS_GET_ECHO_STATE 25 + +/** Set maximal gain increase in dB/second (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_INCREMENT 26 + +/** Get maximal gain increase in dB/second (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_INCREMENT 27 + +/** Set maximal gain decrease in dB/second (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_DECREMENT 28 + +/** Get maximal gain decrease in dB/second (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_DECREMENT 29 + +/** Set maximal gain in dB (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_MAX_GAIN 30 + +/** Get maximal gain in dB (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_MAX_GAIN 31 + #ifdef __cplusplus } #endif +/** @}*/ #endif diff --git a/include/speex/speex_resampler.h b/include/speex/speex_resampler.h new file mode 100644 index 0000000..c44fbcd --- /dev/null +++ b/include/speex/speex_resampler.h @@ -0,0 +1,328 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: speex_resampler.h + Resampling code + + The design goals of this code are: + - Very fast algorithm + - Low memory requirement + - Good *perceptual* quality (and not best SNR) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 SPEEX_RESAMPLER_H +#define SPEEX_RESAMPLER_H + +#ifdef OUTSIDE_SPEEX + +/********* WARNING: MENTAL SANITY ENDS HERE *************/ + +/* If the resampler is defined outside of Speex, we change the symbol names so that + there won't be any clash if linking with Speex later on. */ + +/* #define RANDOM_PREFIX your software name here */ +#ifndef RANDOM_PREFIX +#error "Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes" +#endif + +#define CAT_PREFIX2(a,b) a ## b +#define CAT_PREFIX(a,b) CAT_PREFIX2(a, b) + +#define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init) +#define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac) +#define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy) +#define speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float) +#define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int) +#define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float) +#define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int) +#define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate) +#define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate) +#define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac) +#define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio) +#define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality) +#define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality) +#define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride) +#define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride) +#define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride) +#define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride) +#define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros) +#define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem) +#define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror) + +#define spx_int16_t short +#define spx_int32_t int +#define spx_uint16_t unsigned short +#define spx_uint32_t unsigned int + +#else /* OUTSIDE_SPEEX */ + +#include "speex/speex_types.h" + +#endif /* OUTSIDE_SPEEX */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPEEX_RESAMPLER_QUALITY_MAX 10 +#define SPEEX_RESAMPLER_QUALITY_MIN 0 +#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4 +#define SPEEX_RESAMPLER_QUALITY_VOIP 3 +#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5 + +enum { + RESAMPLER_ERR_SUCCESS = 0, + RESAMPLER_ERR_ALLOC_FAILED = 1, + RESAMPLER_ERR_BAD_STATE = 2, + RESAMPLER_ERR_INVALID_ARG = 3, + RESAMPLER_ERR_PTR_OVERLAP = 4, + + RESAMPLER_ERR_MAX_ERROR +}; + +struct SpeexResamplerState_; +typedef struct SpeexResamplerState_ SpeexResamplerState; + +/** Create a new resampler with integer input and output rates. + * @param nb_channels Number of channels to be processed + * @param in_rate Input sampling rate (integer number of Hz). + * @param out_rate Output sampling rate (integer number of Hz). + * @param quality Resampling quality between 0 and 10, where 0 has poor quality + * and 10 has very high quality. + * @return Newly created resampler state + * @retval NULL Error: not enough memory + */ +SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, + spx_uint32_t in_rate, + spx_uint32_t out_rate, + int quality, + int *err); + +/** Create a new resampler with fractional input/output rates. The sampling + * rate ratio is an arbitrary rational number with both the numerator and + * denominator being 32-bit integers. + * @param nb_channels Number of channels to be processed + * @param ratio_num Numerator of the sampling rate ratio + * @param ratio_den Denominator of the sampling rate ratio + * @param in_rate Input sampling rate rounded to the nearest integer (in Hz). + * @param out_rate Output sampling rate rounded to the nearest integer (in Hz). + * @param quality Resampling quality between 0 and 10, where 0 has poor quality + * and 10 has very high quality. + * @return Newly created resampler state + * @retval NULL Error: not enough memory + */ +SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, + spx_uint32_t ratio_num, + spx_uint32_t ratio_den, + spx_uint32_t in_rate, + spx_uint32_t out_rate, + int quality, + int *err); + +/** Destroy a resampler state. + * @param st Resampler state + */ +void speex_resampler_destroy(SpeexResamplerState *st); + +/** Resample a float array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param channel_index Index of the channel to process for the multi-channel + * base (0 otherwise) + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the + * number of samples processed + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written + */ +int speex_resampler_process_float(SpeexResamplerState *st, + spx_uint32_t channel_index, + const float *in, + spx_uint32_t *in_len, + float *out, + spx_uint32_t *out_len); + +/** Resample an int array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param channel_index Index of the channel to process for the multi-channel + * base (0 otherwise) + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written + */ +int speex_resampler_process_int(SpeexResamplerState *st, + spx_uint32_t channel_index, + const spx_int16_t *in, + spx_uint32_t *in_len, + spx_int16_t *out, + spx_uint32_t *out_len); + +/** Resample an interleaved float array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed. This is all per-channel. + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written. + * This is all per-channel. + */ +int speex_resampler_process_interleaved_float(SpeexResamplerState *st, + const float *in, + spx_uint32_t *in_len, + float *out, + spx_uint32_t *out_len); + +/** Resample an interleaved int array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed. This is all per-channel. + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written. + * This is all per-channel. + */ +int speex_resampler_process_interleaved_int(SpeexResamplerState *st, + const spx_int16_t *in, + spx_uint32_t *in_len, + spx_int16_t *out, + spx_uint32_t *out_len); + +/** Set (change) the input/output sampling rates (integer value). + * @param st Resampler state + * @param in_rate Input sampling rate (integer number of Hz). + * @param out_rate Output sampling rate (integer number of Hz). + */ +int speex_resampler_set_rate(SpeexResamplerState *st, + spx_uint32_t in_rate, + spx_uint32_t out_rate); + +/** Get the current input/output sampling rates (integer value). + * @param st Resampler state + * @param in_rate Input sampling rate (integer number of Hz) copied. + * @param out_rate Output sampling rate (integer number of Hz) copied. + */ +void speex_resampler_get_rate(SpeexResamplerState *st, + spx_uint32_t *in_rate, + spx_uint32_t *out_rate); + +/** Set (change) the input/output sampling rates and resampling ratio + * (fractional values in Hz supported). + * @param st Resampler state + * @param ratio_num Numerator of the sampling rate ratio + * @param ratio_den Denominator of the sampling rate ratio + * @param in_rate Input sampling rate rounded to the nearest integer (in Hz). + * @param out_rate Output sampling rate rounded to the nearest integer (in Hz). + */ +int speex_resampler_set_rate_frac(SpeexResamplerState *st, + spx_uint32_t ratio_num, + spx_uint32_t ratio_den, + spx_uint32_t in_rate, + spx_uint32_t out_rate); + +/** Get the current resampling ratio. This will be reduced to the least + * common denominator. + * @param st Resampler state + * @param ratio_num Numerator of the sampling rate ratio copied + * @param ratio_den Denominator of the sampling rate ratio copied + */ +void speex_resampler_get_ratio(SpeexResamplerState *st, + spx_uint32_t *ratio_num, + spx_uint32_t *ratio_den); + +/** Set (change) the conversion quality. + * @param st Resampler state + * @param quality Resampling quality between 0 and 10, where 0 has poor + * quality and 10 has very high quality. + */ +int speex_resampler_set_quality(SpeexResamplerState *st, + int quality); + +/** Get the conversion quality. + * @param st Resampler state + * @param quality Resampling quality between 0 and 10, where 0 has poor + * quality and 10 has very high quality. + */ +void speex_resampler_get_quality(SpeexResamplerState *st, + int *quality); + +/** Set (change) the input stride. + * @param st Resampler state + * @param stride Input stride + */ +void speex_resampler_set_input_stride(SpeexResamplerState *st, + spx_uint32_t stride); + +/** Get the input stride. + * @param st Resampler state + * @param stride Input stride copied + */ +void speex_resampler_get_input_stride(SpeexResamplerState *st, + spx_uint32_t *stride); + +/** Set (change) the output stride. + * @param st Resampler state + * @param stride Output stride + */ +void speex_resampler_set_output_stride(SpeexResamplerState *st, + spx_uint32_t stride); + +/** Get the output stride. + * @param st Resampler state copied + * @param stride Output stride + */ +void speex_resampler_get_output_stride(SpeexResamplerState *st, + spx_uint32_t *stride); + +/** Make sure that the first samples to go out of the resamplers don't have + * leading zeros. This is only useful before starting to use a newly created + * resampler. It is recommended to use that when resampling an audio file, as + * it will generate a file with the same length. For real-time processing, + * it is probably easier not to use this call (so that the output duration + * is the same for the first frame). + * @param st Resampler state + */ +int speex_resampler_skip_zeros(SpeexResamplerState *st); + +/** Reset a resampler so a new (unrelated) stream can be processed. + * @param st Resampler state + */ +int speex_resampler_reset_mem(SpeexResamplerState *st); + +/** Returns the English meaning for an error code + * @param err Error code + * @return English string + */ +const char *speex_resampler_strerror(int err); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/speex/speex_stereo.h b/include/speex/speex_stereo.h index 6ccaa31..45da338 100644 --- a/include/speex/speex_stereo.h +++ b/include/speex/speex_stereo.h @@ -34,6 +34,10 @@ #ifndef STEREO_H #define STEREO_H +/** @defgroup SpeexStereoState SpeexStereoState: Handling Speex stereo files + * This describes the Speex intensity stereo encoding/decoding + * @{ + */ #include "speex/speex_types.h" #include "speex/speex_bits.h" @@ -74,5 +78,5 @@ int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data); } #endif - +/** @} */ #endif |