From b58de2fab71ad53b5a385476620dc7b45970cfb6 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Thu, 22 Dec 2016 16:42:46 +0100 Subject: Binaural synthesis (confbridge): Adds utils/conf_bridge_binaural_hrir_importer Adds the import tool for converting a HRIR database to hrirs.h ASTERISK-26292 Change-Id: I51eb31b54c23ffd9b544bdc6a09d20c112c8a547 --- utils/Makefile | 9 ++ utils/conf_bridge_binaural_hrir_importer.c | 148 +++++++++++++++++++++++++++++ utils/utils.xml | 5 + 3 files changed, 162 insertions(+) create mode 100644 utils/conf_bridge_binaural_hrir_importer.c (limited to 'utils') diff --git a/utils/Makefile b/utils/Makefile index 97b0e2fe6..b6618e195 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -70,6 +70,10 @@ ifneq ($(filter pbx_ael,$(MENUSELECT_PBX)),) UTILS:=$(filter-out conf2ael,$(UTILS)) endif +ifeq ($(SNDFILE_LIB),) + UTILS:=$(filter-out conf_bridge_binaural_hrir_importer,$(UTILS)) +endif + all: $(UTILS) install: @@ -93,6 +97,7 @@ clean: rm -f db1-ast/.*.d @$(MAKE) -C db1-ast clean + md5.c: $(ASTTOPDIR)/main/md5.c $(ECHO_PREFIX) echo " [CP] $(subst $(ASTTOPDIR)/,,$<) -> $@" $(CMD_PREFIX) cp "$<" "$@" @@ -188,6 +193,10 @@ smsq: LIBS+=$(POPT_LIB) streamplayer: streamplayer.o +conf_bridge_binaural_hrir_importer: LIBS+=$(SNDFILE_LIB) +conf_bridge_binaural_hrir_importer: _ASTCFLAGS+=$(SNDFILE_INCLUDE) +conf_bridge_binaural_hrir_importer: conf_bridge_binaural_hrir_importer.o + muted: muted.o muted: LIBS+=$(AUDIO_LIBS) muted: _ASTCFLAGS:=$(filter-out -Werror,$(_ASTCFLAGS)) diff --git a/utils/conf_bridge_binaural_hrir_importer.c b/utils/conf_bridge_binaural_hrir_importer.c new file mode 100644 index 000000000..5690d86ea --- /dev/null +++ b/utils/conf_bridge_binaural_hrir_importer.c @@ -0,0 +1,148 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2016, Digium, Inc. + * + * Frank Haase + * Dennis Guse + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/*! + * \file + * Converts a Head Related Impulse Response (HRIR) database (a multi-channel wave) into a C header file. + * HRIR for the left ear and HRIR for right ear have to be interleaved. + * No further signal processing is applied (e.g., resampling). + * + * Info messages are printed to stderror and the generated header file to output. + */ + +#include +#include +#include +#include + +int main (int argc, char **argv) +{ + char *hrir_filename; + unsigned int binaural_index_start; + unsigned int binaural_index_end; + + SNDFILE *hrir_file; + SF_INFO hrir_info; + float *hrir_data; + + unsigned int impulse_response_index_start; + unsigned int impulse_response_index_end; + + int j; + int ir_current; + + if(argc != 4) { + puts("HRIR database to C header file converter."); + puts("Usage: conf_bridge_binaural_hrir_importer HRIR.wav INDEX_START INDEX_END > OUTPUT.h"); + puts("Example: conf_bridge_binaural_hrir_importer hrirs.wav 0 180 > ../bridges/bridge_softmix/include/hrirs.h"); + + return -1; + } + + /* Parse arguments */ + hrir_filename = argv[1]; + binaural_index_start = atoi(argv[2]); + binaural_index_end = atoi(argv[3]); + + /* Read HRIR database */ + hrir_file = sf_open(hrir_filename, SFM_READ, &hrir_info); + if(hrir_file == NULL) { + fprintf(stderr, "ERROR: Could not open HRIR database (%s).\n", hrir_filename); + + return -1; + } + fprintf(stderr, "INFO: Opened HRIR database (%s) with: number channels: %d; samplerate: %d; samples per channel: %ld\n", hrir_filename, hrir_info.channels, hrir_info.samplerate, hrir_info.frames); + + hrir_data = (float *)malloc(hrir_info.channels * hrir_info.frames * sizeof(float)); + if(hrir_data == NULL) { + fprintf(stderr, "ERROR: Out of memory!"); + + return -1; + } + + /* Channels are interleaved */ + sf_read_float(hrir_file, hrir_data, hrir_info.channels * hrir_info.frames); + sf_close(hrir_file); + + if(binaural_index_start >= binaural_index_end) { + fprintf(stderr, "ERROR: INDEX_START (%d) must be smaller than INDEX_END (%d).", binaural_index_start, binaural_index_end); + free(hrir_data); + + return -1; + } + + if (binaural_index_end * 2 >= hrir_info.channels) { + fprintf(stderr, "ERROR: END_INDEX (%d) is out of range for HRIR database (%s).\n", binaural_index_end, hrir_filename); + free(hrir_data); + + return -1; + } + + /* Convert indices */ + impulse_response_index_start = 2 * binaural_index_start; + impulse_response_index_end = (binaural_index_end + 1) * 2; + + /* Write header */ + printf("//Used hrirs database: %s\n", hrir_filename); + printf("//Start index in database: %d\n", impulse_response_index_start); + printf("//End index in database: %d\n", impulse_response_index_end); + + printf("#define HRIRS_IMPULSE_LEN %ld\n", hrir_info.frames); + printf("#define HRIRS_IMPULSE_SIZE %d\n", binaural_index_end - binaural_index_start + 1); + printf("#define HRIRS_SAMPLE_RATE %d\n", hrir_info.samplerate); + + printf("float hrirs_left[HRIRS_IMPULSE_SIZE][HRIRS_IMPULSE_LEN] = {\n"); + for (ir_current = impulse_response_index_start; ir_current < impulse_response_index_end; ir_current += 2) { + printf("{"); + + for (j = 0; j < hrir_info.frames - 1; j++) { + printf("%.16f,", hrir_data[ir_current * hrir_info.frames + j]); + } + /* Write last without trailing "," */ + printf("%.16f", hrir_data[ir_current * hrir_info.frames + hrir_info.frames - 1]); + + if (ir_current + 2 < impulse_response_index_end) { + printf("},\n"); + } else { + printf("}};"); + } + } + + printf("\nfloat hrirs_right[HRIRS_IMPULSE_SIZE][HRIRS_IMPULSE_LEN] = {\n"); + for (ir_current = impulse_response_index_start + 1; ir_current < impulse_response_index_end + 1; ir_current += 2) { + printf("{"); + + for (j = 0; j < hrir_info.frames - 1; j++) { + printf("%.16f,", hrir_data[ir_current * hrir_info.frames + j]); + } + /* Write last without trailing "," */ + printf("%.16f", hrir_data[ir_current * hrir_info.frames + hrir_info.frames - 1]); + + if (ir_current + 2 < impulse_response_index_end) { + printf("},\n"); + } else { + printf("}};"); + } + } + + fprintf(stderr, "INFO: Successfully converted: imported %d impulse responses.\n", impulse_response_index_end - impulse_response_index_start); + free(hrir_data); + + return 0; +} diff --git a/utils/utils.xml b/utils/utils.xml index 909406e84..498929a27 100644 --- a/utils/utils.xml +++ b/utils/utils.xml @@ -20,6 +20,11 @@ newt extended + + no + sndfile + extended + no extended -- cgit v1.2.3