32#ifdef BINAURAL_RENDERING 
   37#define CONVOLVE_CHANNEL_PREALLOC 3 
   39#define CONVOLVE_MAX_BUFFER 4096 
   43#define CONVOLUTION_SAMPLE_SIZE 960 
   45#ifdef BINAURAL_RENDERING 
   46  #if SOFTMIX_BINAURAL_SAMPLE_RATE != HRIRS_SAMPLE_RATE 
   47      #error HRIRs are required to be SOFTMIX_BINAURAL_SAMPLE_RATE Hz. Please adjust hrirs.h accordingly. 
   49  #if CONVOLUTION_SAMPLE_SIZE < HRIRS_IMPULSE_LEN 
   50      #error HRIRS_IMPULSE_LEN cannot be longer than CONVOLUTION_SAMPLE_SIZE. Please adjust hrirs.h accordingly. 
   55        unsigned int default_sample_size)
 
 
   87        unsigned int in_sample_size, 
unsigned int hrtf_length)
 
   89#ifdef BINAURAL_RENDERING 
   98        chan->
fftw_in[i] = in_samples[i] * (FLT_MAX / SHRT_MAX);
 
  104    fftw_execute(chan->fftw_plan);
 
  109    for (i = 1; i < (hrtf_length / 2); i++) {
 
  112                (chan->
fftw_out[hrtf_length - i] * chan->
hrtf[hrtf_length - i]);
 
  119    if (hrtf_length % 2 == 0) {
 
  121                chan->
hrtf[hrtf_length / 2];
 
  125    fftw_execute(chan->fftw_plan_inverse);
 
  127    for (i = 0; i < hrtf_length; i++) {
 
  132    for (i = 0; i < in_sample_size; i++) {
 
  137    for (i = 0; i < in_sample_size; i++) {
 
 
  146        unsigned int pos_id, int16_t *in_samples, 
unsigned int in_sample_size,
 
  147        const char *channel_name)
 
  152    if (data->
pos_ids[pos_id] != 1) {
 
  153        ast_log(
LOG_ERROR, 
"Channel %s: Channel pair has no active member! (pos id = %d)\n",
 
  154                channel_name, pos_id);
 
  160        ast_log(
LOG_ERROR, 
"Channel %s: Binaural processing failed.", channel_name);
 
  165        ast_log(
LOG_ERROR, 
"Channel %s: Binaural processing failed.", channel_name);
 
 
  172float *
get_hrir(
unsigned int chan_pos, 
unsigned int chan_side)
 
  174#ifdef BINAURAL_RENDERING 
  181    ast_log(
LOG_ERROR, 
"Requesting data for the binaural conference feature without " 
  182            "it beeing active.\n");
 
 
  189        unsigned int chan_pos, 
unsigned int chan_side, 
unsigned int default_sample_size)
 
  191#ifdef BINAURAL_RENDERING 
  196    channel->
fftw_in = (
double *) fftw_malloc(
sizeof(
double) * (hrtf_len + 1));
 
  201    channel->
fftw_out = (
double *) fftw_malloc(
sizeof(
double) * (hrtf_len + 1));
 
  207    memset(channel->
fftw_in, 0, 
sizeof(
double) * (hrtf_len + 1));
 
  208    memset(channel->
fftw_out, 0, 
sizeof(
double) * (hrtf_len + 1));
 
  210    channel->fftw_plan = fftw_plan_r2r_1d(hrtf_len, channel->
fftw_in, channel->
fftw_out,
 
  211            FFTW_R2HC, FFTW_PATIENT);
 
  212    channel->fftw_plan_inverse = fftw_plan_r2r_1d(hrtf_len, channel->
fftw_in, channel->
fftw_out,
 
  213            FFTW_HC2R, FFTW_PATIENT);
 
  225    hrir = 
get_hrir(chan_pos, chan_side);
 
  241    fftw_execute(channel->fftw_plan);
 
  242    channel->
hrtf = (
double *) fftw_malloc(
sizeof(
double) * hrtf_len);
 
  250    for (j = 0; j < hrtf_len; j++) {
 
 
  261        unsigned int hrtf_len, 
unsigned int chan_pos, 
unsigned int default_sample_size)
 
  263#ifdef BINAURAL_RENDERING 
  264    unsigned int hrirs_pos = chan_pos * 2;
 
  267    ast_debug(3, 
"Binaural pos for the new channel pair will be L: %d R: %d (pos id = %d)\n",
 
  268            hrirs_pos, hrirs_pos + 1, chan_pos);
 
  270            default_sample_size);
 
  284            "without it beeing active.\n");
 
 
  314            for (j = 0; j < i; j++) {
 
  325                default_sample_size);
 
  328            for (j = 0; j < i; j++) {
 
 
  343#ifdef BINAURAL_RENDERING 
  346    fftw_free(cchan->
hrtf);
 
  349    fftw_destroy_plan(cchan->fftw_plan);
 
  350    fftw_destroy_plan(cchan->fftw_plan_inverse);
 
 
  388            goto binaural_join_fails;
 
  394        if (cchan_pair_tmp) {
 
  397            goto binaural_join_fails;
 
  402            goto binaural_join_fails;
 
  406                data->
chan_size - 1, default_sample_size);
 
  408            goto binaural_join_fails;
 
 
  429        unsigned int default_sample_size)
 
 
  441        unsigned int default_sample_size)
 
  451        for (i = 0; i < default_sample_size; i++) {
 
  459    for (i = 0; i < default_sample_size; i++) {
 
 
  470    unsigned int pos_change;
 
 
  534    for (idx = 0; idx < mixing_array->
used_entries; idx++) {
 
  539                ann_buf[x * 2] = mixing_array->
buffers[idx][x];
 
  540                ann_buf[(x * 2) + 1] = mixing_array->
buffers[idx][x];
 
 
  555        unsigned int softmix_datalen, 
unsigned int softmix_samples, int16_t *
buf)
 
  564            memcpy(sc->
final_buf, ann_buf, softmix_datalen * 2);
 
  566            memcpy(sc->
final_buf, bin_buf, softmix_datalen * 2);
 
  576    for (i = 0; i < softmix_samples; i++) {
 
 
#define ast_realloc(p, len)
A wrapper for realloc()
#define ast_calloc(num, len)
A wrapper for calloc()
#define ast_malloc(len)
A wrapper for malloc()
#define ast_bridge_unlock(bridge)
Unlock the bridge.
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
int set_binaural_data_join(struct convolve_data *data, unsigned int default_sample_size)
Joins a channel into a virtual enviroment build with the help of binaural synthesis.
int do_convolve(struct convolve_channel *chan, int16_t *in_samples, unsigned int in_sample_size, unsigned int hrtf_length)
Binaural convolving of audio data for a channel.
#define CONVOLVE_CHANNEL_PREALLOC
float * get_hrir(unsigned int chan_pos, unsigned int chan_side)
Provides a head related impulse response for the given position in the virtual enviroment.
void create_binaural_frame(struct ast_bridge_channel *bridge_channel, struct softmix_channel *sc, int16_t *bin_buf, int16_t *ann_buf, unsigned int softmix_datalen, unsigned int softmix_samples, int16_t *buf)
Creates a frame out of binaural audio data.
int init_convolve_channel(struct convolve_channel *channel, unsigned int hrtf_len, unsigned int chan_pos, unsigned int chan_side, unsigned int default_sample_size)
Initializes all data needed for binaural audio processing.
void softmix_process_write_binaural_audio(struct softmix_channel *sc, unsigned int default_sample_size)
Writes the binaural audio to a channel.
void binaural_mixing(struct ast_bridge *bridge, struct softmix_bridge_data *softmix_data, struct softmix_mixing_array *mixing_array, int16_t *bin_buf, int16_t *ann_buf)
Mixes all binaural audio data contained in the mixing array.
void reset_channel_pair(struct convolve_channel_pair *channel_pair, unsigned int default_sample_size)
Deletes left over signals on a channel that it can be reused.
void add_binaural_mixing(struct ast_bridge *bridge, struct softmix_bridge_data *softmix_data, unsigned int softmix_samples, struct softmix_mixing_array *mixing_array, struct softmix_channel *sc, const char *channel_name)
Processes audio data with the binaural synthesis and adds the result to the mixing array.
void free_convolve_channel_pair(struct convolve_channel_pair *cchan_pair)
Frees all data needed for binaural processing by a pair of audio channels (left and right).
#define CONVOLVE_MAX_BUFFER
void free_convolve_channel(struct convolve_channel *cchan)
Frees all data needed for binaural processing by an audio channel.
int init_convolve_data(struct convolve_data *data, unsigned int default_sample_size)
Preinits a specific number of channels (CONVOLVE_CHANNEL_PREALLOC) at the beginning of a conference.
void random_binaural_pos_change(struct softmix_bridge_data *softmix_data)
Randomly changes the virtual positions of conference participants.
#define CONVOLUTION_SAMPLE_SIZE
int init_convolve_channel_pair(struct convolve_channel_pair *cchan_pair, unsigned int hrtf_len, unsigned int chan_pos, unsigned int default_sample_size)
Initializes all data needed for binaural audio processing of a channel pair (left and right).
void check_binaural_position_change(struct ast_bridge *bridge, struct softmix_bridge_data *softmix_data)
Checks if a position change in the virtual enviroment is requested by one of the participants.
struct convolve_channel_pair * do_convolve_pair(struct convolve_data *data, unsigned int pos_id, int16_t *in_samples, unsigned int in_sample_size, const char *channel_name)
Binaural convolving of audio data for a channel pair (left and right channel).
void free_convolve_data(struct convolve_data *data)
Frees all channels and data needed for binaural audio processing.
void set_binaural_data_leave(struct convolve_data *data, unsigned int pos, unsigned int default_sample_size)
Removes a channel from the binaural conference bridge. Marks the position in the virtual room as unus...
Multi-party software based channel mixing (header)
#define HRIRS_IMPULSE_SIZE
float hrirs_right[HRIRS_IMPULSE_SIZE][HRIRS_IMPULSE_LEN]
float hrirs_left[HRIRS_IMPULSE_SIZE][HRIRS_IMPULSE_LEN]
#define HRIRS_IMPULSE_LEN
Multi-party software binaural channel mixing (header)
static unsigned int ast_binaural_positions[POSITION_SIZE]
#define HRIRS_CHANNEL_RIGHT
#define HRIRS_CHANNEL_LEFT
#define ast_debug(level,...)
Log a DEBUG message.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Structure that contains information regarding a channel in a bridge.
struct ast_bridge * bridge
Bridge this channel is participating in.
unsigned int binaural_suspended
unsigned int binaural_pos_change
struct ast_bridge_channel::@204 entry
unsigned int binaural_active
Structure that contains information about a bridge.
struct ast_bridge_softmix softmix
struct ast_bridge_channels_list channels
struct convolve_channel chan_left
struct convolve_channel chan_right
struct convolve_channel_pair ** cchan_pair
struct convolve_data convolve
unsigned int default_sample_size
Structure which contains per-channel mixing information.
unsigned int binaural_pos
unsigned int binaural_suspended
struct convolve_channel_pair * our_chan_pair
short final_buf[MAX_DATALEN]
short our_buf[MAX_DATALEN]
unsigned int is_announcement
struct ast_frame write_frame
unsigned int used_entries
struct convolve_channel_pair ** chan_pairs
static force_inline void ast_slinear_saturated_subtract(short *input, short *value)
static force_inline void ast_slinear_saturated_add(short *input, short *value)