45 void Audiofile::reset(
void) {
60 if ((_sndfile = sf_open(name.c_str(), SFM_READ, &I)) == 0)
return ERR_OPEN;
62 switch (I.format & SF_FORMAT_TYPEMASK) {
70 #ifdef SFC_WAVEX_GET_AMBISONIC 71 if (sf_command(_sndfile, SFC_WAVEX_GET_AMBISONIC, 0, 0) == SF_AMBISONIC_B_FORMAT)
78 switch (I.format & SF_FORMAT_SUBMASK) {
79 case SF_FORMAT_PCM_16:
82 case SF_FORMAT_PCM_24:
85 case SF_FORMAT_PCM_32:
102 if (_sndfile) sf_close(_sndfile);
110 if (sf_seek(_sndfile, posit, SEEK_SET) != posit)
return ERR_SEEK;
116 return sf_readf_float(_sndfile, data, frames);
119 bool read_audio(
const std::string& filename,
unsigned int *audio_size,
int *audio_chan,
120 int *audio_type,
int *audio_form,
int *audio_rate,
float **buffer) {
123 gx_print_error(
"jconvolver",
"Unable to open '" + filename +
"'");
124 *audio_size = *audio_chan = *audio_type = *audio_form = *audio_rate = 0;
128 *audio_size = audio.
size();
129 *audio_chan = audio.
chan();
130 *audio_type = audio.
type();
131 *audio_form = audio.
form();
132 *audio_rate = audio.
rate();
133 const unsigned int limit = 2000000;
134 if (*audio_size > limit) {
136 "jconvolver", (boost::format(_(
"too many samples (%1%), truncated to %2%"))
137 % *audio_size % limit).str());
140 if (*audio_size * *audio_chan == 0) {
142 *audio_size = *audio_chan = *audio_type = *audio_form = *audio_rate = 0;
146 *buffer =
new float[*audio_size * *audio_chan];
147 if (audio.
read(*buffer, *audio_size) !=
static_cast<int>(*audio_size)) {
150 *audio_size = *audio_chan = *audio_type = *audio_form = *audio_rate = 0;
168 unsigned int audio_size,
unsigned int& count,
unsigned int& offset,
169 unsigned int& delay,
unsigned int& ldelay,
unsigned int& length,
170 unsigned int&
size,
unsigned int& bufsize) {
172 if (bufsize < count) {
175 if (bufsize < Convproc::MINPART) {
176 bufsize = Convproc::MINPART;
178 if (offset > audio_size) {
182 if (offset + length > audio_size) {
185 (boost::format(
"length adjusted (%1% + %2% > %3%")
186 % offset % length % audio_size).str());
187 length = audio_size - offset;
190 length = audio_size - offset;
192 size =
max(delay, ldelay) + offset + length;
200 if (offset > size -
max(delay, ldelay)) {
201 offset = size -
max(delay, ldelay);
203 if (length > size -
max(delay, ldelay) - offset) {
204 length = size -
max(delay, ldelay) - offset;
208 length = size -
max(delay, ldelay) - offset;
214 int rc = start_process(priority, policy);
224 if (state() == Convproc::ST_WAIT) {
230 }
else if (state() == ST_STOP) {
264 bool GxConvolver::read_sndfile(
265 Audiofile& audio,
int nchan,
int samplerate,
const float *gain,
266 unsigned int *delay,
unsigned int offset,
unsigned int length,
267 const Gainline& points) {
274 const unsigned int BSIZE = 0x8000;
277 if (offset && audio.
seek(offset)) {
283 buff =
new float[BSIZE * audio.
chan()];
289 if (samplerate != audio.
rate()) {
291 "convolver", Glib::ustring::compose(
292 _(
"resampling from %1 to %2"), audio.
rate(), samplerate));
293 if (!resamp.setup(audio.
rate(), samplerate, audio.
chan())) {
299 rbuff =
new float[resamp.get_max_out_size(BSIZE)*audio.
chan()];
310 unsigned int idx = 0;
311 double gp = 0.0, fct = 0.0;
313 while ((
unsigned int)points[idx].i < offset) {
315 assert(idx < points.size());
317 if ((
unsigned int)points[idx].i > offset) {
319 compute_interpolation(fct, gp, idx, points, offset);
325 nfram = (length > BSIZE) ? BSIZE : length;
327 nfram = audio.
read(buff, nfram);
335 for (
int ix = 0; ix < nfram; ix++) {
336 if (idx+1 < points.size() && (
unsigned int)points[idx].i == offset + ix) {
337 compute_interpolation(fct, gp, idx, points, offset);
340 for (
int ichan = 0; ichan <
min(audio.
chan(), nchan); ichan++) {
341 buff[ix*audio.
chan()+ichan] *= pow(10, gp + ix*fct) * gain[ichan];
348 cnt = resamp.process(nfram, buff, rbuff);
352 cnt = resamp.flush(rbuff);
360 for (
int ichan = 0; ichan < nchan; ichan++) {
362 if (ichan >= audio.
chan()) {
363 rc = impdata_copy(0, 0, ichan, ichan);
365 rc = impdata_create(ichan, ichan, audio.
chan(), bufp + ichan,
366 delay[ichan], delay[ichan] + cnt);
389 string fname,
float gain,
float lgain,
390 unsigned int delay,
unsigned int ldelay,
unsigned int offset,
391 unsigned int length,
unsigned int size,
unsigned int bufsize,
392 const Gainline& points) {
399 gx_print_error(
"convolver", Glib::ustring::compose(
"Unable to open '%1'", fname));
402 if (audio.
chan() > 2) {
405 Glib::ustring::compose(
"only taking first 2 of %1 channels in impulse response", audio.
chan()));
408 adjust_values(audio.
size(), buffersize, offset, delay, ldelay, length,
size, bufsize);
410 if (samplerate != static_cast<unsigned int>(audio.
rate())) {
411 float f = float(samplerate) / audio.
rate();
412 size = round(size * f) + 2;
413 delay = round(delay * f);
414 ldelay = round(ldelay * f);
416 if (Convproc::configure(2, 2, size, buffersize, bufsize, Convproc::MAXPART)) {
421 float gain_a[2] = {gain, lgain};
422 unsigned int delay_a[2] = {delay, ldelay};
423 return read_sndfile(audio, 2, samplerate, gain_a, delay_a, offset, length, points);
427 float *output1,
float *output2) {
428 if (state() != Convproc::ST_PROC) {
429 if (input1 != output1) {
430 memcpy(output1, input1, count *
sizeof(
float));
432 if (input2 != output2) {
433 memcpy(output2, input2, count *
sizeof(
float));
435 if (state() == Convproc::ST_WAIT) {
438 if (state() == ST_STOP) {
443 memcpy(inpdata(0), input1, count *
sizeof(
float));
444 memcpy(inpdata(1), input2, count *
sizeof(
float));
446 int flags = process(sync);
448 memcpy(output1, outdata(0), count *
sizeof(
float));
449 memcpy(output2, outdata(1), count *
sizeof(
float));
454 unsigned int length,
unsigned int size,
unsigned int bufsize,
455 const Gainline& points) {
462 gx_print_error(
"convolver", Glib::ustring::compose(
"Unable to open '%1'", fname));
465 if (audio.
chan() > 1) {
468 Glib::ustring::compose(
"only taking first channel of %1 channels in impulse response", audio.
chan()));
471 unsigned int ldelay = delay;
472 adjust_values(audio.
size(), buffersize, offset, delay, ldelay, length,
size, bufsize);
474 if (samplerate != static_cast<unsigned int>(audio.
rate())) {
475 float f = float(samplerate) / audio.
rate();
476 size = round(size * f) + 2;
477 delay = round(delay * f);
479 if (Convproc::configure(1, 1, size, buffersize, bufsize, Convproc::MAXPART)) {
484 float gain_a[1] = {gain};
485 unsigned int delay_a[1] = {delay};
486 return read_sndfile(audio, 1, samplerate, gain_a, delay_a, offset, length, points);
490 if (state() != Convproc::ST_PROC) {
491 if (input != output) {
492 memcpy(output, input, count *
sizeof(
float));
494 if (state() == Convproc::ST_WAIT) {
497 if (state() == ST_STOP) {
502 memcpy(inpdata(0), input, count *
sizeof(
float));
504 int flags = process(sync);
506 memcpy(output, outdata(0), count *
sizeof(
float));
521 float *
resample(
int *count,
float *impresp,
unsigned int imprate,
unsigned int samplerate) {
522 if (imprate != samplerate) {
523 vec = resamp.
process(imprate, *count, impresp, samplerate, count);
525 boost::format msg = boost::format(
"failed to resample %1% -> %2%") % imprate % samplerate;
547 impresp = r.
resample(&count, impresp, imprate, samplerate);
552 unsigned int bufsize = buffersize;
553 if (bufsize < Convproc::MINPART) {
554 bufsize = Convproc::MINPART;
556 if (Convproc::configure(1, 1, count, buffersize,
557 bufsize, Convproc::MAXPART)) {
561 if (impdata_create(0, 0, 1, impresp, 0, count)) {
570 impresp = r.
resample(&count, impresp, imprate, samplerate);
574 if (impdata_update(0, 0, 1, impresp, 0, count)) {
582 if (state() != Convproc::ST_PROC) {
583 if (input != output) {
584 memcpy(output, input, count *
sizeof(
float));
586 if (state() == Convproc::ST_WAIT) {
589 if (state() == ST_STOP) {
594 memcpy(inpdata(0), input, count *
sizeof(
float));
596 int flags = process(sync);
598 memcpy(output, outdata(0), count *
sizeof(
float));
608 impresp = r.
resample(&count, impresp, imprate, samplerate);
611 printf(
"no impresp\n");
615 unsigned int bufsize = buffersize;
616 if (bufsize < Convproc::MINPART)
618 bufsize = Convproc::MINPART;
620 if (Convproc::configure(2, 2, count, buffersize,
623 printf(
"no configure\n");
626 if (impdata_create(0, 0, 1, impresp, 0, count) & impdata_create(1, 1, 1, impresp, 0, count))
628 printf(
"no impdata_create()\n");
639 impresp = r.
resample(&count, impresp, imprate, samplerate);
644 if (impdata_update(0, 0, 1, impresp, 0, count) & impdata_update(1, 1, 1, impresp, 0, count))
654 if (state() != Convproc::ST_PROC)
659 memcpy(output, input, count *
sizeof(
float));
660 memcpy(output1, input1, count *
sizeof(
float));
662 if (state() == Convproc::ST_WAIT)
667 if (state() == ST_STOP)
675 if (static_cast<unsigned int>(count) == buffersize)
677 memcpy(inpdata(0), input, count *
sizeof(
float));
678 memcpy(inpdata(1), input1, count *
sizeof(
float));
680 flags = process(sync);
682 memcpy(output, outdata(0), count *
sizeof(
float));
683 memcpy(output1, outdata(1), count *
sizeof(
float));
685 float *in, *in1, *out, *out1;
692 for(
int i = 0; i<count; ++i){
695 if(++b == buffersize) {
698 for(
unsigned int d = 0; d<buffersize; ++d) {
699 output[d*c] = out[d];
700 output1[d*c] = out1[d];
void gx_print_info(const char *, const std::string &)
bool update_stereo(int count, float *impresp, unsigned int imprate)
bool start(int policy, int priority)
bool configure(int count, float *impresp, unsigned int imprate)
bool compute(int count, float *input, float *output)
int open_read(string name)
bool read_audio(const std::string &filename, unsigned int *audio_size, int *audio_chan, int *audio_type, int *audio_form, int *audio_rate, float **buffer)
float * process(int fs_inp, int ilen, float *input, int fs_outp, int *olen)
void adjust_values(unsigned int audio_size, unsigned int &count, unsigned int &offset, unsigned int &delay, unsigned int &ldelay, unsigned int &length, unsigned int &size, unsigned int &bufsize)
void gx_print_error(const char *, const std::string &)
unsigned int size(void) const
int seek(unsigned int posit)
bool compute(int count, float *input1, float *input2, float *output1, float *output2)
bool update(int count, float *impresp, unsigned int imprate)
bool configure(string fname, float gain, float lgain, unsigned int delay, unsigned int ldelay, unsigned int offset, unsigned int length, unsigned int size, unsigned int bufsize, const Gainline &gainline)
bool compute_stereo(int count, float *input, float *input1, float *output, float *output1)
void gx_print_warning(const char *, const std::string &)
bool configure_stereo(int count, float *impresp, unsigned int imprate)
float * resample(int *count, float *impresp, unsigned int imprate, unsigned int samplerate)
CheckResample(gx_resample::BufferResampler &resamp_)
int read(float *data, unsigned int frames)