@@ 580,7 580,7 @@ int lpipc_destroyvalue(char * path) {
* BUFFER TOOLS
* ************/
int lpsampler_get_path(char * name, char * path) {
- snprintf(path, PATH_MAX, "/astrid-sampler-%s", name);
+ snprintf(path, PATH_MAX, "/lpsamp-%s", name);
//syslog(LOG_ERR, "name=%s path=%s PATH_MAX=%d\n", name, path, PATH_MAX);
return 0;
}
@@ 2031,6 2031,8 @@ int encode_update_message_param_int32(uint16_t id, char * valstr, lpmsg_t * msg)
// Takes the cmd on the instrument and runs each param through the
// instrument's param update callback.
+// TODO think about handling large / special values, like buffers...
+// payload could be the shm ID like render complete messages...?
int process_param_updates(lpinstrument_t * instrument) {
char cmdline[LPMAXMSG] = {0};
char * paramline;
@@ 2038,6 2040,9 @@ int process_param_updates(lpinstrument_t * instrument) {
char * valtoken;
char * cmdline_save;
char * paramline_save;
+ uint32_t key_hash = 0;
+ float val_f = 0;
+ int32_t val_i32 = 0;
memcpy(cmdline, instrument->msg.msg, LPMAXMSG);
@@ 2048,8 2053,37 @@ int process_param_updates(lpinstrument_t * instrument) {
valtoken = strtok_r(NULL, "=", ¶mline_save);
if(valtoken != NULL) {
syslog(LOG_DEBUG, "UPDATE Key: %s, Value: %s\n", keytoken, valtoken);
- // TODO think about handling large / special values, like buffers...
- // payload could be the shm ID like render complete messages...?
+ // first process built-in param updates
+ /*
+ * name-volume: float - post-resampler volume (1.0)
+ * name-resampler-rec: int - resampler record toggle (1)
+ * name-resampler-dub: int - resampler overdub toggle (0)
+ * name-resampler-pos: float - resampler write pos from 0 to 1 in loop bounds (0)
+ * name-resampler-clear: int - value ignored, clear the buffer
+ * name-resampler-feedback: float - feedback amount from 0 to 1 (0.25)
+ * */
+ key_hash = lphashstr(keytoken);
+ if(key_hash == instrument->param_volume) {
+ extract_float_from_token(valtoken, &val_f);
+ astrid_instrument_set_param_float(instrument, instrument->param_volume, val_f);
+ } else if(key_hash == instrument->resampler_param_rec) {
+ extract_int32_from_token(valtoken, &val_i32);
+ astrid_instrument_set_param_int32(instrument, instrument->resampler_param_rec, val_i32);
+ } else if(key_hash == instrument->resampler_param_dub) {
+ extract_int32_from_token(valtoken, &val_i32);
+ astrid_instrument_set_param_int32(instrument, instrument->resampler_param_dub, val_i32);
+ } else if(key_hash == instrument->resampler_param_pos) {
+ extract_float_from_token(valtoken, &val_f);
+ astrid_instrument_set_param_float(instrument, instrument->resampler_param_pos, val_f);
+ } else if(key_hash == instrument->resampler_param_clear) {
+ astrid_instrument_set_param_int32(instrument, instrument->resampler_param_clear, 1);
+ } else if(key_hash == instrument->resampler_param_feedback) {
+ extract_float_from_token(valtoken, &val_f);
+ astrid_instrument_set_param_float(instrument, instrument->resampler_param_feedback, val_f);
+ }
+
+ // process the update callback if there is one
+ if(instrument->update == NULL) continue;
if(instrument->update(instrument, keytoken, valtoken) < 0) {
syslog(LOG_ERR, "process_param_updates: failed to pass param (%s=%s) to update callback.\n", keytoken, valtoken);
}
@@ 2155,6 2189,8 @@ int parse_message_from_args(int argc, int arg_offset, char * argv[], lpmsg_t * m
strncpy(msg->instrument_name, instrument_name, instrument_name_length);
strncpy(msg->msg, message_params, bytesread);
+ printf("msgtype=%c instrument_name=%s message_params=%s\n", msgtype, instrument_name, message_params);
+
if(prepare_and_send_instrument_message(msg, msgtype) < 0) {
syslog(LOG_ERR, "Could not prepare message of type %c: (%d) %s\n", msgtype, errno, strerror(errno));
return -1;
@@ 2683,6 2719,7 @@ int astrid_instrument_jack_callback(jack_nframes_t nframes, void * arg) {
lpinstrument_t * instrument = (lpinstrument_t *)arg;
float * output_channels[instrument->output_channels];
float * input_channels[instrument->input_channels];
+ lpfloat_t volume;
size_t i;
int c;
@@ 2734,21 2771,24 @@ int astrid_instrument_jack_callback(jack_nframes_t nframes, void * arg) {
}
/* write the output block into the resampler ringbuffer */
- syslog(LOG_DEBUG, "Writing output to resampler ringbuffer. %s\n", instrument->name);
- if(lpsampler_write_ringbuffer_block(instrument->resamplername, instrument->resamplerbuf, output_channels, instrument->output_channels, nframes) < 0) {
- syslog(LOG_ERR, "Error writing into resampler ringbuf\n");
- return 0;
+ if(astrid_instrument_get_param_int32(instrument, instrument->resampler_param_rec, 1) == 1) {
+ /* TODO: support overdub with feedback, toggling rec on/off */
+ syslog(LOG_DEBUG, "Writing output to resampler ringbuffer. %s\n", instrument->name);
+ if(lpsampler_write_ringbuffer_block(instrument->resamplername, instrument->resamplerbuf, output_channels, instrument->output_channels, nframes) < 0) {
+ syslog(LOG_ERR, "Error writing into resampler ringbuf\n");
+ return 0;
+ }
}
/* clamp output and apply post fader volume */
- syslog(LOG_DEBUG, "Clamping output. %s\n", instrument->name);
+ volume = astrid_instrument_get_param_float(instrument, instrument->param_volume, instrument->initial_volume);
+ syslog(LOG_DEBUG, "Clamping output w/volume %f. %s\n", volume, instrument->name);
for(c=0; c < instrument->output_channels; c++) {
for(i=0; i < (size_t)nframes; i++) {
- output_channels[c][i] = fmax(-1.f, fmin(output_channels[c][i] * instrument->volume, 1.f));
+ output_channels[c][i] = fmax(-1.f, fmin(output_channels[c][i] * volume, 1.f));
}
}
-
syslog(LOG_DEBUG, "JACK CALLBACK: Done. %s\n", instrument->name);
return 0;
}
@@ 3008,13 3048,10 @@ void * instrument_message_thread(void * arg) {
case LPMSG_UPDATE:
syslog(LOG_DEBUG, "C MSG: update\n");
- if(instrument->update == NULL) continue;
- // decode each update param and call the callback with it
if(process_param_updates(instrument) < 0) {
syslog(LOG_ERR, "Could not encode update messages...\n");
continue;
}
- //instrument->update(instrument);
break;
case LPMSG_PLAY:
@@ 3506,23 3543,20 @@ void * instrument_midi_output_thread(void * arg) {
return 0;
}
+lpinstrument_config_t astrid_instrument_init_config(char * name) {
+ lpinstrument_config_t config = {0};
+ config.name = name;
+ config.input_channels = 2;
+ config.output_channels = 2;
+ config.initial_volume = 1.f;
+ config.requested_samplerate = -1.f;
+ config.is_interactive = 1;
+ config.adc_length = 60.f;
+ config.resampler_length = 60.f;
+ return config;
+}
-lpinstrument_t * astrid_instrument_start(
- char * name,
- int input_channels,
- int output_channels,
- int ext_relay_enabled,
- double adc_length,
- double resampler_length,
- void * ctx,
- char * tty,
- char * midiin_device_name,
- char * midiout_device_name,
- int (*stream)(size_t blocksize, float ** input, float ** output, void * instrument),
- int (*renderer)(void * instrument),
- int (*update)(void * instrument, char * key, char * val),
- int (*trigger)(void * instrument)
-) {
+lpinstrument_t * astrid_instrument_start_from_config(lpinstrument_config_t config) {
lpinstrument_t * instrument;
struct sigaction shutdown_action;
jack_status_t jack_status;
@@ 3532,37 3566,39 @@ lpinstrument_t * astrid_instrument_start(
int c=0;
const char ** ports;
int port_count=0;
+ char hash_key[PATH_MAX] = {0};
instrument = (lpinstrument_t *)LPMemoryPool.alloc(1, sizeof(lpinstrument_t));
memset(instrument, 0, sizeof(lpinstrument_t));
setlogmask(LOG_UPTO(LOG_ERR));
- openlog(name, LOG_PID, LOG_USER);
- syslog(LOG_DEBUG, "starting %s instrument...\n", name);
-
- instrument->name = name;
- instrument->volume = 1.f; // TODO accept default initial volume on config
- instrument->input_channels = input_channels;
- instrument->output_channels = output_channels;
- instrument->context = ctx;
-
- instrument->stream = stream;
- instrument->renderer = renderer;
- instrument->update = update;
- instrument->trigger = trigger;
- instrument->ext_relay_enabled = ext_relay_enabled;
+ openlog(config.name, LOG_PID, LOG_USER);
+ syslog(LOG_DEBUG, "starting %s instrument...\n", config.name);
+
+ instrument->name = config.name;
+ instrument->initial_volume = config.initial_volume;
+ instrument->input_channels = config.input_channels;
+ instrument->output_channels = config.output_channels;
+ instrument->context = config.ctx;
+ instrument->is_interactive = config.is_interactive;
+
+ instrument->stream = config.stream_callback;
+ instrument->renderer = config.renderer_callback;
+ instrument->update = config.update_callback;
+ instrument->trigger = config.trigger_callback;
+ instrument->ext_relay_enabled = config.ext_relay_enabled;
instrument->is_ready = 1;
instrument->midiin_device_id = -1;
- if(midiin_device_name != NULL) {
- instrument->midiin_device_id = lpmidi_get_device_id_by_name(midiin_device_name);
- syslog(LOG_DEBUG, "Set MIDI input device ID (%d) for %s\n", instrument->midiin_device_id, midiin_device_name);
+ if(config.midiin_device_name != NULL) {
+ instrument->midiin_device_id = lpmidi_get_device_id_by_name(config.midiin_device_name);
+ syslog(LOG_DEBUG, "Set MIDI input device ID (%d) for %s\n", instrument->midiin_device_id, config.midiin_device_name);
}
instrument->midiout_device_id = -1;
- if(midiout_device_name != NULL) {
- instrument->midiout_device_id = lpmidi_get_device_id_by_name(midiout_device_name);
- syslog(LOG_DEBUG, "Set MIDI output device ID (%d) for %s\n", instrument->midiout_device_id, midiout_device_name);
+ if(config.midiout_device_name != NULL) {
+ instrument->midiout_device_id = lpmidi_get_device_id_by_name(config.midiout_device_name);
+ syslog(LOG_DEBUG, "Set MIDI output device ID (%d) for %s\n", instrument->midiout_device_id, config.midiout_device_name);
}
/* Seed the random number generator */
@@ 3575,12 3611,12 @@ lpinstrument_t * astrid_instrument_start(
astrid_instrument_is_running = &instrument->is_running;
if(sigaction(SIGINT, &shutdown_action, NULL) == -1) {
- syslog(LOG_ERR, "%s Could not init SIGINT signal handler. Error: %s\n", name, strerror(errno));
+ syslog(LOG_ERR, "%s Could not init SIGINT signal handler. Error: %s\n", instrument->name, strerror(errno));
exit(1);
}
if(sigaction(SIGTERM, &shutdown_action, NULL) == -1) {
- syslog(LOG_ERR, "%s Could not init SIGTERM signal handler. Error: %s\n", name, strerror(errno));
+ syslog(LOG_ERR, "%s Could not init SIGTERM signal handler. Error: %s\n", instrument->name, strerror(errno));
exit(1);
}
@@ 3590,8 3626,8 @@ lpinstrument_t * astrid_instrument_start(
snprintf(instrument->midiout_message_q_name, NAME_MAX, "/%s-midiout", instrument->name);
// Set the tty path
- if(tty != NULL) {
- snprintf(instrument->tty_path, NAME_MAX, "%s", tty);
+ if(config.tty != NULL) {
+ snprintf(instrument->tty_path, NAME_MAX, "%s", config.tty);
instrument->tty_is_enabled = 1;
}
@@ 3601,11 3637,11 @@ lpinstrument_t * astrid_instrument_start(
// set up the voice counter and the buffer counter
if(lpcounter_create("voiceid") < 0) {
- syslog(LOG_ERR, "%s Could not create voiceid counter. Error: %s\n", name, strerror(errno));
+ syslog(LOG_ERR, "%s Could not create voiceid counter. Error: %s\n", instrument->name, strerror(errno));
exit(1);
}
if(lpcounter_create("bufferid") < 0) {
- syslog(LOG_ERR, "%s Could not create bufferid counter. Error: %s\n", name, strerror(errno));
+ syslog(LOG_ERR, "%s Could not create bufferid counter. Error: %s\n", instrument->name, strerror(errno));
exit(1);
}
@@ 3613,18 3649,18 @@ lpinstrument_t * astrid_instrument_start(
astrid_instrument_session_open(instrument);
/* Set up JACK */
- instrument->inports = (jack_port_t **)calloc(input_channels, sizeof(jack_port_t *));
- instrument->outports = (jack_port_t **)calloc(output_channels, sizeof(jack_port_t *));
- instrument->jack_client = jack_client_open(name, jack_options, &jack_status, NULL);
+ instrument->inports = (jack_port_t **)calloc(config.input_channels, sizeof(jack_port_t *));
+ instrument->outports = (jack_port_t **)calloc(config.output_channels, sizeof(jack_port_t *));
+ instrument->jack_client = jack_client_open(config.name, jack_options, &jack_status, NULL);
syslog(LOG_DEBUG, "JACK STATUS %d\n", (int)jack_status);
if(instrument->jack_client == NULL) {
- syslog(LOG_ERR, "%s Could not open jack client. Client is NULL: %s\n", name, strerror(errno));
+ syslog(LOG_ERR, "%s Could not open jack client. Client is NULL: %s\n", instrument->name, strerror(errno));
if((jack_status & JackServerFailed) == JackServerFailed) {
- syslog(LOG_ERR, "%s Could not open jack client. Jack server failed with status %2.0x\n", name, jack_status);
+ syslog(LOG_ERR, "%s Could not open jack client. Jack server failed with status %2.0x\n", instrument->name, jack_status);
} else {
- syslog(LOG_ERR, "%s Could not open jack client. Unknown error: %s\n", name, strerror(errno));
+ syslog(LOG_ERR, "%s Could not open jack client. Unknown error: %s\n", instrument->name, strerror(errno));
}
goto astrid_instrument_shutdown_with_error;
}
@@ 3642,25 3678,25 @@ lpinstrument_t * astrid_instrument_start(
/* Set the main jack callback which always runs: maybe there is an analysis-only use to support too? */
jack_set_process_callback(instrument->jack_client, astrid_instrument_jack_callback, (void *)instrument);
- for(c=0; c < output_channels; c++) {
+ for(c=0; c < instrument->output_channels; c++) {
snprintf(outport_name, sizeof(outport_name), "out%d", c);
instrument->outports[c] = jack_port_register(instrument->jack_client, outport_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
}
- for(c=0; c < input_channels; c++) {
+ for(c=0; c < instrument->input_channels; c++) {
snprintf(inport_name, sizeof(inport_name), "in%d", c);
instrument->inports[c] = jack_port_register(instrument->jack_client, inport_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
}
/* Request some ports from jack */
- for(c=0; c < output_channels; c++) {
+ for(c=0; c < instrument->output_channels; c++) {
if(instrument->outports[c] == NULL) {
syslog(LOG_ERR, "No more JACK output ports available, shutting down...\n");
goto astrid_instrument_shutdown_with_error;
}
}
- for(c=0; c < input_channels; c++) {
+ for(c=0; c < instrument->input_channels; c++) {
if(instrument->inports[c] == NULL) {
syslog(LOG_ERR, "No more JACK input ports available, shutting down...\n");
goto astrid_instrument_shutdown_with_error;
@@ 3669,7 3705,7 @@ lpinstrument_t * astrid_instrument_start(
/* activate the jack client */
if(jack_activate(instrument->jack_client) != 0) {
- syslog(LOG_ERR, "%s Could not activate JACK client, shutting down...\n", name);
+ syslog(LOG_ERR, "%s Could not activate JACK client, shutting down...\n", instrument->name);
goto astrid_instrument_shutdown_with_error;
}
@@ 3710,22 3746,39 @@ lpinstrument_t * astrid_instrument_start(
/* Create the internal ringbuffer for sampling from the adc */
snprintf(instrument->adcname, PATH_MAX, "%s-adc", instrument->name);
- if((instrument->adcbuf = lpsampler_create(instrument->adcname, adc_length, instrument->input_channels, instrument->samplerate)) == NULL) {
+ if((instrument->adcbuf = lpsampler_create(instrument->adcname, config.adc_length, instrument->input_channels, instrument->samplerate)) == NULL) {
syslog(LOG_INFO, "Could not create instrument ADC buffer\n");
goto astrid_instrument_shutdown_with_error;
}
/* Create the internal ringbuffer for resampling */
snprintf(instrument->resamplername, PATH_MAX, "%s-resampler", instrument->name);
- if((instrument->resamplerbuf = lpsampler_create(instrument->resamplername, resampler_length, instrument->output_channels, instrument->samplerate)) == NULL) {
+ if((instrument->resamplerbuf = lpsampler_create(instrument->resamplername, config.resampler_length, instrument->output_channels, instrument->samplerate)) == NULL) {
syslog(LOG_INFO, "Could not create instrument resampler buffer\n");
goto astrid_instrument_shutdown_with_error;
}
+ /* Create (or open) mix busses if we've selected any */
+ // TODO
+
+ /* Initialize the built-in control param hashes */
+ snprintf(hash_key, PATH_MAX, "%s-volume", instrument->name);
+ instrument->param_volume = lphashstr(hash_key);
+ snprintf(hash_key, PATH_MAX, "%s-resampler-rec", instrument->name);
+ instrument->resampler_param_rec = lphashstr(hash_key);
+ snprintf(hash_key, PATH_MAX, "%s-resampler-dub", instrument->name);
+ instrument->resampler_param_dub = lphashstr(hash_key);
+ snprintf(hash_key, PATH_MAX, "%s-resampler-clear", instrument->name);
+ instrument->resampler_param_clear = lphashstr(hash_key);
+ snprintf(hash_key, PATH_MAX, "%s-resampler-pos", instrument->name);
+ instrument->resampler_param_pos = lphashstr(hash_key);
+ snprintf(hash_key, PATH_MAX, "%s-resampler-feedback", instrument->name);
+ instrument->resampler_param_feedback = lphashstr(hash_key);
+
/* Register that everything is running and ready */
instrument->is_running = 1;
- syslog(LOG_INFO, "%s is running...\n", name);
+ syslog(LOG_INFO, "%s is running...\n", instrument->name);
/* Open the message queues */
if((instrument->msgq = astrid_msgq_open(instrument->qname)) == (mqd_t) -1) {
@@ 3806,6 3859,40 @@ astrid_instrument_shutdown_with_error:
return NULL;
}
+lpinstrument_t * astrid_instrument_start(
+ char * name,
+ int input_channels,
+ int output_channels,
+ int ext_relay_enabled,
+ double adc_length,
+ double resampler_length,
+ void * ctx,
+ char * tty,
+ char * midiin_device_name,
+ char * midiout_device_name,
+ int (*stream)(size_t blocksize, float ** input, float ** output, void * instrument),
+ int (*renderer)(void * instrument),
+ int (*update)(void * instrument, char * key, char * val),
+ int (*trigger)(void * instrument)
+) {
+ syslog(LOG_WARNING, "astrid_instrument_start is deprecated.\nuse astrid_instrument_start_from_config instead.");
+ lpinstrument_config_t config = astrid_instrument_init_config(name);
+ config.input_channels = input_channels;
+ config.output_channels = output_channels;
+ config.ext_relay_enabled = ext_relay_enabled;
+ config.adc_length = adc_length;
+ config.resampler_length = resampler_length;
+ config.ctx = ctx;
+ config.tty = tty;
+ config.midiin_device_name = midiin_device_name;
+ config.midiout_device_name = midiout_device_name;
+ config.stream_callback = stream;
+ config.renderer_callback = renderer;
+ config.update_callback = update;
+ config.trigger_callback = trigger;
+ return astrid_instrument_start_from_config(config);
+}
+
int astrid_instrument_stop(lpinstrument_t * instrument) {
int c, ret;
@@ 4177,6 4264,11 @@ int astrid_instrument_tick(lpinstrument_t * instrument) {
size_t prompt_len = strlen("^_- ") + strlen(instrument->name) + strlen(": ") + 1;
char prompt[LPMAXNAME+10] = {0};
+ if(instrument->is_interactive == 0) {
+ usleep((useconds_t)500);
+ return 0;
+ }
+
snprintf(prompt, prompt_len, "^_- %s: ", instrument->name);
if(instrument->is_running == 0) return 0;
@@ 4188,8 4280,8 @@ int astrid_instrument_tick(lpinstrument_t * instrument) {
FD_ZERO(&readfds);
FD_SET(instrument->cmdstate.ifd, &readfds);
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 1000;
if((ret = select(instrument->cmdstate.ifd+1, &readfds, NULL, NULL, &timeout)) < 0) {
syslog(LOG_ERR, "astrid_instrument_tick: select error (%d) %s\n", errno, strerror(errno));
@@ 312,7 312,8 @@ cdef class SessionParamBucket:
cdef int32_t val_i32
cdef float val_f
- if key not in self.instrument.instrument_param_type_map:
+ if self.instrument.instrument_param_type_map is None or \
+ key not in self.instrument.instrument_param_type_map:
logger.warning('Unknown param "%s"' % key)
return
@@ 394,29 395,36 @@ cdef class EventContext:
channels = self.instrument.input_channels
return self.instrument.read_from_adc(length, offset=offset, channels=channels)
- def sample(self,
- str name,
- SoundBuffer snd=None,
- double length=0,
- double offset=0,
- int channels=2,
- bint overdub=False,
- bint wrap=False,
- bint overwrite=False
- ):
- # read operations
- if snd is None:
- if length <= 0 and offset == 0:
- # just read the entire sample
- return self.instrument.read_from_sampler(name)
+ def load_sample(self, str name, double length=0, double offset=0, int channels=0):
+ if length <= 0 and offset == 0:
+ # just read the entire sample
+ logger.error(f'Reading entire sample {name}')
+ return self.instrument.read_from_sampler(name)
+
+ if channels <= 0:
+ channels = self.instrument.output_channels
- # otherwise read a portion from the sample
- return self.instrument.read_block_from_sampler(name, length, offset=offset, channels=channels)
+ # otherwise read a portion from the sample
+ logger.error(f'Reading {length=} {offset=} sample {name}')
+ return self.instrument.read_block_from_sampler(name, length, offset=offset, channels=channels)
+
+ def save_sample(self, str name, SoundBuffer snd):
+ return self.instrument.save_to_sampler(name, snd)
+
+ def dub_into_sample(self, str name, SoundBuffer snd, double offset=0, bint overdub=False, bint wrap=False):
+ return self.instrument.write_block_into_sampler(name, snd, offset, overdub, wrap)
+
+ def sample(self, str name, SoundBuffer snd=None, double length=0, double offset=0, int channels=2, bint overdub=False, bint wrap=False, bint overwrite=False):
+ # FIXME: maybe get rid of this API, it's confusing
+ if snd is None:
+ return self.load_sample(name, length, offset, channels)
# write operations
if overwrite:
+ logger.error(f'Overwrite sample {name}')
return self.instrument.save_to_sampler(name, snd)
else:
+ logger.error(f'Dub into sample {name} {overdub=} {wrap=}')
return self.instrument.write_block_into_sampler(name, snd, offset, overdub, wrap)
def resample(self, length=1, offset=0, channels=2, samplerate=48000, instrument=None):
@@ 439,16 447,20 @@ cdef class Instrument:
str path,
int input_channels,
int output_channels,
+ double initial_volume,
double adc_length,
double resampler_length,
str midi_input_device_name,
- str midi_output_device_name
+ str midi_output_device_name,
+ int is_interactive
):
cdef char * midi_input_device_cstr
cdef char * midi_output_device_cstr
self.midi_input_device_name = NULL
self.midi_output_device_name = NULL
+ cdef lpinstrument_config_t config
+
if midi_input_device_name is not None:
midi_input_device_name_byte_string = midi_input_device_name.encode('UTF-8')
midi_input_device_cstr = midi_input_device_name_byte_string
@@ 467,28 479,25 @@ cdef class Instrument:
self.ascii_name = <char *>calloc(LPMAXNAME, sizeof(char))
strncpy(self.ascii_name, _instrument_ascii_name, LPMAXNAME-1)
+ config = astrid_instrument_init_config(self.ascii_name)
+
self.name = name
self.path = path
self.cache = None
self.last_reload = 0
self.max_processing_time = 0
- self.i = astrid_instrument_start(
- self.ascii_name,
- input_channels,
- output_channels,
- 1, # ext relay enabled
- adc_length,
- resampler_length,
- NULL, # ctx
- NULL, # tty
- self.midi_input_device_name,
- self.midi_output_device_name,
- NULL, # c stream callback
- NULL, # c renderer callback
- NULL, # c update callback
- NULL # c trigger callback
- )
+ config.initial_volume = initial_volume
+ config.input_channels = input_channels
+ config.output_channels = output_channels
+ config.midiin_device_name = self.midi_input_device_name
+ config.midiout_device_name = self.midi_output_device_name
+ config.adc_length = adc_length
+ config.resampler_length = resampler_length
+ config.ext_relay_enabled = 1
+ config.is_interactive = is_interactive
+
+ self.i = astrid_instrument_start_from_config(config)
if self.i == NULL:
raise InstrumentError('Could not initialize lpinstrument_t')
@@ 618,7 627,6 @@ cdef class Instrument:
out = LPBuffer.create(length_in_frames, self.input_channels, samplerate)
- # fixme add dcblock
if lpsampler_read_ringbuffer_block(self.i.adcname, self.i.adcbuf, offset_in_frames, out) < 0:
logger.error('pippi.renderer ADC read: failed to read %d frames at offset %d from ADC' % (length_in_frames, offset_in_frames))
return snd
@@ 639,17 647,12 @@ cdef class Instrument:
name_bytes = name.encode('UTF-8')
cdef char * _name = name_bytes
-
out = lpsampler_aquire_and_map(_name)
-
- if out == NULL or out.length <= 0 or out.channels <= 0:
+ if out == NULL:
logger.error('pippi.renderer sampler read: failed to read from %s' % _name)
- if out != NULL:
- logger.error('length=%s channels=%s' % (out.length, out.channels))
return None
snd = SoundBuffer(framelength=out.length, channels=self.output_channels, samplerate=self.samplerate)
- logger.debug('out.length=%s len(snd)=%s self.samplerate=%s' % (out.length, len(snd), self.samplerate))
if len(snd) == 0:
logger.error('sampler BLOWUP! len(snd)==0 self.output_channels=%d self.samplerate=%s' % (self.output_channels, self.samplerate))
@@ 678,6 681,8 @@ cdef class Instrument:
cdef size_t offset_in_frames = <size_t>(offset * samplerate)
bank = lpsampler_aquire_and_map(_name)
+ if bank == NULL:
+ return None
start = (bank.pos - offset_in_frames - length_in_frames) % bank.length
for i in range(length_in_frames):
@@ 1064,6 1069,8 @@ def _run_forever(Instrument instrument,
str instrument_name,
int input_channels,
int output_channels,
+ int is_interactive,
+ double initial_volume,
double adc_length,
double resampler_length,
object q,
@@ 1110,7 1117,15 @@ def _run_forever(Instrument instrument,
# FIXME pass this along to the comrades
try:
if instrument is None:
- instrument = Instrument(instrument_name, script_path, input_channels, output_channels, adc_length, resampler_length)
+ instrument = Instrument(instrument_name,
+ script_path,
+ input_channels,
+ output_channels,
+ initial_volume,
+ adc_length,
+ resampler_length,
+ is_interactive,
+ )
else:
last_edit = os.path.getmtime(instrument.path)
if last_edit > instrument.last_reload:
@@ 1130,8 1145,10 @@ def run_forever(
int output_channels=2,
double adc_length=60,
double resampler_length=60,
+ double initial_volume=1,
str midi_input_device_name=None,
- str midi_output_device_name=None
+ str midi_output_device_name=None,
+ int is_interactive=1,
):
cdef Instrument instrument = None
instrument_name = instrument_name if instrument_name is not None else Path(script_path).stem
@@ 1150,10 1167,12 @@ def run_forever(
script_path,
input_channels,
output_channels,
+ initial_volume,
adc_length,
resampler_length,
midi_input_device_name,
- midi_output_device_name
+ midi_output_device_name,
+ is_interactive
)
logger.info(f'PY: started instrument... {script_path=} {instrument_name=}')
except InstrumentError as e:
@@ 1167,7 1186,18 @@ def run_forever(
comrade.start()
render_pool += [ comrade ]
- message_process = Process(target=_run_forever, args=(instrument, script_path, instrument_name, input_channels, output_channels, adc_length, resampler_length, render_q))
+ message_process = Process(target=_run_forever, args=(
+ instrument,
+ script_path,
+ instrument_name,
+ input_channels,
+ output_channels,
+ is_interactive,
+ initial_volume,
+ adc_length,
+ resampler_length,
+ render_q
+ ))
message_process.start()
try: