diff options
author | Jean-Marc Valin <Jean-Marc.Valin@csiro.au> | 2007-11-26 06:47:00 +0300 |
---|---|---|
committer | Jean-Marc Valin <Jean-Marc.Valin@csiro.au> | 2008-05-19 09:24:16 +0400 |
commit | 622aadef4c06d7a49ca8ef8f5a0f3fad2690daf5 (patch) | |
tree | 3bd5b75baf91876991903e6300eb406ff7c0c303 /include | |
parent | 3d7a6f0bd0a60145d8ac3a2f4037da623f407fba (diff) | |
parent | 37657c2b0b228b26ebecf31e36c69327489e66f1 (diff) |
More changes merged from single channel case, renamed back to speex_*
Merge commit '37657c2b0b228b26ebecf31e36c69327489e66f1' 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 | 13 | ||||
-rw-r--r-- | include/speex/speex.h | 14 | ||||
-rw-r--r-- | include/speex/speex_bits.h | 3 | ||||
-rw-r--r-- | include/speex/speex_buffer.h | 68 | ||||
-rw-r--r-- | include/speex/speex_callbacks.h | 2 | ||||
-rw-r--r-- | include/speex/speex_echo.h | 70 | ||||
-rw-r--r-- | include/speex/speex_jitter.h | 98 | ||||
-rw-r--r-- | include/speex/speex_preprocess.h | 4 | ||||
-rw-r--r-- | include/speex/speex_stereo.h | 13 | ||||
-rw-r--r-- | include/speex/speex_types.h | 10 |
10 files changed, 206 insertions, 89 deletions
diff --git a/include/speex/Makefile.am b/include/speex/Makefile.am index 08cd88b..2ae34f9 100644 --- a/include/speex/Makefile.am +++ b/include/speex/Makefile.am @@ -3,14 +3,7 @@ nodist_pkginclude_HEADERS = speex_config_types.h -pkginclude_HEADERS = speex.h \ - speex_types.h \ - speex_bits.h \ - speex_header.h \ - speex_callbacks.h \ - speex_stereo.h \ - speex_preprocess.h \ - speex_jitter.h \ - speex_echo.h \ - speex_resampler.h +pkginclude_HEADERS = speex.h speex_bits.h speex_buffer.h speex_callbacks.h \ + speex_echo.h speex_header.h speex_jitter.h speex_preprocess.h speex_resampler.h \ + speex_stereo.h speex_types.h diff --git a/include/speex/speex.h b/include/speex/speex.h index f17fa19..54349a1 100644 --- a/include/speex/speex.h +++ b/include/speex/speex.h @@ -155,6 +155,10 @@ extern "C" { /** Get status of input/output high-pass filtering */ #define SPEEX_GET_HIGHPASS 45 +/** Get "activity level" of the last decoded frame, i.e. + how much damage we cause if we remove the frame */ +#define SPEEX_GET_ACTIVITY 47 + /* Preserving compatibility:*/ /** Equivalent to SPEEX_SET_ENH */ @@ -406,17 +410,17 @@ extern const SpeexMode speex_wb_mode; /** Default "ultra-wideband" mode */ extern const SpeexMode speex_uwb_mode; -#ifdef EPIC_48K -/** 4.8 kbps narrowband mode */ -extern const SpeexMode speex_nb_48k_mode; -#endif - /** List of all modes available */ extern const SpeexMode * const speex_mode_list[SPEEX_NB_MODES]; /** Obtain one of the modes available */ const SpeexMode * speex_lib_get_mode (int mode); +#ifndef WIN32 +/* We actually override the function in the narrowband case so that we can avoid linking in the wideband stuff */ +#define speex_lib_get_mode(mode) ((mode)==SPEEX_MODEID_NB ? &speex_nb_mode : speex_lib_get_mode (mode)) +#endif + #ifdef __cplusplus } #endif diff --git a/include/speex/speex_bits.h b/include/speex/speex_bits.h index 88334c4..a26fb4c 100644 --- a/include/speex/speex_bits.h +++ b/include/speex/speex_bits.h @@ -64,6 +64,9 @@ void speex_bits_init(SpeexBits *bits); /** Initializes SpeexBits struct using a pre-allocated buffer*/ void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size); +/** Sets the bits in a SpeexBits struct to use data from an existing buffer (for decoding without copying data) */ +void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size); + /** Frees all resources associated to a SpeexBits struct. Right now this does nothing since no resources are allocated, but this could change in the future.*/ void speex_bits_destroy(SpeexBits *bits); diff --git a/include/speex/speex_buffer.h b/include/speex/speex_buffer.h new file mode 100644 index 0000000..df56f5f --- /dev/null +++ b/include/speex/speex_buffer.h @@ -0,0 +1,68 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: speex_buffer.h + This is a very simple ring buffer implementation. It is not thread-safe + so you need to do your own locking. + + 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_BUFFER_H +#define SPEEX_BUFFER_H + +#include "speex/speex_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct SpeexBuffer_; +typedef struct SpeexBuffer_ SpeexBuffer; + +SpeexBuffer *speex_buffer_init(int size); + +void speex_buffer_destroy(SpeexBuffer *st); + +int speex_buffer_write(SpeexBuffer *st, void *data, int len); + +int speex_buffer_writezeros(SpeexBuffer *st, int len); + +int speex_buffer_read(SpeexBuffer *st, void *data, int len); + +int speex_buffer_get_available(SpeexBuffer *st); + +int speex_buffer_resize(SpeexBuffer *st, int len); + +#ifdef __cplusplus +} +#endif + +#endif + + + + diff --git a/include/speex/speex_callbacks.h b/include/speex/speex_callbacks.h index 7892e2f..6f450b3 100644 --- a/include/speex/speex_callbacks.h +++ b/include/speex/speex_callbacks.h @@ -119,7 +119,7 @@ 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) */ +/** Standard handler for enhancer request (Turn enhancer 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) */ diff --git a/include/speex/speex_echo.h b/include/speex/speex_echo.h index f5e4b89..91314f5 100644 --- a/include/speex/speex_echo.h +++ b/include/speex/speex_echo.h @@ -33,7 +33,10 @@ #ifndef SPEEX_ECHO_H #define SPEEX_ECHO_H - +/** @defgroup SpeexEchoState SpeexEchoState: Acoustic echo canceller + * This is the acoustic echo canceller module. + * @{ + */ #include "speex/speex_types.h" #ifdef __cplusplus @@ -48,44 +51,73 @@ extern "C" { /** Get sampling rate */ #define SPEEX_ECHO_GET_SAMPLING_RATE 25 - -/*struct drft_lookup;*/ +/** Internal echo canceller state. Should never be accessed directly. */ struct SpeexEchoState_; +/** @class SpeexEchoState + * This holds the state of the echo canceller. You need one per channel. +*/ + +/** Internal echo canceller state. Should never be accessed directly. */ typedef struct SpeexEchoState_ SpeexEchoState; -/** Creates a new echo canceller state */ -SpeexEchoState *mc_echo_state_init(int frame_size, int filter_length, int nb_mic, int nb_speakers); +/** Creates a new echo canceller state + * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms) + * @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms) + * @return Newly-created echo canceller state + */ +SpeexEchoState *speex_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); +/** Destroys an echo canceller state + * @param st Echo canceller state +*/ +void speex_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, based on the audio sent to the speaker (no delay is added + * to playback in this form) + * + * @param st Echo canceller state + * @param rec Signal from the microphone (near end + far end echo) + * @param play Signal played to the speaker (received from far end) + * @param out Returns near-end signal with echo removed + */ +void speex_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); +/** Performs echo cancellation a frame (deprecated) */ +void speex_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); +/** Perform echo cancellation using internal playback buffer, which is delayed by two frames + * to account for the delay introduced by most soundcards (but it could be off!) + * @param st Echo canceller state + * @param rec Signal from the microphone (near end + far end echo) + * @param out Returns near-end signal with echo removed +*/ +void speex_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); +/** Let the echo canceller know that a frame was just queued to the soundcard + * @param st Echo canceller state + * @param play Signal played to the speaker (received from far end) +*/ +void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play); -/** Reset the echo canceller state */ -void mc_echo_state_reset(SpeexEchoState *st); +/** Reset the echo canceller to its original state + * @param st Echo canceller state + */ +void speex_echo_state_reset(SpeexEchoState *st); /** Used like the ioctl function to control the echo canceller parameters * - * @param state Encoder state + * @param st Echo canceller state * @param request ioctl-type request (one of the SPEEX_ECHO_* macros) * @param ptr Data exchanged to-from function * @return 0 if no error, -1 if request in unknown */ -int mc_echo_ctl(SpeexEchoState *st, int request, void *ptr); +int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr); #ifdef __cplusplus } #endif + +/** @}*/ #endif diff --git a/include/speex/speex_jitter.h b/include/speex/speex_jitter.h index 570e22b..5bae9cb 100644 --- a/include/speex/speex_jitter.h +++ b/include/speex/speex_jitter.h @@ -41,8 +41,7 @@ * @{ */ -#include "speex.h" -#include "speex_bits.h" +#include "speex/speex_types.h" #ifdef __cplusplus extern "C" { @@ -63,13 +62,16 @@ struct _JitterBufferPacket { 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) */ + spx_uint16_t sequence; /**< RTP Sequence number if available (0 otherwise) */ + spx_uint16_t flags; /**< Info about the returned packet */ + spx_uint32_t user_data; /**< Put whatever data you like here (it's ignored by the jitter buffer) */ }; /** 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 */ +/** Packet is incomplete (does not cover the entire tick */ #define JITTER_BUFFER_INCOMPLETE 2 /** There was an error in the jitter buffer */ #define JITTER_BUFFER_INTERNAL_ERROR -1 @@ -81,20 +83,44 @@ struct _JitterBufferPacket { #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 */ +/* JITTER_BUFFER_SET_AVAILABLE_COUNT wouldn't make sense */ + +/** Get the amount of available packets currently buffered */ +#define JITTER_BUFFER_GET_AVAILABLE_COUNT 3 +/** Included because of an early misspelling (will remove in next release) */ #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 +/** Assign a function to destroy unused packet. When setting that, the jitter + buffer no longer copies packet data. */ +#define JITTER_BUFFER_SET_DESTROY_CALLBACK 4 +/** */ +#define JITTER_BUFFER_GET_DESTROY_CALLBACK 5 + +/** Tell the jitter buffer to only adjust the delay in multiples of the step parameter provided */ +#define JITTER_BUFFER_SET_DELAY_STEP 6 +/** */ +#define JITTER_BUFFER_GET_DELAY_STEP 7 + +/** Tell the jitter buffer to only do concealment in multiples of the size parameter provided */ +#define JITTER_BUFFER_SET_CONCEALMENT_SIZE 8 +#define JITTER_BUFFER_GET_CONCEALMENT_SIZE 9 + +/** Absolute max amount of loss that can be tolerated regardless of the delay. Typical loss + should be half of that or less. */ +#define JITTER_BUFFER_SET_MAX_LATE_RATE 10 +#define JITTER_BUFFER_GET_MAX_LATE_RATE 11 + +/** Equivalent cost of one percent late packet in timestamp units */ +#define JITTER_BUFFER_SET_LATE_COST 12 +#define JITTER_BUFFER_GET_LATE_COST 13 + /** 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); +JitterBuffer *jitter_buffer_init(void); /** Restores jitter buffer to its original state * @@ -119,9 +145,18 @@ void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet); * * @param jitter Jitter buffer state * @param packet Returned packet + * @param desired_span Number of samples (or units) we wish to get from the buffer (no guarantee) * @param current_timestamp Timestamp for the returned packet */ -int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset); +int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset); + +/** Used right after jitter_buffer_get() to obtain another packet that would have the same timestamp. + * This is mainly useful for media where a single "frame" can be split into several packets. + * + * @param jitter Jitter buffer state + * @param packet Returned packet + */ +int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet); /** Get pointer timestamp of jitter buffer * @@ -135,6 +170,12 @@ int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter); */ void jitter_buffer_tick(JitterBuffer *jitter); +/** Telling the jitter buffer about the remaining data in the application buffer + * @param jitter Jitter buffer state + * @param rem Amount of data buffered by the application (timestamp units) + */ +void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem); + /** Used like the ioctl function to control the jitter buffer parameters * * @param jitter Jitter buffer state @@ -148,45 +189,8 @@ int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, /* @} */ -/** @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; /**< Generic jitter buffer state */ - void *dec; /**< Pointer to Speex decoder */ - spx_int32_t frame_size; /**< Frame size of Speex decoder */ -} SpeexJitter; - -/** 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 */ -void speex_jitter_destroy(SpeexJitter *jitter); - -/** Put one packet into the jitter buffer */ -void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp); - -/** Get one packet from the jitter buffer */ -void speex_jitter_get(SpeexJitter *jitter, spx_int16_t *out, int *start_offset); - -/** Get pointer timestamp of jitter buffer */ -int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter); - #ifdef __cplusplus } #endif -/* @} */ #endif diff --git a/include/speex/speex_preprocess.h b/include/speex/speex_preprocess.h index 59b0aab..a0d3aa3 100644 --- a/include/speex/speex_preprocess.h +++ b/include/speex/speex_preprocess.h @@ -178,6 +178,10 @@ int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr); /** Get maximal gain in dB (int32) */ #define SPEEX_PREPROCESS_GET_AGC_MAX_GAIN 31 +/* Can't set loudness */ +/** Get loudness */ +#define SPEEX_PREPROCESS_GET_AGC_LOUDNESS 33 + #ifdef __cplusplus } #endif diff --git a/include/speex/speex_stereo.h b/include/speex/speex_stereo.h index 45da338..a259713 100644 --- a/include/speex/speex_stereo.h +++ b/include/speex/speex_stereo.h @@ -46,7 +46,7 @@ extern "C" { #endif -/** State used for decoding (intensity) stereo information */ +/** If you access any of these fields directly, I'll personally come and bite you */ typedef struct SpeexStereoState { float balance; /**< Left/right balance info */ float e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */ @@ -56,9 +56,18 @@ typedef struct SpeexStereoState { float reserved2; /**< Reserved for future use */ } SpeexStereoState; -/** Initialization value for a stereo state */ +/** Deprecated. Use speex_stereo_state_init() instead. */ #define SPEEX_STEREO_STATE_INIT {1,.5,1,1,0,0} +/** Initialise/create a stereo stereo state */ +SpeexStereoState *speex_stereo_state_init(); + +/** Reset/re-initialise an already allocated stereo state */ +void speex_stereo_state_reset(SpeexStereoState *stereo); + +/** Destroy a stereo stereo state */ +void speex_stereo_state_destroy(SpeexStereoState *stereo); + /** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */ void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits); diff --git a/include/speex/speex_types.h b/include/speex/speex_types.h index c746d4f..852fed8 100644 --- a/include/speex/speex_types.h +++ b/include/speex/speex_types.h @@ -31,10 +31,10 @@ typedef _G_int16_t spx_int16_t; typedef _G_uint16_t spx_uint16_t; # elif defined(__MINGW32__) - typedef short spx_int16_t; - typedef unsigned short spx_uint16_t; - typedef int spx_int32_t; - typedef unsigned int spx_uint32_t; + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; # elif defined(__MWERKS__) typedef int spx_int32_t; typedef unsigned int spx_uint32_t; @@ -56,7 +56,7 @@ typedef SInt32 spx_int32_t; typedef UInt32 spx_uint32_t; -#elif defined(__MACOSX__) /* MacOS X Framework build */ +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ # include <sys/types.h> typedef int16_t spx_int16_t; |