Allow loading the entire audio file at vsjack_open() time,
get the actual oversampling, to allocate the sample space.
This commit is contained in:
parent
dbb81ae1e7
commit
6e9e5f7d80
|
|
@ -13,13 +13,14 @@
|
|||
#define VS_RESAMPLING_CHUNK 1024
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "vsjack.h"
|
||||
|
||||
extern char* inp_pathresolve(const char* name);
|
||||
|
||||
#define MAX_D 6
|
||||
static char* (sources[MAX_D]);
|
||||
|
||||
static SNDFILE* m_sndfile[MAX_D];
|
||||
static int m_channel[MAX_D]; //< channel to be used in src-file
|
||||
static int m_channels[MAX_D]; //< number of channles in src-file
|
||||
static uint32_t m_samplerate[MAX_D]; //< samplerate of source
|
||||
static uint32_t m_frames[MAX_D]; //< duration of source in frames
|
||||
|
|
@ -29,8 +30,7 @@ static float* (interleaved[MAX_D]); //< internal soundfile buffer
|
|||
|
||||
#ifdef HAVE_SRC
|
||||
#include <samplerate.h>
|
||||
static double src_ratio = 64.0;
|
||||
#define SRC_RATIO (src_ratio)
|
||||
static double src_ratio[MAX_D];
|
||||
static SRC_STATE* rabbit[MAX_D];
|
||||
static int rabbit_err[MAX_D];
|
||||
static float* (resampled[MAX_D]); //< internal soundfile buffer
|
||||
|
|
@ -38,7 +38,7 @@ static uint32_t input_frames_used[MAX_D];
|
|||
static uint32_t output_frames_generated[MAX_D];
|
||||
#endif
|
||||
|
||||
void vsjack_initialize(void) {
|
||||
static void vsjack_initialize(void) {
|
||||
int d;
|
||||
for (d = 0; d < MAX_D; d++) {
|
||||
m_sndfile[d] = NULL;
|
||||
|
|
@ -46,19 +46,16 @@ void vsjack_initialize(void) {
|
|||
#ifdef HAVE_SRC
|
||||
resampled[d] = NULL;
|
||||
#endif
|
||||
sources[d] = NULL;
|
||||
}
|
||||
sources[0] = strdup("/tmp/test.wav");
|
||||
sources[1] = strdup("/tmp/test1.wav");
|
||||
}
|
||||
|
||||
void realloc_sf(int d, uint32_t buffersize) {
|
||||
static void realloc_sf(int d, uint32_t buffersize) {
|
||||
if (interleaved[d]) free(interleaved[d]);
|
||||
interleaved[d] = (float*)calloc(m_channels[d] * buffersize, sizeof(float));
|
||||
}
|
||||
|
||||
#ifdef HAVE_SRC
|
||||
void realloc_src(int d, uint32_t buffersize) {
|
||||
static void realloc_src(int d, uint32_t buffersize) {
|
||||
if (resampled[d]) free(resampled[d]);
|
||||
resampled[d] = (float*)calloc(m_channels[d] * buffersize, sizeof(float));
|
||||
}
|
||||
|
|
@ -75,8 +72,8 @@ void closefile_sf(int d) {
|
|||
}
|
||||
#endif
|
||||
|
||||
int openfile_sf(int d, char* filename) {
|
||||
uint32_t nframes;
|
||||
static int openfile_sf(int d, char* filename, uint32_t channel, double oversampling) {
|
||||
int nframes;
|
||||
SF_INFO sfinfo;
|
||||
if (!m_sndfile[d])
|
||||
sf_close(m_sndfile[d]);
|
||||
|
|
@ -102,17 +99,22 @@ int openfile_sf(int d, char* filename) {
|
|||
return (-1);
|
||||
}
|
||||
nframes = sfinfo.frames;
|
||||
if (channel >= sfinfo.channels) {
|
||||
fprintf(stderr, "Error: Audio file does not have channel %d (0-%d)\n", channel, sfinfo.channels-1);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
m_channel[d] = channel;
|
||||
m_channels[d] = sfinfo.channels;
|
||||
m_samplerate[d] = sfinfo.samplerate;
|
||||
m_frames[d] = nframes;
|
||||
realloc_sf(d, nframes);
|
||||
#ifdef HAVE_SRC
|
||||
SRC_DATA src_data;
|
||||
|
||||
realloc_src(d, nframes * SRC_RATIO);
|
||||
src_ratio[d] = oversampling;
|
||||
realloc_src(d, nframes * oversampling);
|
||||
rabbit[d] = src_new(SRC_SINC_BEST_QUALITY, m_channels[d], &(rabbit_err[d]));
|
||||
src_set_ratio(rabbit[d], SRC_RATIO);
|
||||
src_set_ratio(rabbit[d], oversampling);
|
||||
src_reset(rabbit[d]);
|
||||
output_frames_generated[d] = 0;
|
||||
input_frames_used[d] = 0;
|
||||
|
|
@ -127,7 +129,8 @@ int openfile_sf(int d, char* filename) {
|
|||
return (0);
|
||||
}
|
||||
|
||||
double get_value(int d, double time, int channel) {
|
||||
static double get_value(int d, double time) {
|
||||
uint32_t channel = m_channel[d];
|
||||
uint32_t nframes = m_frames[d];
|
||||
double sample_fp = time * ((double)m_samplerate[d]);
|
||||
uint32_t sample = (uint32_t)floor(sample_fp);
|
||||
|
|
@ -135,6 +138,7 @@ double get_value(int d, double time, int channel) {
|
|||
if (sample >= nframes) return (0.0);
|
||||
|
||||
#ifdef HAVE_SRC
|
||||
double SRC_RATIO = src_ratio[d];
|
||||
sample_fp *= SRC_RATIO;
|
||||
sample = (uint32_t)floor(sample_fp);
|
||||
|
||||
|
|
@ -201,32 +205,24 @@ double get_value(int d, double time, int channel) {
|
|||
* "public" functions
|
||||
*/
|
||||
|
||||
double vsjack_get_value(int d, double time, double time_offset, int channel, double oversampling) {
|
||||
double vsjack_get_value(int d, double time, double time_offset) {
|
||||
assert(d >= 0 && d < MAX_D);
|
||||
if (m_sndfile[d] == NULL) return (0.0); // FIXME
|
||||
if (oversampling > 0) src_ratio = oversampling;
|
||||
|
||||
double value = get_value(d, time + time_offset, channel);
|
||||
double value = get_value(d, time + time_offset);
|
||||
return (value);
|
||||
}
|
||||
|
||||
void vsjack_set_file(int d, char* fn) {
|
||||
assert(d >= 0 && d < MAX_D);
|
||||
if (sources[d] != NULL) free(sources[d]);
|
||||
sources[d] = strdup(fn);
|
||||
}
|
||||
|
||||
int vsjack_open(int d) {
|
||||
int vsjack_open(int d, char *file, int channel, double oversampling) {
|
||||
static int initialized = 0;
|
||||
if (!initialized) {
|
||||
initialized = 1;
|
||||
vsjack_initialize();
|
||||
}
|
||||
if (d == -1) return -1;// initialize only
|
||||
assert(d >= 0 && d < MAX_D);
|
||||
assert(sources[d] != NULL);
|
||||
if (openfile_sf(d, sources[d])) {
|
||||
fprintf(stderr, "Error: Could not open or read '%s'\n", sources[d]);
|
||||
|
||||
if (openfile_sf(d, file, channel, oversampling)) {
|
||||
fprintf(stderr, "Error: Could not open or read '%s'\n", file);
|
||||
controlled_exit(1);
|
||||
}
|
||||
return (d);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
double vsjack_get_value (int, double, double, int, double);
|
||||
int vsjack_open (int);
|
||||
void vsjack_set_file (int, char*);
|
||||
double vsjack_get_value (int, double time, double time_offset);
|
||||
int vsjack_open (int, char *file, int channel, double oversampling);
|
||||
|
|
|
|||
|
|
@ -425,7 +425,7 @@ VNoi3 3 0 DC 0 TRNOISE(0 0 0 0 15m 22u 50u) : generate RTS noise
|
|||
break;
|
||||
|
||||
case SOUND: {
|
||||
value = here->VSRCcoeffs[2] * vsjack_get_value((int)here->VSRCcoeffs[0], time, here->VSRCcoeffs[3], (int)rint(here->VSRCcoeffs[4]), rint(here->VSRCcoeffs[5]));
|
||||
value = here->VSRCcoeffs[2] * vsjack_get_value((int)here->VSRCcoeffs[0], time, here->VSRCcoeffs[3]);
|
||||
value += here->VSRCcoeffs[1];
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -295,18 +295,25 @@ VSRCparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
|
|||
break;
|
||||
|
||||
case VSRC_SOUND: {
|
||||
int id, channel;
|
||||
double oversampling;
|
||||
here->VSRCfunctionType = SOUND;
|
||||
here->VSRCfuncTGiven = TRUE;
|
||||
copy_coeffs(here, value);
|
||||
here->VSRCcoeffsGiven = TRUE;
|
||||
vsjack_open(-1); // initialize
|
||||
if (jfile) {
|
||||
vsjack_set_file((int)rint(here->VSRCcoeffs[0]), jfile);
|
||||
tfree(jfile);
|
||||
if (!jfile) {
|
||||
fprintf(stderr, "Warning! Need filename for sound input");
|
||||
return(E_BADPARM);
|
||||
}
|
||||
if (value->v.numValue != 6)
|
||||
if (value->v.numValue != 6) {
|
||||
fprintf(stderr, "Warning! invalid jack args: %i\nFormat: jack(id v_off v_mult t_off channel oversampling)", value->v.numValue);
|
||||
vsjack_open((int)rint(here->VSRCcoeffs[0]));
|
||||
return (E_BADPARM);
|
||||
}
|
||||
id = (int)rint(here->VSRCcoeffs[0]);
|
||||
channel = (int)rint(here->VSRCcoeffs[4]);
|
||||
oversampling = here->VSRCcoeffs[5];
|
||||
vsjack_open(id, jfile, channel, oversampling);
|
||||
tfree(jfile);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue