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);
101 for (i = CONVOLUTION_SAMPLE_SIZE; i < hrtf_length; i++) {
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);
172 float *
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));
197 if (channel->
fftw_in == NULL) {
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);
222 chan_pos = chan_pos % HRIRS_IMPULSE_SIZE;
225 hrir =
get_hrir(chan_pos, chan_side);
233 for (j = 0; j < HRIRS_IMPULSE_LEN; j++) {
237 for (j = HRIRS_IMPULSE_LEN; j < hrtf_len; j++) {
241 fftw_execute(channel->fftw_plan);
242 channel->
hrtf = (
double *) fftw_malloc(
sizeof(
double) * hrtf_len);
243 if (channel->
hrtf == NULL) {
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);
283 ast_log(LOG_ERROR,
"Requesting data for the binaural conference feature "
284 "without it beeing active.\n");
304 CONVOLVE_CHANNEL_PREALLOC);
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++) {
453 ast_slinear_saturated_subtract(&sc->
final_buf[(i * 2) + 1], &sc->
our_buf[i]);
459 for (i = 0; i < default_sample_size; i++) {
460 ast_slinear_saturated_subtract(&sc->
final_buf[i * 2],
462 ast_slinear_saturated_subtract(&sc->
final_buf[(i * 2) + 1],
470 unsigned int pos_change;
515 mixing_array->buffers[mixing_array->used_entries], softmix_samples, channel_name);
518 mixing_array->
chan_pairs[mixing_array->used_entries] = pair;
531 memset(bin_buf, 0, MAX_DATALEN);
532 memset(ann_buf, 0, MAX_DATALEN);
534 for (idx = 0; idx < mixing_array->used_entries; idx++) {
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];
544 ast_slinear_saturated_add(bin_buf + (x * 2),
546 ast_slinear_saturated_add(bin_buf + (x * 2) + 1,
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++) {
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.
Multi-party software based channel mixing (header)
#define CONVOLUTION_SAMPLE_SIZE
struct convolve_channel_pair ** chan_pairs
#define ast_realloc(p, len)
A wrapper for realloc()
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...
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.
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 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.
unsigned int default_sample_size
unsigned int binaural_pos
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.
struct convolve_channel_pair * our_chan_pair
#define CONVOLVE_MAX_BUFFER
short our_buf[MAX_DATALEN]
unsigned int binaural_suspended
#define CONVOLVE_CHANNEL_PREALLOC
unsigned int binaural_suspended
void softmix_process_write_binaural_audio(struct softmix_channel *sc, unsigned int default_sample_size)
Writes the binaural audio to a channel.
static unsigned int ast_binaural_positions[POSITION_SIZE]
short final_buf[MAX_DATALEN]
struct ast_bridge_softmix softmix
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.
Multi-party software binaural channel mixing (header)
void free_convolve_channel(struct convolve_channel *cchan)
Frees all data needed for binaural processing by an audio channel.
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)...
#define ast_malloc(len)
A wrapper for malloc()
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_debug(level,...)
Log a DEBUG message.
#define HRIRS_CHANNEL_RIGHT
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...
void free_convolve_data(struct convolve_data *data)
Frees all channels and data needed for binaural audio processing.
Structure that contains information about a bridge.
struct ast_frame write_frame
Structure which contains per-channel mixing information.
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.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define ast_bridge_unlock(bridge)
Unlock the bridge.
#define ast_calloc(num, len)
A wrapper for calloc()
struct convolve_channel chan_right
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.
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 ast_bridge_channels_list channels
struct convolve_channel_pair ** cchan_pair
Structure that contains information regarding a channel in a bridge.
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 ast_bridge_channel_lock_bridge(struct ast_bridge_channel *bridge_channel)
Lock the bridge associated with the bridge channel.
struct convolve_data convolve
unsigned int is_announcement
unsigned int binaural_pos_change
#define HRIRS_CHANNEL_LEFT
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.
unsigned int binaural_active