From 45dfb5debd4a0d0bc79ad8b6691576e8462d1396 Mon Sep 17 00:00:00 2001 From: David Doukhan Date: Mon, 7 Feb 2011 13:09:27 +0000 Subject: cw_binaural~ code and examples! Makefile still missing svn path=/trunk/externals/ddoukhan/cw_binaural~/; revision=14855 --- src/raw_wav_hrtfcont.cpp | 178 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 src/raw_wav_hrtfcont.cpp (limited to 'src/raw_wav_hrtfcont.cpp') diff --git a/src/raw_wav_hrtfcont.cpp b/src/raw_wav_hrtfcont.cpp new file mode 100644 index 0000000..52bf82b --- /dev/null +++ b/src/raw_wav_hrtfcont.cpp @@ -0,0 +1,178 @@ +/* + cw_binaural~: a binaural synthesis external for pure data + by David Doukhan - david.doukhan@gmail.com - http://www.limsi.fr/Individu/doukhan + and Anne Sedes - sedes.anne@gmail.com + Copyright (C) 2009-2011 David Doukhan and Anne Sedes + + For more details, see CW_binaural~, a binaural synthesis external for Pure Data + David Doukhan and Anne Sedes, PDCON09 + + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#include +#include +#include +#include +#include +#include "raw_wav_hrtfcont.hpp" +#include "logstring.hpp" + + + +void RawWavHrtfCont::set_ir_buffer_from_path(ir_buffer& irb, string path) +{ + SF_INFO sfinfo; + SNDFILE* sndfd; + + // slog << "Trying " << path << std::endl; + //irb.fname = path.c_str(); + + // opening the sound file + sfinfo.format = 0; + sndfd = sf_open(path.c_str(), SFM_READ, &sfinfo); + if (!sndfd) + { + slog << "failed to open " << path << endl; + throw 0; + } + + //slog << sfinfo.channels << endl; + if (sfinfo.channels != 2) + { + slog << path << " has " << sfinfo.channels << " channels instead of 2!" << endl; + throw 0; + } + assert(sfinfo.samplerate == 44100); + + //slog << "frames" << sfinfo.frames << endl; + const size_t wav_length = sfinfo.frames;// / 2; + //slog << "ir length before" << _ir_length << endl; + if (!_ir_length) + // we're extrating the first impulse response + // all other impulse response extrated + // must have the same length + _ir_length = wav_length; + //slog << "ir length" << _ir_length << endl; + + // if the considered file is empty + // or if its size is different from previously + // extracted impulse response files + assert(wav_length && (wav_length == _ir_length)); + + float* wavdata = new float[sfinfo.frames*2]; + sf_read_float(sndfd, wavdata, sfinfo.frames*2); + + irb.lbuf = new float[wav_length]; + irb.rbuf = new float[wav_length]; + + + for (size_t i = 0; i < wav_length; ++i) + { + irb.lbuf[i] = wavdata[i*2]; + irb.rbuf[i] = wavdata[i*2+1]; + } + + delete [] wavdata; + sf_close(sndfd); +} + +// constructor should parse the directory +// deduce the how many different azimuths +// and elevations are present, according +// to a given regexp +// => intermediate list structure +// then use a faster structure to store +// the extracted wavs!!! +// FIXME: check the map size is != 0 +RawWavHrtfCont::RawWavHrtfCont(const ir_key& k): + HrtfCont(k) +{ + // regex vars + int re_status; + regex_t re; + regmatch_t pmatch[3]; + // directory parsing vars + DIR *dp; + struct dirent *dirp; + // other + float az, elev; + + _ir_length = 0; + + // slog << "Raw Wav HRTF CONT " << k.iir_regex << endl; + // compile the regex + if (regcomp(&re, k.iir_regex.c_str(), REG_EXTENDED|REG_ICASE)) + { + slog << "regex: " << k.iir_regex << " is not supported!" << endl; + throw 0; + } + + // test existence of directory supposed to store hrtf impulse responses + if((dp = opendir(k.path.c_str())) == NULL) + { + slog << "directory " << k.path << " does not exist!" << endl; + throw 0; + } + + // extract wav files matching the regex + // contained in path + while ((dirp = readdir(dp))) + //{ slog << dirp->d_name << endl; + if (!regexec(&re, dirp->d_name, 3, pmatch, REG_NOTBOL|REG_NOTEOL)) + { + //slog << "match!" << endl; + string dirname(dirp->d_name); + string group0 = dirname.substr(pmatch[1].rm_so, pmatch[1].rm_eo); + string group1 = dirname.substr(pmatch[2].rm_so, pmatch[2].rm_eo); + + if (k.is_azimuth_first) + { + az = atof(group0.c_str()); + elev = atof(group1.c_str()); + } + else + { + az = atof(group1.c_str()); + elev = atof(group0.c_str()); + } + // slog << "(az,elev)=(" << az << ", " << elev << ") for file " << dirname << endl; + + if (k.vertical_polar_coords) + { + normalize_vertpolar_coords(az, elev); + set_ir_buffer_from_path(_m[elev][az], k.path + "/" + dirname); + } + else + { + // TO BE IMPROVED + if (elev > 180) + elev -= 360; + set_ir_buffer_from_path(_m[az][elev], k.path + "/" + dirname); + } + + } + + // close the directory structure + closedir(dp); + + // free the regex + regfree(&re); + + //slog << "END OF RAW WAV HRTF CONT" << endl; +} + + -- cgit v1.2.1