Asterisk - The Open Source Telephony Project  18.5.0
Macros | Functions
bridge_softmix_binaural.c File Reference

Multi-party software based binaural mixing. More...

#include "include/bridge_softmix_internal.h"
Include dependency graph for bridge_softmix_binaural.c:

Go to the source code of this file.

Macros

#define CONVOLUTION_SAMPLE_SIZE   960
 
#define CONVOLVE_CHANNEL_PREALLOC   3
 
#define CONVOLVE_MAX_BUFFER   4096
 

Functions

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. More...
 
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. More...
 
void check_binaural_position_change (struct ast_bridge *bridge, struct softmix_bridge_data *softmix_data)
 Checks if a position change in the virual enviroment is requested by one of the participants. More...
 
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. More...
 
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. More...
 
struct convolve_channel_pairdo_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). More...
 
void free_convolve_channel (struct convolve_channel *cchan)
 Frees all data needed for binaural processing by an audio channel. More...
 
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). More...
 
void free_convolve_data (struct convolve_data *data)
 Frees all channels and data needed for binaural audio processing. More...
 
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. More...
 
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. More...
 
int init_convolve_channel_pair (struct convolve_channel_pair *cchan_pair, unsigned int hrtf_len, unsigned int chan_pos, unsigned int default_sample_size)
 Initializies all data needed for binaural audio processing of a channel pair (left and right). More...
 
int init_convolve_data (struct convolve_data *data, unsigned int default_sample_size)
 Preinits a specific number of channels (CONVOVLE_CHANNEL_PREALLOC) at the beginning of a conference. More...
 
void random_binaural_pos_change (struct softmix_bridge_data *softmix_data)
 Randomly changes the virtual positions of conference participants. More...
 
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. More...
 
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 sythesis. More...
 
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 unused that it can be reused by the next channel which enters the conference. More...
 
void softmix_process_write_binaural_audio (struct softmix_channel *sc, unsigned int default_sample_size)
 Writes the binaural audio to a channel. More...
 

Detailed Description

Multi-party software based binaural mixing.

Author
Frank Haase fra.h.nosp@m.aase.nosp@m.@goog.nosp@m.lema.nosp@m.il.co.nosp@m.m
Dennis Guse denni.nosp@m.s.gu.nosp@m.se@al.nosp@m.umni.nosp@m..tu-b.nosp@m.erli.nosp@m.n.de

Definition in file bridge_softmix_binaural.c.

Macro Definition Documentation

◆ CONVOLUTION_SAMPLE_SIZE

#define CONVOLUTION_SAMPLE_SIZE   960

The default sample size in an binaural environment with a two-channel codec at 48kHz is 960 samples.

Definition at line 43 of file bridge_softmix_binaural.c.

Referenced by add_binaural_mixing(), and do_convolve().

◆ CONVOLVE_CHANNEL_PREALLOC

#define CONVOLVE_CHANNEL_PREALLOC   3

The number of prealloced channels when a bridge will be created.

Definition at line 37 of file bridge_softmix_binaural.c.

Referenced by init_convolve_data().

◆ CONVOLVE_MAX_BUFFER

#define CONVOLVE_MAX_BUFFER   4096

Max size of the convolve buffer.

Definition at line 39 of file bridge_softmix_binaural.c.

Referenced by init_convolve_channel().

Function Documentation

◆ add_binaural_mixing()

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.

Parameters
bridgeThe conference bridge needed to check if binaural processing is active or not.
softmix_dataContains all data for the softmix bridge and for the binaural processing.
softmix_samplesThe sample size.
mixing_arrayThe array which holds all audio data for mixing.
scThe channel which contains the audio data to process.
channel_nameThe name of the channel

Definition at line 500 of file bridge_softmix_binaural.c.

References convolve_data::binaural_active, ast_bridge_softmix::binaural_active, softmix_channel::binaural_pos, softmix_mixing_array::buffers, softmix_mixing_array::chan_pairs, CONVOLUTION_SAMPLE_SIZE, softmix_bridge_data::convolve, do_convolve_pair(), softmix_channel::is_announcement, NULL, softmix_channel::our_chan_pair, ast_bridge::softmix, and softmix_mixing_array::used_entries.

Referenced by softmix_mixing_loop().

503 {
504  struct convolve_channel_pair *pair;
505 
506  pair = NULL;
507  /* We only check binaural things if at least one binaural channel joined. */
508  if (!(bridge->softmix.binaural_active && softmix_data->convolve.binaural_active
509  && (softmix_samples % CONVOLUTION_SAMPLE_SIZE) == 0)) {
510  return;
511  }
512 
513  if (!sc->is_announcement) {
514  pair = do_convolve_pair(&softmix_data->convolve, sc->binaural_pos,
515  mixing_array->buffers[mixing_array->used_entries], softmix_samples, channel_name);
516  }
517  sc->our_chan_pair = pair;
518  mixing_array->chan_pairs[mixing_array->used_entries] = pair;
519 }
#define CONVOLUTION_SAMPLE_SIZE
struct convolve_channel_pair ** chan_pairs
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).
struct convolve_channel_pair * our_chan_pair
#define NULL
Definition: resample.c:96
struct ast_bridge_softmix softmix
Definition: bridge.h:375
struct convolve_data convolve
unsigned int binaural_active
Definition: bridge.h:303

