M astrid/Makefile => astrid/Makefile +10 -2
@@ 29,7 29,7 @@ LPDBINCLUDES = -I${LPDIR}/vendor/sqlite3
LPFLAGS = -g -std=gnu2x -Wall -Wextra -pedantic -O0 -DNOPYTHON
LPLIBS = -lm -ldl -lpthread -lrt -ljack -lasound
-default: littlefield
+default: astrid-sampler
clean:
rm -rf build/*
@@ 57,7 57,6 @@ astrid-ipc:
#gcc $(LPFLAGS) $(LPINCLUDES) $(LPSOURCES) src/astrid.c src/ipcgetvalue.c $(LPLIBS) -o build/astrid-ipcgetvalue
#gcc $(LPFLAGS) $(LPINCLUDES) $(LPSOURCES) src/astrid.c src/ipcsetvalue.c $(LPLIBS) -o build/astrid-ipcsetvalue
#gcc $(LPFLAGS) $(LPINCLUDES) $(LPSOURCES) src/astrid.c src/ipcdestroyvalue.c $(LPLIBS) -o build/astrid-ipcdestroyvalue
- gcc $(LPFLAGS) $(LPINCLUDES) $(LPSOURCES) src/astrid.c src/sampler.c $(LPLIBS) -o build/astrid-sampler
astrid-q:
echo "Building astrid queue reader...";
@@ 102,6 101,15 @@ astrid-bufstr:
echo "Building astrid bufstr...";
$(CC) $(LPFLAGS) $(LPINCLUDES) $(LPSOURCES) src/astrid.c orc/bufstr.c $(LPLIBS) -o build/astrid-bufstr
+astrid-sampler:
+ mkdir -p build
+
+ echo "Building astrid sampler test programs...";
+ $(CC) $(LPFLAGS) $(LPINCLUDES) $(LPSOURCES) src/astrid.c orc/dubby.c $(LPLIBS) -o build/dubby
+
+ #$(CC) $(LPFLAGS) $(LPINCLUDES) $(LPSOURCES) src/astrid.c src/sampler.c $(LPLIBS) -o build/astrid-sampler
+
+
astrid-paramset:
mkdir -p build
M astrid/src/astrid.c => astrid/src/astrid.c +24 -13
@@ 3369,7 3369,7 @@ void * instrument_midi_listener_thread(void * arg) {
lpinstrument_t * instrument = (lpinstrument_t *)arg;
- syslog(LOG_DEBUG, "%s MIDI listener thread starting for device ID %d\n", instrument->name, instrument->midi_device_id);
+ syslog(LOG_DEBUG, "%s MIDI listener thread starting for device ID %d\n", instrument->name, instrument->midiin_device_id);
if((ret = snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT, 0)) < 0) {
syslog(LOG_ERR, "%s midi listener: Could not open ALSA seq. Error: (%d) %s\n", instrument->name, ret, snd_strerror(ret));
@@ 3386,7 3386,7 @@ void * instrument_midi_listener_thread(void * arg) {
return 0;
}
- if((ret = snd_seq_connect_from(seq_handle, port, instrument->midi_device_id, 0)) < 0) {
+ if((ret = snd_seq_connect_from(seq_handle, port, instrument->midiin_device_id, 0)) < 0) {
syslog(LOG_ERR, "%s midi listener: Could not connect to ALSA port. Error: (%d) %s\n", instrument->name, ret, snd_strerror(ret));
snd_seq_close(seq_handle);
return 0;
@@ 3422,7 3422,7 @@ void * instrument_midi_output_thread(void * arg) {
lpinstrument_t * instrument = (lpinstrument_t *)arg;
- syslog(LOG_ERR, "%s MIDI output thread starting for device ID %d\n", instrument->name, instrument->midi_device_id);
+ syslog(LOG_ERR, "%s MIDI output thread starting for device ID %d\n", instrument->name, instrument->midiout_device_id);
if((instrument->midioutmsgq = astrid_msgq_open(instrument->midiout_message_q_name)) == (mqd_t) -1) {
syslog(LOG_CRIT, "Could not open midiout msgq for instrument %s. Error: %s\n", instrument->name, strerror(errno));
@@ 3445,7 3445,7 @@ void * instrument_midi_output_thread(void * arg) {
return 0;
}
- if((ret = snd_seq_connect_to(seq_handle, port, instrument->midi_device_id, 0)) < 0) {
+ if((ret = snd_seq_connect_to(seq_handle, port, instrument->midiout_device_id, 0)) < 0) {
syslog(LOG_ERR, "%s midi output: Could not connect to ALSA port. Error: (%d) %s\n", instrument->name, ret, snd_strerror(ret));
snd_seq_close(seq_handle);
return 0;
@@ 3467,7 3467,7 @@ void * instrument_midi_output_thread(void * arg) {
usleep((useconds_t)10000);
continue;
}
- syslog(LOG_ERR, "%s MIDI output thread got msg for device ID %d\n", instrument->name, instrument->midi_device_id);
+ syslog(LOG_ERR, "%s MIDI output thread got msg for device ID %d\n", instrument->name, instrument->midiout_device_id);
if(snd_midi_event_encode(midi_event, (unsigned char *)msg.msg, sizeof(unsigned char) * 3, &event) < 0) {
syslog(LOG_ERR, "%s midi output: Could not decode MIDI message from lpmsg_t body. Error: (%d) %s\n", instrument->name, errno, strerror(errno));
@@ 3505,7 3505,8 @@ lpinstrument_t * astrid_instrument_start(
double resampler_length,
void * ctx,
char * tty,
- char * midi_device_name,
+ 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),
@@ 3523,7 3524,7 @@ lpinstrument_t * astrid_instrument_start(
instrument = (lpinstrument_t *)LPMemoryPool.alloc(1, sizeof(lpinstrument_t));
memset(instrument, 0, sizeof(lpinstrument_t));
- setlogmask(LOG_UPTO(LOG_ERR));
+ //setlogmask(LOG_UPTO(LOG_ERR));
openlog(name, LOG_PID, LOG_USER);
syslog(LOG_DEBUG, "starting %s instrument...\n", name);
@@ 3538,10 3539,16 @@ lpinstrument_t * astrid_instrument_start(
instrument->ext_relay_enabled = ext_relay_enabled;
instrument->is_ready = 1;
- instrument->midi_device_id = -1;
- if(midi_device_name != NULL) {
- instrument->midi_device_id = lpmidi_get_device_id_by_name(midi_device_name);
- syslog(LOG_DEBUG, "Set MIDI device ID (%d) for %s\n", instrument->midi_device_id, midi_device_name);
+ 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);
+ }
+
+ 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);
}
/* Seed the random number generator */
@@ 3730,13 3737,15 @@ lpinstrument_t * astrid_instrument_start(
/* Start listening for MIDI messages in the midi listener thread */
// TODO support multiple devices
- if(instrument->midi_device_id >= 0) {
+ if(instrument->midiin_device_id >= 0) {
syslog(LOG_DEBUG, "We're gonna listen for some MIDI over here in %s-land!\n", instrument->name);
if(pthread_create(&instrument->midi_listener_thread, NULL, instrument_midi_listener_thread, (void*)instrument) != 0) {
syslog(LOG_ERR, "Could not initialize instrument midi listener thread. Error: %s\n", strerror(errno));
return NULL;
}
+ }
+ if(instrument->midiout_device_id >= 0) {
if(pthread_create(&instrument->midi_output_thread, NULL, instrument_midi_output_thread, (void*)instrument) != 0) {
syslog(LOG_ERR, "Could not initialize instrument midi output thread. Error: %s\n", strerror(errno));
return NULL;
@@ 3804,7 3813,7 @@ int astrid_instrument_stop(lpinstrument_t * instrument) {
syslog(LOG_ERR, "Error while attempting to join with cleanup thread. Ret: %d Errno: %d (%s)\n", ret, errno, strerror(ret));
}
- if(instrument->midi_device_id >= 0) {
+ if(instrument->midiin_device_id >= 0) {
syslog(LOG_DEBUG, "Joining with midi listener thread...\n");
if((ret = pthread_join(instrument->midi_listener_thread, NULL)) != 0) {
if(ret == EINVAL) syslog(LOG_ERR, "EINVAL\n");
@@ 3812,7 3821,9 @@ int astrid_instrument_stop(lpinstrument_t * instrument) {
if(ret == ESRCH) syslog(LOG_ERR, "ESRCH\n");
syslog(LOG_ERR, "Error while attempting to join with midi listener thread. Ret: %d Errno: %d (%s)\n", ret, errno, strerror(ret));
}
+ }
+ if(instrument->midiout_device_id >= 0) {
syslog(LOG_DEBUG, "Joining with midi output thread...\n");
if((ret = pthread_join(instrument->midi_output_thread, NULL)) != 0) {
if(ret == EINVAL) syslog(LOG_ERR, "EINVAL\n");
M astrid/src/astrid.h => astrid/src/astrid.h +4 -2
@@ 185,7 185,8 @@ typedef struct lpinstrument_t {
lpmsg_t msg;
lpmsg_t cmd;
- int midi_device_id;
+ int midiin_device_id;
+ int midiout_device_id;
int tty_is_enabled;
char tty_path[NAME_MAX];
@@ 374,7 375,8 @@ lpinstrument_t * astrid_instrument_start(
double resampler_length,
void * ctx,
char * tty,
- char * midi_device_name,
+ 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),
M libpippi/src/pippicore.c => libpippi/src/pippicore.c +45 -1
@@ 41,6 41,7 @@ lpbuffer_t * concat_buffers(lpbuffer_t * a, lpbuffer_t * b);
int buffers_are_equal(lpbuffer_t * a, lpbuffer_t * b);
int buffers_are_close(lpbuffer_t * a, lpbuffer_t * b, int d);
void dub_buffer(lpbuffer_t * a, lpbuffer_t * b, size_t start);
+void dub_into_buffer(lpbuffer_t * buf, lpbuffer_t * src, size_t offset, lpfloat_t feedback, int wrap, int overdub);
void dub_scalar(lpbuffer_t * a, lpfloat_t, size_t start);
void env_buffer(lpbuffer_t * buf, lpbuffer_t * env);
lpbuffer_t * pad_buffer(lpbuffer_t * buf, size_t before, size_t after);
@@ 128,7 129,7 @@ lprand_t LPRand = { LOGISTIC_SEED_DEFAULT, LOGISTIC_X_DEFAULT, \
rand_base_stdlib, rand_rand, rand_randint, rand_randbool, rand_choice };
lpmemorypool_factory_t LPMemoryPool = { 0, 0, 0, memorypool_init, memorypool_custom_init, memorypool_alloc, memorypool_custom_alloc, memorypool_free };
const lparray_factory_t LPArray = { create_array, create_array_from, destroy_array };
-const lpbuffer_factory_t LPBuffer = { create_buffer, create_buffer_from_float, create_buffer_from_bytes, copy_buffer, clone_buffer, clear_buffer, split2_buffer, scale_buffer, min_buffer, max_buffer, mag_buffer, play_buffer, pan_stereo_buffer, mix_buffers, remix_buffer, clip_buffer, cut_buffer, cut_into_buffer, varispeed_buffer, resample_buffer, multiply_buffer, scalar_multiply_buffer, add_buffers, scalar_add_buffer, subtract_buffers, scalar_subtract_buffer, divide_buffers, scalar_divide_buffer, concat_buffers, buffers_are_equal, buffers_are_close, dub_buffer, dub_scalar, env_buffer, pad_buffer, taper_buffer, trim_buffer, fill_buffer, repeat_buffer, reverse_buffer, resize_buffer, plot_buffer, destroy_buffer };
+const lpbuffer_factory_t LPBuffer = { create_buffer, create_buffer_from_float, create_buffer_from_bytes, copy_buffer, clone_buffer, clear_buffer, split2_buffer, scale_buffer, min_buffer, max_buffer, mag_buffer, play_buffer, pan_stereo_buffer, mix_buffers, remix_buffer, clip_buffer, cut_buffer, cut_into_buffer, varispeed_buffer, resample_buffer, multiply_buffer, scalar_multiply_buffer, add_buffers, scalar_add_buffer, subtract_buffers, scalar_subtract_buffer, divide_buffers, scalar_divide_buffer, concat_buffers, buffers_are_equal, buffers_are_close, dub_buffer, dub_into_buffer, dub_scalar, env_buffer, pad_buffer, taper_buffer, trim_buffer, fill_buffer, repeat_buffer, reverse_buffer, resize_buffer, plot_buffer, destroy_buffer };
const lpinterpolation_factory_t LPInterpolation = { interpolate_linear_pos, interpolate_linear_pos2, interpolate_linear, interpolate_linear_channel, interpolate_hermite_pos, interpolate_hermite };
const lpparam_factory_t LPParam = { param_create_from_float, param_create_from_int };
const lpwavetable_factory_t LPWavetable = { create_wavetable, create_wavetable_stack, destroy_wavetable };
@@ 1044,6 1045,49 @@ void dub_buffer(lpbuffer_t * a, lpbuffer_t * b, size_t start) {
}
}
+void dub_into_buffer(
+ lpbuffer_t * buf,
+ lpbuffer_t * src,
+ size_t offset,
+ lpfloat_t feedback,
+ int wrap,
+ int overdub
+ ) {
+ size_t i, j, dublength, slop=0;
+ int c, d;
+ lpfloat_t sample;
+
+ dublength = src->length;
+ slop = (src->length + offset) - buf->length;
+ if(slop > 0) dublength -= slop;
+
+ if(overdub == 0) {
+ memset(buf->data+(offset*buf->channels), 0, sizeof(lpfloat_t) * buf->channels * dublength);
+ }
+
+ for(i=0; i < dublength; i++) {
+ for(c=0; c < buf->channels; c++) {
+ d = c % src->channels;
+ sample = buf->data[(i+offset) * buf->channels + c] * feedback;
+ sample += src->data[i * src->channels + d];
+ buf->data[(i+offset) * buf->channels + c] = sample;
+ }
+ }
+
+ if(wrap == 1 && slop > 0) {
+ for(j=0; j < slop; j++) {
+ for(c=0; c < buf->channels; c++) {
+ d = c % src->channels;
+ sample = buf->data[j * buf->channels + c] * feedback;
+ sample += src->data[(i+j) * src->channels + d];
+ buf->data[j * buf->channels + c] = sample;
+ }
+ }
+ }
+}
+
+
+
void dub_scalar(lpbuffer_t * a, lpfloat_t val, size_t start) {
int c;
M libpippi/src/pippicore.h => libpippi/src/pippicore.h +1 -0
@@ 124,6 124,7 @@ typedef struct lpbuffer_factory_t {
int (*buffers_are_equal)(lpbuffer_t *, lpbuffer_t *);
int (*buffers_are_close)(lpbuffer_t *, lpbuffer_t *, int);
void (*dub)(lpbuffer_t *, lpbuffer_t *, size_t);
+ void (*dub_into)(lpbuffer_t * buf, lpbuffer_t * src, size_t offset, lpfloat_t feedback, int wrap, int overdub);
void (*dub_scalar)(lpbuffer_t *, lpfloat_t, size_t);
void (*env)(lpbuffer_t *, lpbuffer_t *);
lpbuffer_t * (*pad)(lpbuffer_t * buf, size_t before, size_t after);
M pippi/renderer.pxd => pippi/renderer.pxd +5 -2
@@ 185,7 185,8 @@ cdef extern from "astrid.h":
double resampler_length,
void * ctx,
char * tty,
- char * midi_device_name,
+ char * midi_input_device_name,
+ char * midi_output_device_name,
int (*stream)(size_t blocksize, float ** input, float ** output, void * instrument),
int (*renderer)(void * instrument),
int (*update)(void * instrument),
@@ 243,7 244,8 @@ cdef class Instrument:
cdef public double samplerate
cdef public int default_midi_device
cdef char * ascii_name # instrument name as a c string
- cdef char * midi_device_name
+ cdef char * midi_input_device_name
+ cdef char * midi_output_device_name
cdef lpinstrument_t * i
cpdef EventContext get_event_context(Instrument self, str msgstr=*, bint with_graph=*)
cpdef lpmsg_t get_message(Instrument self)
@@ 252,6 254,7 @@ cdef class Instrument:
cdef SoundBuffer read_block_from_sampler(Instrument self, str name, double length, double offset=*, int channels=*, int samplerate=*)
cdef SoundBuffer read_from_sampler(Instrument self, str name)
cdef void save_to_sampler(Instrument self, str name, SoundBuffer snd)
+ cdef SoundBuffer write_block_into_sampler(Instrument self, str name, SoundBuffer snd, double offset, bint overdub=*, bint wrap=*)
cdef class SessionParamBucket:
cdef Instrument instrument
M pippi/renderer.pyx => pippi/renderer.pyx +94 -23
@@ 373,15 373,21 @@ cdef class EventContext:
def adc(self, length=1, offset=0, channels=2):
return self.instrument.read_from_adc(length, offset=offset, channels=channels)
- def sample(self, str name, SoundBuffer snd=None, length=0, offset=0, channels=2):
- if snd is None and length > 0:
- # read a portion from the sample
+ 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)
+
+ # otherwise read a portion from the sample
return self.instrument.read_block_from_sampler(name, length, offset=offset, channels=channels)
- elif snd is None:
- # read the entire sample
- return self.instrument.read_from_sampler(name)
- # write to the samplebank FIXME, should be able to use this like dub()
- self.instrument.save_to_sampler(name, snd)
+
+ # write operations
+ if overwrite:
+ return self.instrument.save_to_sampler(name, snd)
+ else:
+ 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):
return self.instrument.read_from_resampler(length, offset=offset, channels=channels, samplerate=samplerate, instrument=instrument)
@@ 393,14 399,23 @@ cdef class EventContext:
return self.p._params
cdef class Instrument:
- def __cinit__(self, str name, str path, int channels, double adc_length, double resampler_length, str midi_device_name):
- cdef char * midi_device_cstr
- self.midi_device_name = NULL
- if midi_device_name is not None:
- midi_device_name_byte_string = midi_device_name.encode('UTF-8')
- midi_device_cstr = midi_device_name_byte_string
- self.midi_device_name = <char *>calloc(LPMAXNAME, sizeof(char))
- strncpy(self.midi_device_name, midi_device_cstr, LPMAXNAME-1)
+ def __cinit__(self, str name, str path, int channels, double adc_length, double resampler_length, str midi_input_device_name, str midi_output_device_name):
+ cdef char * midi_input_device_cstr
+ cdef char * midi_output_device_cstr
+ self.midi_input_device_name = NULL
+ self.midi_output_device_name = NULL
+
+ 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
+ self.midi_input_device_name = <char *>calloc(LPMAXNAME, sizeof(char))
+ strncpy(self.midi_input_device_name, midi_input_device_cstr, LPMAXNAME-1)
+
+ if midi_output_device_name is not None:
+ midi_output_device_name_byte_string = midi_output_device_name.encode('UTF-8')
+ midi_output_device_cstr = midi_output_device_name_byte_string
+ self.midi_output_device_name = <char *>calloc(LPMAXNAME, sizeof(char))
+ strncpy(self.midi_output_device_name, midi_output_device_cstr, LPMAXNAME-1)
instrument_byte_string = name.encode('UTF-8')
cdef char * _instrument_ascii_name = instrument_byte_string
@@ 415,7 430,8 @@ cdef class Instrument:
self.max_processing_time = 0
self.i = astrid_instrument_start(self.ascii_name, channels, 1, adc_length, resampler_length, NULL, NULL,
- self.midi_device_name,
+ self.midi_input_device_name,
+ self.midi_output_device_name,
NULL, NULL, NULL, NULL)
if self.i == NULL:
raise InstrumentError('Could not initialize lpinstrument_t')
@@ 451,13 467,15 @@ cdef class Instrument:
renderer._ = None
self.renderer = renderer
+ ctx = self.get_event_context()
# fill the cache if there is something to fill:
if hasattr(self.renderer, 'cache'):
self.cache = self.renderer.cache()
+ elif hasattr(self.renderer, 'onload'):
+ self.cache = self.renderer.onload(ctx) or self.cache
if hasattr(self.renderer, 'stream'):
- ctx = self.get_event_context()
self.graph = self.renderer.stream(ctx)
if hasattr(self.renderer, 'MIDI_DEVICE'):
@@ 595,7 613,7 @@ cdef class Instrument:
return None
snd = SoundBuffer(framelength=out.length, channels=self.channels, samplerate=self.samplerate)
- logger.debug('out.length=%s len(snd)=%s self.samplerate=%s' % (out.length, len(snd), self.samplerate))
+ logger.error('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.channels=%d self.samplerate=%s' % (self.channels, self.samplerate))
@@ 635,6 653,8 @@ cdef class Instrument:
return snd
cdef void save_to_sampler(Instrument self, str name, SoundBuffer snd):
+ """ Overwrite the entire sampler bank with the SoundBuffer
+ """
cdef size_t i
cdef int c
cdef lpbuffer_t * out
@@ 648,13 668,64 @@ cdef class Instrument:
logger.debug('out.length=%s len(snd)=%s' % (out.length, len(snd)))
# write the data into it
- for i in range(out.length):
+ for i in range(len(snd.frames)):
for c in range(out.channels):
out.data[i * out.channels + c] = snd.frames[i,c]
if lpsampler_release_and_unmap(_name, out) < 0:
logger.error('Could not release %s sampler memory' % _name)
+ cdef SoundBuffer write_block_into_sampler(Instrument self, str name, SoundBuffer snd, double offset, bint overdub=False, bint wrap=False):
+ """ Write or dub into a portion of the sampler bank
+ """
+ cdef size_t framelength, frameoffset, endpoint, i=0, slop=0, last_pos=0
+ cdef int c, channels
+ cdef lpbuffer_t * buf
+
+ name_bytes = name.encode('UTF-8')
+ cdef char * _name = name_bytes
+
+ # open the shm buffer
+ buf = lpsampler_aquire_and_map(_name)
+ if buf == NULL:
+ buf = lpsampler_create(_name, snd.dur, snd.channels, <int>self.samplerate)
+
+ framelength = <size_t>len(snd.frames) - 1
+ frameoffset = <size_t>int(offset * buf.samplerate)
+ endpoint = frameoffset + framelength
+ slop = buf.length - (frameoffset + framelength) - 1
+
+ if not wrap and slop > 0:
+ framelength = buf.length - frameoffset
+
+ # write the data into it
+ if overdub:
+ for i in range(len(snd.frames)):
+ for c in range(buf.channels):
+ buf.data[(i+frameoffset) * buf.channels + c] += snd.frames[i, (c % snd.channels)]
+
+ if wrap and slop > 0:
+ last_pos = i
+ for i in range(slop):
+ for c in range(buf.channels):
+ buf.data[i * buf.channels + c] += snd.frames[(i+last_pos), (c % snd.channels)]
+
+ else:
+ for i in range(len(snd.frames)):
+ for c in range(buf.channels):
+ buf.data[(i+frameoffset) * buf.channels + c] = snd.frames[i, (c % snd.channels)]
+
+ if wrap and slop > <size_t>0:
+ last_pos = i
+ for i in range(slop):
+ for c in range(buf.channels):
+ buf.data[i * buf.channels + c] = snd.frames[(i+last_pos), (c % snd.channels)]
+
+ if lpsampler_release_and_unmap(_name, buf) < 0:
+ logger.error('Could not release %s sampler memory' % _name)
+
+ return self.read_from_sampler(name)
+
def reload(self):
logger.debug('Reloading instrument %s from %s' % (self.name, self.path))
@@ 995,7 1066,7 @@ def _run_forever(Instrument instrument,
logger.info('PY: python instrument shutting down...')
-def run_forever(str script_path, str instrument_name=None, int channels=2, double adc_length=30, double resampler_length=30, str midi_device_name=None):
+def run_forever(str script_path, str instrument_name=None, int channels=2, double adc_length=30, double resampler_length=30, str midi_input_device_name=None, str midi_output_device_name=None):
cdef Instrument instrument = None
instrument_name = instrument_name if instrument_name is not None else Path(script_path).stem
instrument_byte_string = instrument_name.encode('UTF-8')
@@ 1003,8 1074,8 @@ def run_forever(str script_path, str instrument_name=None, int channels=2, doubl
try:
# Start the stream and setup the instrument
- logger.info(f'PY: loading python instrument... {script_path=} {instrument_name=} {midi_device_name=}')
- instrument = Instrument(instrument_name, script_path, channels, adc_length, resampler_length, midi_device_name)
+ logger.info(f'PY: loading python instrument... {script_path=} {instrument_name=} {midi_input_device_name=} {midi_output_device_name=}')
+ instrument = Instrument(instrument_name, script_path, channels, adc_length, resampler_length, midi_input_device_name, midi_output_device_name)
logger.info(f'PY: started instrument... {script_path=} {instrument_name=}')
except InstrumentError as e:
logger.error('PY: Error trying to start instrument. Shutting down...')
M pippi/rhythm.pyx => pippi/rhythm.pyx +11 -1
@@ 115,6 115,9 @@ cdef class Seq:
smear=smear,
)
+ def set(self, *args, **kwargs):
+ return self.add(*args, **kwargs)
+
def update(self, name, **kwargs):
self.instruments[name].update(kwargs)
@@ 230,7 233,14 @@ cdef class Seq:
return pattern
- def play(self, int numbeats, str patseq=None, bint stems=False, str stemsdir='', str stemsext='wav', bint pool=False):
+ def get_events(self):
+ cdef list events = []
+ return events
+
+ def play(self, *args, **kwargs):
+ self.render(*args, **kwargs)
+
+ def render(self, int numbeats, str patseq=None, bint stems=False, str stemsdir='', str stemsext='wav', bint pool=False):
cdef SoundBuffer out = SoundBuffer()
cdef dict instrument
cdef str expanded
M pippi/soundbuffer.pyx => pippi/soundbuffer.pyx +3 -3
@@ 281,7 281,7 @@ cdef class SoundBuffer:
int samplerate=DEFAULT_SAMPLERATE,
object filename=None,
int offset=0,
- double[:,:] buf=None, int framelength=-1):
+ double[:,:] buf=None, size_t framelength=-1):
self.samplerate = samplerate
self.channels = max(channels, 1)
@@ 289,9 289,9 @@ cdef class SoundBuffer:
framelength = len(frames)
if length >= 0:
- framelength = <int>(length * self.samplerate)
+ framelength = <size_t>(length * self.samplerate)
elif framelength >= 0:
- length = framelength * samplerate
+ length = framelength * self.samplerate
elif filename is None and frames is None and buf is None:
length = 0