Asterisk - The Open Source Telephony Project  18.5.0
conf_bridge_binaural_hrir_importer.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2016, Frank Haase, Dennis Guse
5  *
6  * Frank Haase <[email protected]>
7  * Dennis Guse <[email protected]>
8  *
9  * See http://www.asterisk.org for more information about
10  * the Asterisk project. Please do not directly contact
11  * any of the maintainers of this project for assistance;
12  * the project provides a web site, mailing lists and IRC
13  * channels for your use.
14  *
15  * This program is free software, distributed under the terms of
16  * the GNU General Public License Version 2. See the LICENSE file
17  * at the top of the source tree.
18  */
19 
20 /*!
21  * \file
22  * Converts a Head Related Impulse Response (HRIR) database (a multi-channel wave) into a C header file.
23  * HRIR for the left ear and HRIR for right ear have to be interleaved.
24  * No further signal processing is applied (e.g., resampling).
25  *
26  * Info messages are printed to stderror and the generated header file to output.
27  */
28 
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <sndfile.h>
34 
35 int main (int argc, char **argv)
36 {
37  char *hrir_filename;
38  unsigned int binaural_index_start;
39  unsigned int binaural_index_end;
40 
41  SNDFILE *hrir_file;
42  SF_INFO hrir_info;
43  float *hrir_data;
44 
45  unsigned int impulse_response_index_start;
46  unsigned int impulse_response_index_end;
47 
48  int j;
49  int ir_current;
50 
51  if(argc != 4) {
52  puts("HRIR database to C header file converter.");
53  puts("Usage: conf_bridge_binaural_hrir_importer HRIR.wav INDEX_START INDEX_END > OUTPUT.h");
54  puts("Example: conf_bridge_binaural_hrir_importer hrirs.wav 0 180 > ../bridges/bridge_softmix/include/hrirs.h");
55 
56  return -1;
57  }
58 
59  /* Parse arguments */
60  hrir_filename = argv[1];
61  binaural_index_start = atoi(argv[2]);
62  binaural_index_end = atoi(argv[3]);
63 
64  /* Read HRIR database */
65  hrir_file = sf_open(hrir_filename, SFM_READ, &hrir_info);
66  if(hrir_file == NULL) {
67  fprintf(stderr, "ERROR: Could not open HRIR database (%s).\n", hrir_filename);
68 
69  return -1;
70  }
71  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);
72 
73  hrir_data = (float *)malloc(hrir_info.channels * hrir_info.frames * sizeof(float));
74  if(hrir_data == NULL) {
75  fprintf(stderr, "ERROR: Out of memory!");
76 
77  return -1;
78  }
79 
80  /* Channels are interleaved */
81  sf_read_float(hrir_file, hrir_data, hrir_info.channels * hrir_info.frames);
82  sf_close(hrir_file);
83 
84  if(binaural_index_start >= binaural_index_end) {
85  fprintf(stderr, "ERROR: INDEX_START (%d) must be smaller than INDEX_END (%d).", binaural_index_start, binaural_index_end);
86  free(hrir_data);
87 
88  return -1;
89  }
90 
91  if (binaural_index_end * 2 >= hrir_info.channels) {
92  fprintf(stderr, "ERROR: END_INDEX (%d) is out of range for HRIR database (%s).\n", binaural_index_end, hrir_filename);
93  free(hrir_data);
94 
95  return -1;
96  }
97 
98  /* Convert indices */
99  impulse_response_index_start = 2 * binaural_index_start;
100  impulse_response_index_end = (binaural_index_end + 1) * 2;
101 
102  /* Write header */
103  printf(FILE_HEADER, hrir_filename, binaural_index_start, binaural_index_end);
104 
105  printf("#define HRIRS_IMPULSE_LEN %ld\n", hrir_info.frames);
106  printf("#define HRIRS_IMPULSE_SIZE %d\n", binaural_index_end - binaural_index_start + 1);
107  printf("#define HRIRS_SAMPLE_RATE %d\n\n", hrir_info.samplerate);
108 
109  printf("float hrirs_left[HRIRS_IMPULSE_SIZE][HRIRS_IMPULSE_LEN] = {\n");
110  for (ir_current = impulse_response_index_start; ir_current < impulse_response_index_end; ir_current += 2) {
111  printf("{");
112 
113  for (j = 0; j < hrir_info.frames - 1; j++) {
114  printf("%.16f,%s", hrir_data[ir_current * hrir_info.frames + j], ((j + 1) % 4 ? " " : "\n"));
115  }
116  /* Write last without trailing "," */
117  printf("%.16f", hrir_data[ir_current * hrir_info.frames + hrir_info.frames - 1]);
118 
119  if (ir_current + 2 < impulse_response_index_end) {
120  printf("},\n");
121  } else {
122  printf("}};");
123  }
124  }
125 
126  printf("\nfloat hrirs_right[HRIRS_IMPULSE_SIZE][HRIRS_IMPULSE_LEN] = {\n");
127  for (ir_current = impulse_response_index_start + 1; ir_current < impulse_response_index_end + 1; ir_current += 2) {
128  printf("{");
129 
130  for (j = 0; j < hrir_info.frames - 1; j++) {
131  printf("%.16f,%s", hrir_data[ir_current * hrir_info.frames + j], ((j + 1) % 4 ? " " : "\n"));
132  }
133  /* Write last without trailing "," */
134  printf("%.16f", hrir_data[ir_current * hrir_info.frames + hrir_info.frames - 1]);
135 
136  if (ir_current + 2 < impulse_response_index_end) {
137  printf("},\n");
138  } else {
139  printf("}};");
140  }
141  }
142 
143  fprintf(stderr, "INFO: Successfully converted: imported %d impulse responses.\n", impulse_response_index_end - impulse_response_index_start);
144  free(hrir_data);
145 
146  return 0;
147 }
#define NULL
Definition: resample.c:96
char * malloc()
void free()
int main(int argc, char **argv)