◆ binaural_mixing()

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.

Parameters
bridgeThe conference bridge needed to check if binaural processing is active or not.
softmix_dataContains all data for the softmix bridge and for the binaural processing.
mixing_arrayThe array which holds all audio data for mixing.
bin_bufThe buffer that will contain the mixing results.
ann_bufThe buffer that will contain mixed announcements in an interleaved format.

Definition at line 521 of file bridge_softmix_binaural.c.

References ast_slinear_saturated_add(), convolve_data::binaural_active, ast_bridge_softmix::binaural_active, softmix_mixing_array::buffers, convolve_channel_pair::chan_left, softmix_mixing_array::chan_pairs, convolve_channel_pair::chan_right, softmix_bridge_data::convolve, softmix_bridge_data::default_sample_size, MAX_DATALEN, NULL, convolve_channel::out_data, ast_bridge::softmix, and softmix_mixing_array::used_entries.

Referenced by softmix_mixing_loop().

523 {
524  unsigned int idx;
525  unsigned int x;
526 
527  if (!(bridge->softmix.binaural_active && softmix_data->convolve.binaural_active)) {
528  return;
529  }
530  /* mix it like crazy (binaural channels) */
531  memset(bin_buf, 0, MAX_DATALEN);
532  memset(ann_buf, 0, MAX_DATALEN);
533 
534  for (idx = 0; idx < mixing_array->used_entries; idx++) {
535  if (mixing_array->chan_pairs[idx] == NULL) {
536  for (x = 0; x < softmix_data->default_sample_size; x++) {
537  ast_slinear_saturated_add(bin_buf + (x * 2), mixing_array->buffers[idx] + x);
538  ast_slinear_saturated_add(bin_buf + (x * 2) + 1, mixing_array->buffers[idx] + x);
539  ann_buf[x * 2] = mixing_array->buffers[idx][x];
540  ann_buf[(x * 2) + 1] = mixing_array->buffers[idx][x];
541  }
542  } else {
543  for (x = 0; x < softmix_data->default_sample_size; x++) {
544  ast_slinear_saturated_add(bin_buf + (x * 2),
545  mixing_array->chan_pairs[idx]->chan_left.out_data + x);
546  ast_slinear_saturated_add(bin_buf + (x * 2) + 1,
547  mixing_array->chan_pairs[idx]->chan_right.out_data + x);
548  }
549  }
550  }
551 }
struct convolve_channel_pair ** chan_pairs
struct convolve_channel chan_left
#define NULL
Definition: resample.c:96
struct ast_bridge_softmix softmix
Definition: bridge.h:375
static force_inline void ast_slinear_saturated_add(short *input, short *value)
Definition: utils.h:425
struct convolve_channel chan_right
#define MAX_DATALEN
struct convolve_data convolve
unsigned int binaural_active
Definition: bridge.h:303

◆ check_binaural_position_change()

void check_binaural_position_change ( struct ast_bridge bridge,
struct softmix_bridge_data softmix_data 
)

Checks if a position change in the virual enviroment is requested by one of the participants.

Parameters
bridgeThe conference bridge.
softmix_dataThe data used by the softmix bridge.

Definition at line 467 of file bridge_softmix_binaural.c.

References ast_bridge_channel_lock_bridge(), ast_bridge_unlock, AST_LIST_TRAVERSE, convolve_data::binaural_active, ast_bridge_softmix::binaural_active, ast_bridge_channel::binaural_pos_change, ast_bridge_channel::bridge, ast_bridge::channels, softmix_bridge_data::convolve, random_binaural_pos_change(), and ast_bridge::softmix.

Referenced by softmix_mixing_loop().

