CSL 5.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

BinauralDB.h
Go to the documentation of this file.
1 ///
2 /// BinauralDB.h -- Specification of the HRTF file format and database
3 /// This is the CSL 5 version that uses the FFT wrapper framework
4 ///
5 /// Classes
6 /// HRTF: holds the data that corresponds to an HRTF for a single position
7 /// as a stereo pair of multi-block arrays of complex spectra.
8 /// 2 channels * 16 blocks * 512-complex-float arrays
9 /// There is support in the code for taking a subset of the HRIR and changing the block size.
10 ///
11 /// HRTFDatabase: vector of HRTFs; implemented as a Singleton because it's large.
12 /// Has a vector of HRTFs and can access them by position -- hrtfAt(CPoint) --
13 /// or by index -- hrtfAt(unsigned). Create it with a folder/resource name,
14 /// it reads "files.txt" for a list of HRIR files to load.
15 /// This has a number of file/folder/DB IO methods for load/store of bulk HRTF
16 /// data sets in IRCAM format and CSL's pre-processed HRTF.dat files.
17 ///
18 /// The companion file has the classes
19 /// BinauralPanner: place sources in 3D using block-wise convolution with an HRTF;
20 /// best heard over headphones .
21 /// BinauralSourceCache: used for caching previous state of spatial sources.
22 ///
23 /// See the copyright notice and acknowledgment of authors in the file COPYRIGHT
24 /// Created by Jorge Castellanos on 7/19/06.
25 /// Inspired by and partially based on the VST HRTF Plug-in written by Ryan Avery.
26 /// Rewritten for FFT wrappers and pluggable sound file APIs in 8/09 by STP.
27 ///
28 /// @todo HRTFs should be equalized, currently they are being loaded and used raw.
29 /// @todo Interpolation of HRTFs. Currently the closest HRTF is being used.
30 ///
31 /// CSL HRTF.dat file format
32 /// Header = a string with the label and geometry list,
33 /// label is: "HRTF" name #-hrtfs HRIR-len blk-size #-blocks
34 /// as in, HRTF 1047 188 8192 512 16
35 ///
36 /// geometry is a cr-separated list of 2 integers per line of the azim/elev
37 /// in degrees of the points; empty line ends list.
38 ///
39 /// Header is followed by the per-head, per-spsition, blocked HRTF complex vectors.
40 /// 2-16 blocks/set, each has 257 or 513 complex values for L and R
41 /// for full-len HRIR, this = 8 * 2 * 513 * 16 = 131 kB / HRTF * 188 = 24.6 MB / DB
42 ///
43 /// Trailer is "\nHRTF\n"
44 /// The methods storeToDB() and loadFromDB() implement this format.
45 ///
46
47 #ifndef CSL_BINAURALDB_H
48 #define CSL_BINAURALDB_H
49
50 #include "CSL_Core.h"
51 #include "SpatialPanner.h"
52 #include "FFT_Wrapper.h"
53
54 #ifdef USE_JSND
55 #include "SoundFileJ.h"
56 #endif
57 #ifdef USE_LSND
58 #include "SoundFileL.h"
59 #endif
60 #ifdef USE_CASND
61 #include "SoundFileCA.h"
62 #endif
63
64 #ifndef IPHONE /// Typically CGestalt::blockSize()
65 #define HRTF_BLOCK_SIZE 512 /// (or use a block resizer)
66 #define HRIR_SIZE 1024 /// reduce this to save space
67 #else // iPhone
68 #define HRTF_BLOCK_SIZE 256 /// run with smaller I/O blocks
69 #define HRIR_SIZE 1024 /// reduce this to save space
70 #endif
71
72 #define FLIST_NAME "files.txt" ///< name of file list file
73 #define DEFAULT_HRTF_FOLDER "IRCAM_HRTF/" ///< where are the HRTFs under the CSL_Data folder?
74
75 #ifdef USE_CASND
76 #define HRTF_RESOURCE "1047" ///< Default HRTF resource name for iPhone
77 #else
78 #define HRTF_RESOURCE "IRC_1047_R" ///< What's the default HRTF folder under data?
79 #endif
80
81 // complex multiply-accumulate macro; uses cx_r/i marcos
82
83 //#define cmac(in1, in2, out) \
84 // cx_r(out) += (cx_r(in1) * cx_r(in2)) - (cx_i(in1) * cx_i(in2)); \
85 // cx_i(out) += (cx_r(in1) * cx_i(in2)) + (cx_i(in1) * cx_r(in2))
86
87 // this way assumes SampleComplex is sample[2]
88
89 #define cmac(in1, in2, out) \
90 out[0] += in1[0] * in2[0] - in1[1] * in2[1]; \
91 out[1] += in1[0] * in2[1] + in1[1] * in2[0];
92
93 namespace csl {
94
95 /// HRTF: holds the data that corresponds to an HRTF for a single position.
96 /// It has a list of complex buffers for the FFTs of the HRIR,
97 /// typically 16 blocks of 512 each for an 8k HRTF.
98 /// This version knows how to parse the IRCAM hrtfs sets
99 /// Subclasses could load different HRTF sets (e.g., CIPIC).
100
101 class HRTF {
102 public: /// HRTF constructor allocates memory for the HRTF data and then
103 /// reads the HRIR file and performs the block-wise FFT
104 HRTF(); ///< generic constructor allocates all data
105 HRTF(char * fname, FFTWrapper & fft); ///< load an HRIR file and do FFTs
106 ~HRTF();
107
108 void dump(); ///< Prints the position that corresponds to this HRTF
109 unsigned size(); ///< returns the size on bytes of the receiver's storage
110
111 CPoint mPosition; ///< The Position at which the HRIR was recorded
112 SampleComplexVector *mHrtfL, *mHrtfR; ///< 2 arrays of arrays of mNumFFTBlocks * complex[513]:
113 /// the HRTF data in blocks of complex # for stereo
114 unsigned mNumFFTBlocks; ///< # of blocks (16)
115 };
116
117 typedef vector <HRTF *> HRTFVector;
118
119
120 /// HRTFDatabase: has a vector of HRTFs and can access them by position -- hrtfAt(CPoint)
121 /// -- or by index -- hrtfAt(unsigned).
122 /// Implemented as a Singleton because it's large (typ 188 HRTFs, 25 MB).
123 /// Create it with a folder/resource name, it reads "files.txt" for a list of HRIR files to load.
124 /// This has a number of file/folder/DB IO methods for load/store of bulk HRTF
125 /// data sets in IRCAM format and CSL's pre-processed HRTF.dat files.
126 ///
127
128 class HRTFDatabase {
129 public:
130 ~HRTFDatabase() { };
131
132 static HRTFDatabase * Database(); ///< accessor for the singleton instance
133 static void Destroy(); ///< free the instance
134 static void Reload(char * folder); ///< load the singleton from the given data folder
135 static void convertDB(const char *listname) throw (CException); ///< bulk-convert DBs
136
137 unsigned numHRTFs(); ///< Total number of HRTFs loaded into the database.
138 unsigned windowSize(); ///< The size of the analysis window (in samples).
139 unsigned hrtfLength(); ///< The length (in samples) of the Transfer Function buffer.
140 unsigned hrirLength(); ///< The length (in samples) of the impulse responses loaded.
141 unsigned numBlocks(); ///< The length (in windows) of the impulse responses loaded.
142
143 unsigned hrtfAt(CPoint srcPos); ///< answer the index of the HRTF nearest the given point
144 HRTF * hrtfAt(unsigned index); ///< answer an HRTF* by index
145
146 void dump(bool verbose = false); ///< Print all the HRTFs in the database.
147 unsigned size(); ///< returns the size on bytes of the receiver's storage
148
149 ///< dump the DB as a single binary file
150 void storeToDB(const char *filename,const char *same) throw (CException);
151
152 protected:
153 HRTFDatabase(const char * folder); ///< constructor that loads from a folder (protected)
154 // HRTFDatabase(HRTFVector hrtfs);
155 /// load a set of HRTFs from a folder or a file list file
156 void loadFromFolder (const char *folder) throw (CException);
157 void loadFromFile(const char *filename) throw (CException);
158 void loadFromDB (const char *dbName) throw (CException);
159
160 HRTFVector mHRTFVector; ///< vector of the HRTFs that constitute the database
161
162 unsigned mWindowSize; ///< FFT sizes (1024)
163 unsigned mHRTFLength; ///< 513
164 unsigned mHRIRLength; ///< The length of the Head Related Impulse Response (8192)
165
166 static HRTFDatabase* mDatabase; ///< The protected single instance of the HRTF Database
167 };
168
169 } // end namespace
170
171 #endif