/*
cw_binaural~: a binaural synthesis external for pure data
by David Doukhan - david.doukhan@gmail.com - http://perso.limsi.fr/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;
}