469 {
470  unsigned int pos_change;
471  struct ast_bridge_channel *bridge_channel;
472 
473  /*
474  * We only check binaural things if binaural is activated by the config
475  * and at least one binaural channel joined.
476  */
477  if (!(bridge->softmix.binaural_active && softmix_data->convolve.binaural_active)) {
478  return;
479  }
480  /*
481  * Before we pull any audio, we must check if any channel requests a
482  * change of binaural positions.
483  */
484  pos_change = 0;
485  AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
486  if (!bridge_channel->binaural_pos_change) {
487  continue;
488  }
489  ast_bridge_channel_lock_bridge(bridge_channel);
490  bridge_channel->binaural_pos_change = 0;
491  ast_bridge_unlock(bridge_channel->bridge);
492  pos_change = 1;
493  }
494 
495  if (pos_change) {
496  random_binaural_pos_change(softmix_data);
497  }
498 }
struct ast_bridge_softmix softmix
Definition: bridge.h:375
void random_binaural_pos_change(struct softmix_bridge_data *softmix_data)
Randomly changes the virtual positions of conference participants.
struct ast_bridge * bridge
Bridge this channel is participating in.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_bridge_unlock(bridge)
Unlock the bridge.
Definition: bridge.h:493
struct ast_bridge_channels_list channels
Definition: bridge.h:371
Structure that contains information regarding a channel in a bridge.
void ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
struct convolve_data convolve
Definition: search.h:40
unsigned int binaural_pos_change
unsigned int binaural_active
Definition: bridge.h:303

◆ create_binaural_frame()

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.

Parameters
bridge_channelContains the information if binaural processing is active or not. If active binaural audio data will be copied, if not mono data will be provided in an interleaved format.
scThe softmix channel holding all informations for the process.
bin_bufThe buffer that contains all mixing results.
ann_bufThe buffer that contains mixed announcements in an interleaved format.
softmix_datalenThe size of the audio data.
softmix_samplesThe number of audio samples.
bufThe buffer that contains all mono mixing results, used if binaural processing is inactive.

Definition at line 553 of file bridge_softmix_binaural.c.

References softmix_channel::binaural_suspended, ast_bridge_channel::binaural_suspended, ast_frame::datalen, softmix_channel::final_buf, softmix_channel::is_announcement, ast_frame::samples, and softmix_channel::write_frame.

Referenced by softmix_mixing_loop().

556 {
557  unsigned int i;
558 
559  sc->write_frame.datalen = softmix_datalen * 2;
560  sc->write_frame.samples = softmix_samples * 2;
561  if (!bridge_channel->binaural_suspended) {
562  sc->binaural_suspended = 0;
563  if (sc->is_announcement) {
564  memcpy(sc->final_buf, ann_buf, softmix_datalen * 2);
565  } else {
566  memcpy(sc->final_buf, bin_buf, softmix_datalen * 2);
567  }
568  return;
569  }
570 
571  /*
572  * Mark that binaural output is suspended, since we use two channel audio
573  * we copy the same signals into both channels.
574  */
575  sc->binaural_suspended = 1;
576  for (i = 0; i < softmix_samples; i++) {
577  sc->final_buf[i * 2] = buf[i];
578  sc->final_buf[(i * 2) + 1] = buf[i];
579  }
580 }
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
unsigned int binaural_suspended
unsigned int binaural_suspended
short final_buf[MAX_DATALEN]
struct ast_frame write_frame

◆ do_convolve()

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.

Parameters
chanThe channel that will contain the binaural audio data as result.
in_samplesThe audio data which will be convolved.
in_sample_sizeThe size of the audio data.
hrtf_lengthThe length of the head related transfer function used to convolve the audio.
Return values
0success
-1failure

Definition at line 86 of file bridge_softmix_binaural.c.

References CONVOLUTION_SAMPLE_SIZE, convolve_channel::fftw_in, convolve_channel::fftw_out, convolve_channel::hrtf, convolve_channel::out_data, and convolve_channel::overlap_add.

Referenced by do_convolve_pair().

88 {
89 #ifdef BINAURAL_RENDERING
90  unsigned int i;
91 
92  if (in_sample_size != CONVOLUTION_SAMPLE_SIZE) {
93  return -1;
94  }
95 
96  /* FFT setting real part */
97  for (i = 0; i < CONVOLUTION_SAMPLE_SIZE; i++) {
98  chan->fftw_in[i] = in_samples[i] * (FLT_MAX / SHRT_MAX);
99  }
100 
101  for (i = CONVOLUTION_SAMPLE_SIZE; i < hrtf_length; i++) {
102  chan->fftw_in[i] = 0;
103  }
104  fftw_execute(chan->fftw_plan);
105 
106  /* Imaginary mulitplication (frequency space). */
107  /* First FFTW result has never an imaginary part. */
108  chan->fftw_in[0] = chan->fftw_out[0] * chan->hrtf[0];
109  for (i = 1; i < (hrtf_length / 2); i++) {
110  /* Real part */
111  chan->fftw_in[i] = (chan->fftw_out[i] * chan->hrtf[i]) -
112  (chan->fftw_out[hrtf_length - i] * chan->hrtf[hrtf_length - i]);
113  /* Imaginary part */
114  chan->fftw_in[hrtf_length - i] = (chan->fftw_out[i] * chan->hrtf[hrtf_length - i]) +
115  (chan->fftw_out[hrtf_length - i] * chan->hrtf[i]);
116  }
117 
118  /* The last (if even) FFTW result has never an imaginary part. */
119  if (hrtf_length % 2 == 0) {
120  chan->fftw_in[hrtf_length / 2] = chan->fftw_out[hrtf_length / 2] *
121  chan->hrtf[hrtf_length / 2];
122  }
123 
124  /* iFFT */
125  fftw_execute(chan->fftw_plan_inverse);
126  /* Remove signal increase due to iFFT. */
127  for (i = 0; i < hrtf_length; i++) {
128  chan->fftw_out[i] = chan->fftw_out[i] / (hrtf_length / 2);
129  }
130 
131  /* Save the block for overlapp add in the next itteration. */
132  for (i = 0; i < in_sample_size; i++) {
133  chan->overlap_add[i] += chan->fftw_out[i];
134  }
135 
136  /* Copy real part to the output, ignore the complex part. */
137  for (i = 0; i < in_sample_size; i++) {
138  chan->out_data[i] = chan->overlap_add[i] * (SHRT_MAX / FLT_MAX);
139  chan->overlap_add[i] = chan->fftw_out[i + in_sample_size];
140  }
141 #endif
142  return 0;
143 }
#define CONVOLUTION_SAMPLE_SIZE

◆ do_convolve_pair()

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).

Parameters
dataContains the left and right audio channel.
pos_idThe position the channel has in the virtual enviroment.
in_samplesThe audio data which will be convolved for both channels.
in_sample_sizeThe size of the audio data.
channel_nameThe name of the channel
Return values
Thechannel pair with convolved audio on success.
NULLfailure

Definition at line 145 of file bridge_softmix_binaural.c.

References ast_log, convolve_data::cchan_pair, convolve_channel_pair::chan_left, convolve_channel_pair::chan_right, do_convolve(), convolve_data::hrtf_length, LOG_ERROR, NULL, and convolve_data::pos_ids.

Referenced by add_binaural_mixing().

148 {
149  struct convolve_channel_pair *chan_pair;
150 
151  /* If a position has no active member we will not convolve. */
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);
155  return NULL;
156  }
157 
158  chan_pair = data->cchan_pair[pos_id];
159  if (do_convolve(&chan_pair->chan_left, in_samples, in_sample_size, data->hrtf_length)) {
160  ast_log(LOG_ERROR, "Channel %s: Binaural processing failed.", channel_name);
161  return NULL;
162  }
163 
164  if (do_convolve(&chan_pair->chan_right, in_samples, in_sample_size, data->hrtf_length)) {
165  ast_log(LOG_ERROR, "Channel %s: Binaural processing failed.", channel_name);
166  return NULL;
167  }
168 
169  return chan_pair;
170 }
struct convolve_channel chan_left
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 NULL
Definition: resample.c:96
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
struct convolve_channel chan_right
struct convolve_channel_pair ** cchan_pair

◆ free_convolve_channel()

void free_convolve_channel ( struct convolve_channel cchan)

Frees all data needed for binaural processing by an audio channel.

Parameters
cchanThe channel to clean up.

Definition at line 341 of file bridge_softmix_binaural.c.

References ast_free, convolve_channel::fftw_in, convolve_channel::fftw_out, convolve_channel::hrtf, convolve_channel::out_data, and convolve_channel::overlap_add.

Referenced by free_convolve_channel_pair(), and init_convolve_channel_pair().

342 {
343 #ifdef BINAURAL_RENDERING
344  fftw_free(cchan->fftw_out);
345  fftw_free(cchan->fftw_in);
346  fftw_free(cchan->hrtf);
347  ast_free(cchan->overlap_add);
348  ast_free(cchan->out_data);
349  fftw_destroy_plan(cchan->fftw_plan);
350  fftw_destroy_plan(cchan->fftw_plan_inverse);
351 #endif
352 }
#define ast_free(a)
Definition: astmm.h:182

◆ free_convolve_channel_pair()

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).

Parameters
cchan_pairThe channel pair to clean up.

Definition at line 354 of file bridge_softmix_binaural.c.

References convolve_channel_pair::chan_left, convolve_channel_pair::chan_right, and free_convolve_channel().

Referenced by free_convolve_data(), and init_convolve_data().

355 {
356  free_convolve_channel(&cchan_pair->chan_left);
357  free_convolve_channel(&cchan_pair->chan_right);
358 }
struct convolve_channel chan_left
void free_convolve_channel(struct convolve_channel *cchan)
Frees all data needed for binaural processing by an audio channel.
struct convolve_channel chan_right

◆ free_convolve_data()

void free_convolve_data ( struct convolve_data data)

Frees all channels and data needed for binaural audio processing.

Parameters
dataContains all channels and data for the cleanup process.

Definition at line 360 of file bridge_softmix_binaural.c.

References ast_free, convolve_data::cchan_pair, convolve_data::chan_size, free_convolve_channel_pair(), and convolve_data::pos_ids.

Referenced by softmix_bridge_destroy().

361 {
362  unsigned int i;
363  ast_free(data->pos_ids);
364  for (i = 0; i < data->chan_size; i++) {
366  ast_free(data->cchan_pair[i]);
367  }
368  ast_free(data->cchan_pair);
369 }
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 ast_free(a)
Definition: astmm.h:182
struct convolve_channel_pair ** cchan_pair

◆ get_hrir()

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.

Parameters
chan_posThe position of the channel in the virtual enviroment.
chan_side0 for the left audio channel, 1 for the right.
Return values
Thehrir for the given position in the virtual room for either the left or right channels.
NULLon failure.

Definition at line 172 of file bridge_softmix_binaural.c.

References ast_binaural_positions, ast_log, HRIRS_CHANNEL_LEFT, HRIRS_CHANNEL_RIGHT, hrirs_left, hrirs_right, LOG_ERROR, and NULL.

Referenced by init_convolve_channel().

173 {
174 #ifdef BINAURAL_RENDERING
175  if (chan_side == HRIRS_CHANNEL_LEFT) {
176  return hrirs_left[ast_binaural_positions[chan_pos]];
177  } else if (chan_side == HRIRS_CHANNEL_RIGHT) {
178  return hrirs_right[ast_binaural_positions[chan_pos]];
179  }
180 #else
181  ast_log(LOG_ERROR, "Requesting data for the binaural conference feature without "
182  "it beeing active.\n");
183 #endif
184 
185  return NULL;
186 }
float hrirs_left[HRIRS_IMPULSE_SIZE][HRIRS_IMPULSE_LEN]
Definition: hrirs.h:49
#define NULL
Definition: resample.c:96
static unsigned int ast_binaural_positions[POSITION_SIZE]
float hrirs_right[HRIRS_IMPULSE_SIZE][HRIRS_IMPULSE_LEN]
Definition: hrirs.h:25390
#define ast_log
Definition: astobj2.c:42
#define HRIRS_CHANNEL_RIGHT
#define LOG_ERROR
Definition: logger.h:285
#define HRIRS_CHANNEL_LEFT

◆ init_convolve_channel()

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.

Parameters
channelThe channel used for binaural audio processing.
hrtf_lenThe length of the head related impulse response used for binaural processing.
chan_posThe position of the channel in the virtual enviroment.
chan_side0 for the left audio channel, 1 for the right.
default_sample_sizeThe default size of audio samples.
Return values
0on success
-1on failure

Definition at line 188 of file bridge_softmix_binaural.c.

References ast_calloc, ast_free, CONVOLVE_MAX_BUFFER, convolve_channel::fftw_in, convolve_channel::fftw_out, get_hrir(), HRIRS_IMPULSE_LEN, HRIRS_IMPULSE_SIZE, convolve_channel::hrtf, NULL, convolve_channel::out_data, and convolve_channel::overlap_add.

Referenced by init_convolve_channel_pair().

190 {
191 #ifdef BINAURAL_RENDERING
192  unsigned int j;
193  float *hrir;
194 
195  /* Prepare FFTW. */
196  channel->fftw_in = (double *) fftw_malloc(sizeof(double) * (hrtf_len + 1));
197  if (channel->fftw_in == NULL) {
198  return -1;
199  }
200 
201  channel->fftw_out = (double *) fftw_malloc(sizeof(double) * (hrtf_len + 1));
202  if (channel->fftw_out == NULL) {
203  fftw_free(channel->fftw_in);
204  return -1;
205  }
206 
207  memset(channel->fftw_in, 0, sizeof(double) * (hrtf_len + 1));
208  memset(channel->fftw_out, 0, sizeof(double) * (hrtf_len + 1));
209 
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);
214  channel->out_data = ast_calloc(CONVOLVE_MAX_BUFFER, sizeof(int16_t));
215  if (channel->out_data == NULL) {
216  fftw_free(channel->fftw_in);
217  fftw_free(channel->fftw_out);
218  return -1;
219  }
220 
221  /* Reuse positions if all positions are already used. */
222  chan_pos = chan_pos % HRIRS_IMPULSE_SIZE;
223 
224  /* Get HRTF for the channels spatial position. */
225  hrir = get_hrir(chan_pos, chan_side);
226  if (hrir == NULL) {
227  fftw_free(channel->fftw_in);
228  fftw_free(channel->fftw_out);
229  ast_free(channel->out_data);
230  return -1;
231  }
232 
233  for (j = 0; j < HRIRS_IMPULSE_LEN; j++) {
234  channel->fftw_in[j] = hrir[j];
235  }
236 
237  for (j = HRIRS_IMPULSE_LEN; j < hrtf_len; j++) {
238  channel->fftw_in[j] = 0;
239  }
240 
241  fftw_execute(channel->fftw_plan);
242  channel->hrtf = (double *) fftw_malloc(sizeof(double) * hrtf_len);
243  if (channel->hrtf == NULL) {
244  fftw_free(channel->fftw_in);
245  fftw_free(channel->fftw_out);
246  ast_free(channel->out_data);
247  return -1;
248  }
249 
250  for (j = 0; j < hrtf_len; j++) {
251  channel->hrtf[j] = channel->fftw_out[j];
252  }
253  channel->overlap_add = ast_calloc(default_sample_size, sizeof(float));
254 
255  return 0;
256 #endif
257  return -1;
258 }
#define HRIRS_IMPULSE_SIZE
Definition: hrirs.h:46
short int16_t
Definition: db.h:59
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.
#define CONVOLVE_MAX_BUFFER
#define NULL
Definition: resample.c:96
#define HRIRS_IMPULSE_LEN
Definition: hrirs.h:45
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204

◆ init_convolve_channel_pair()

int init_convolve_channel_pair ( struct convolve_channel_pair cchan_pair,
unsigned int  hrtf_len,
unsigned int  chan_pos,
unsigned int  default_sample_size 
)

Initializies all data needed for binaural audio processing of a channel pair (left and right).

Parameters
cchan_pairThe channel pair used for binaural audio processing.
hrtf_lenThe length of the head related impulse response used for binaural processing.
chan_posThe position of the channel in the virtual enviroment.
default_sample_sizeThe default size of audio samples.
Return values
0on success
-1on failure

Definition at line 260 of file bridge_softmix_binaural.c.

References ast_debug, ast_log, convolve_channel_pair::chan_left, convolve_channel_pair::chan_right, free_convolve_channel(), HRIRS_CHANNEL_LEFT, HRIRS_CHANNEL_RIGHT, init_convolve_channel(), and LOG_ERROR.

Referenced by init_convolve_data(), and set_binaural_data_join().

262 {
263 #ifdef BINAURAL_RENDERING
264  unsigned int hrirs_pos = chan_pos * 2;
265  int success = 0;
266 
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);
269  success = init_convolve_channel(&cchan_pair->chan_left, hrtf_len, chan_pos, HRIRS_CHANNEL_LEFT,
270  default_sample_size);
271  if (success == -1) {
272  return success;
273  }
274 
275  success = init_convolve_channel(&cchan_pair->chan_right, hrtf_len, chan_pos,
276  HRIRS_CHANNEL_RIGHT, default_sample_size);
277  if (success == -1) {
278  free_convolve_channel(&cchan_pair->chan_left);
279  }
280 
281  return success;
282 #else
283  ast_log(LOG_ERROR, "Requesting data for the binaural conference feature "
284  "without it beeing active.\n");
285 
286  return -1;
287 #endif
288 }
struct convolve_channel chan_left
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.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
void free_convolve_channel(struct convolve_channel *cchan)
Frees all data needed for binaural processing by an audio channel.
#define HRIRS_CHANNEL_RIGHT
#define LOG_ERROR
Definition: logger.h:285
struct convolve_channel chan_right
#define HRIRS_CHANNEL_LEFT

◆ init_convolve_data()

int init_convolve_data ( struct convolve_data data,
unsigned int  default_sample_size 
)

Preinits a specific number of channels (CONVOVLE_CHANNEL_PREALLOC) at the beginning of a conference.

Parameters
dataContains all channels and data needed for binaural processing (e.g. head related transfer functions).
default_sample_sizeThe default size of audio samples.
Return values
0on success
-1on failure

Definition at line 290 of file bridge_softmix_binaural.c.

References ast_calloc, ast_free, ast_malloc, convolve_data::cchan_pair, convolve_data::chan_size, CONVOLVE_CHANNEL_PREALLOC, free_convolve_channel_pair(), convolve_data::hrtf_length, init_convolve_channel_pair(), NULL, convolve_data::number_channels, and convolve_data::pos_ids.

Referenced by softmix_mixing_thread().

291 {
292  unsigned int i;
293  unsigned int j;
294  int success;
295  success = 0;
296 
297  data->pos_ids = ast_calloc(sizeof(int), sizeof(int) * CONVOLVE_CHANNEL_PREALLOC);
298  if (data->pos_ids == NULL) {
299  return -1;
300  }
302  data->number_channels = 0;
303  data->cchan_pair = ast_malloc(sizeof(struct convolve_channel_pair *) *
305  if (data->cchan_pair == NULL) {
306  ast_free(data->pos_ids);
307  return -1;
308  }
309 
310  for (i = 0; i < CONVOLVE_CHANNEL_PREALLOC; i++) {
311  data->cchan_pair[i] = ast_malloc(sizeof(struct convolve_channel_pair));
312  if (data->cchan_pair[i] == NULL) {
313  ast_free(data->pos_ids);
314  for (j = 0; j < i; j++) {
315  ast_free(data->cchan_pair[j]);
316  }
317  ast_free(data->cchan_pair);
318  return -1;
319  }
320  }
321 
322  data->hrtf_length = (default_sample_size * 2) - 1;
323  for (i = 0; i < CONVOLVE_CHANNEL_PREALLOC; i++) {
324  success = init_convolve_channel_pair(data->cchan_pair[i], data->hrtf_length, i,
325  default_sample_size);
326  if (success == -1) {
327  ast_free(data->pos_ids);
328  for (j = 0; j < i; j++) {
330  }
331  for (j = 0; j < CONVOLVE_CHANNEL_PREALLOC; j++) {
332  ast_free(data->cchan_pair[j]);
333  }
334  return -1;
335  }
336  }
337 
338  return success;
339 }
#define CONVOLVE_CHANNEL_PREALLOC
#define NULL
Definition: resample.c:96
int init_convolve_channel_pair(struct convolve_channel_pair *cchan_pair, unsigned int hrtf_len, unsigned int chan_pos, unsigned int default_sample_size)
Initializies all data needed for binaural audio processing of a channel pair (left and right)...
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
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 ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
struct convolve_channel_pair ** cchan_pair

◆ random_binaural_pos_change()

void random_binaural_pos_change ( struct softmix_bridge_data softmix_data)

Randomly changes the virtual positions of conference participants.

Parameters
softmix_dataThe structure containing all position informations.

Definition at line 61 of file bridge_softmix_binaural.c.

References convolve_data::cchan_pair, convolve_data::chan_size, softmix_bridge_data::convolve, softmix_bridge_data::default_sample_size, NULL, reset_channel_pair(), and tmp().

Referenced by check_binaural_position_change().

62 {
63  /*
64  * We perform a shuffle of all channels, even the ones that aren't used at the
65  * moment of shuffling now. This has the efect that new members will be placed
66  * randomly too.
67  */
68  unsigned int i;
69  unsigned int j;
70  struct convolve_channel_pair *tmp;
71 
72  if (softmix_data->convolve.chan_size < 2) {
73  return;
74  }
75 
76  srand(time(NULL));
77  for (i = softmix_data->convolve.chan_size - 1; i > 0; i--) {
78  j = rand() % (i + 1);
79  tmp = softmix_data->convolve.cchan_pair[i];
80  reset_channel_pair(tmp, softmix_data->default_sample_size);
81  softmix_data->convolve.cchan_pair[i] = softmix_data->convolve.cchan_pair[j];
82  softmix_data->convolve.cchan_pair[j] = tmp;
83  }
84 }
static int tmp()
Definition: bt_open.c:389
#define NULL
Definition: resample.c:96
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.
struct convolve_channel_pair ** cchan_pair
struct convolve_data convolve

◆ reset_channel_pair()

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.

Parameters
channel_pairThe channel pair which contains the left and right audio channel.
default_sample_sizeThe sample size which the channel pair uses.

Definition at line 54 of file bridge_softmix_binaural.c.

References convolve_channel_pair::chan_left, convolve_channel_pair::chan_right, and convolve_channel::overlap_add.

Referenced by random_binaural_pos_change(), and set_binaural_data_leave().

56 {
57  memset(channel_pair->chan_left.overlap_add, 0, sizeof(float) * default_sample_size);
58  memset(channel_pair->chan_right.overlap_add, 0, sizeof(float) * default_sample_size);
59 }
struct convolve_channel chan_left
struct convolve_channel chan_right

◆ set_binaural_data_join()

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 sythesis.

Parameters
dataContains all channels and data needed for binaural processing (e.g. head related transfer functions).
default_sample_sizeThe default size of audio samples.
Return values
Theposition of the channel in the virtual enviroment.
-1on failure

Definition at line 371 of file bridge_softmix_binaural.c.

References ast_malloc, ast_realloc, convolve_data::cchan_pair, convolve_data::chan_size, convolve_data::hrtf_length, init_convolve_channel_pair(), NULL, convolve_data::number_channels, and convolve_data::pos_ids.

Referenced by softmix_bridge_join().

372 {
373  struct convolve_channel_pair **cchan_pair_tmp;
374  unsigned int i;
375  int *pos_ids_tmp;
376 
377  /* Raise the number of input channels. */
378  data->number_channels++;
379  /* We realloc another channel pair if we are out of prealloced ones. */
380  /* We have prealloced one at the beginning of a conference and if a member leaves. */
381  if (data->chan_size < data->number_channels) {
382  data->chan_size += 1;
383 
384  pos_ids_tmp = ast_realloc(data->pos_ids, data->chan_size * sizeof(int));
385  if (pos_ids_tmp) {
386  data->pos_ids = pos_ids_tmp;
387  } else {
388  goto binaural_join_fails;
389  }
390 
391  data->pos_ids[data->chan_size - 1] = 0;
392  cchan_pair_tmp = ast_realloc(data->cchan_pair,
393  data->chan_size * sizeof(struct convolve_channel_pair *));
394  if (cchan_pair_tmp) {
395  data->cchan_pair = cchan_pair_tmp;
396  } else {
397  goto binaural_join_fails;
398  }
399 
400  data->cchan_pair[data->chan_size - 1] = ast_malloc(sizeof(struct convolve_channel_pair));
401  if (data->cchan_pair[data->chan_size - 1] == NULL) {
402  goto binaural_join_fails;
403  }
404 
405  i = init_convolve_channel_pair(data->cchan_pair[data->chan_size - 1], data->hrtf_length,
406  data->chan_size - 1, default_sample_size);
407  if (i == -1) {
408  goto binaural_join_fails;
409  }
410  }
411 
412  for (i = 0; i < data->chan_size; i++) {
413  if (data->pos_ids[i] == 0) {
414  data->pos_ids[i] = 1;
415  break;
416  }
417  }
418 
419  return i;
420 
421 binaural_join_fails:
422  data->number_channels--;
423  data->chan_size -= 1;
424 
425  return -1;
426 }
#define ast_realloc(p, len)
A wrapper for realloc()
Definition: astmm.h:228
#define NULL
Definition: resample.c:96
int init_convolve_channel_pair(struct convolve_channel_pair *cchan_pair, unsigned int hrtf_len, unsigned int chan_pos, unsigned int default_sample_size)
Initializies all data needed for binaural audio processing of a channel pair (left and right)...
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:193
struct convolve_channel_pair ** cchan_pair

◆ set_binaural_data_leave()

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 unused that it can be reused by the next channel which enters the conference.

Parameters
dataContains all channels and data needed for binaural processing (e.g. head related transfer functions).
posThe position of the channel in the virtual enviroment.
default_sample_sizeThe default size of audio samples.

Definition at line 428 of file bridge_softmix_binaural.c.

References convolve_data::cchan_pair, convolve_data::chan_size, convolve_data::number_channels, convolve_data::pos_ids, and reset_channel_pair().

Referenced by softmix_bridge_leave().

430 {
431  if (pos >= data->chan_size || data->pos_ids[pos] == 0) {
432  return;
433  }
434 
435  reset_channel_pair(data->cchan_pair[pos], default_sample_size);
436  data->number_channels--;
437  data->pos_ids[pos] = 0;
438 }
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.
struct convolve_channel_pair ** cchan_pair

◆ softmix_process_write_binaural_audio()

void softmix_process_write_binaural_audio ( struct softmix_channel sc,
unsigned int  default_sample_size 
)

Writes the binaural audio to a channel.

Parameters
scThe softmix channel.
default_sample_sizeThe default size of audio samples.

Definition at line 440 of file bridge_softmix_binaural.c.

References ast_slinear_saturated_subtract(), softmix_channel::binaural_suspended, convolve_channel_pair::chan_left, convolve_channel_pair::chan_right, softmix_channel::final_buf, softmix_channel::our_buf, softmix_channel::our_chan_pair, convolve_channel::out_data, ast_frame::samples, and softmix_channel::write_frame.

Referenced by softmix_process_write_audio().

442 {
443  unsigned int i;
444 
445  if (sc->write_frame.samples % default_sample_size != 0) {
446  return;
447  }
448 
449  /* If binaural is suspended, the source audio (mono) will be removed. */
450  if (sc->binaural_suspended) {
451  for (i = 0; i < default_sample_size; i++) {
452  ast_slinear_saturated_subtract(&sc->final_buf[i * 2], &sc->our_buf[i]);
453  ast_slinear_saturated_subtract(&sc->final_buf[(i * 2) + 1], &sc->our_buf[i]);
454  }
455  return;
456  }
457 
458  /* If binaural is NOT suspended, the source audio (binaural) will be removed. */
459  for (i = 0; i < default_sample_size; i++) {
461  &sc->our_chan_pair->chan_left.out_data[i]);
462  ast_slinear_saturated_subtract(&sc->final_buf[(i * 2) + 1],
464  }
465 }
struct convolve_channel chan_left
struct convolve_channel_pair * our_chan_pair
short our_buf[MAX_DATALEN]
unsigned int binaural_suspended
short final_buf[MAX_DATALEN]
struct ast_frame write_frame
struct convolve_channel chan_right
static force_inline void ast_slinear_saturated_subtract(short *input, short *value)
Definition: utils.h:438