~hecanjog/pippi

02ed65473a863840baed69ca6919a46dac0b214f — Erik Schoster 11 days ago 7aaec34
Add minimal sampler interface to astrid event contexts
M libpippi/cython/cyrenderer.pxd => libpippi/cython/cyrenderer.pxd +24 -0
@@ 53,6 53,30 @@ cdef extern from "astrid.h":
        size_t frames
        int channels

    ctypedef struct lpsampler_t:
        int fd
        char * name
        char * buf
        size_t total_bytes
        size_t length
        int samplerate
        int channels

        size_t length_offset
        size_t samplerate_offset
        size_t channels_offset
        size_t buffer_offset

    lpsampler_t * lpsampler_create_from(int bankid, lpbuffer_t * buf)
    lpsampler_t * lpsampler_open(int bankid)
    lpsampler_t * lpsampler_dub(int bankid, lpbuffer_t * buf)
    int lpsampler_close(lpsampler_t *)
    int lpsampler_destroy(lpsampler_t *)
    int lpsampler_get_length(lpsampler_t * sampler, size_t * length)
    int lpsampler_get_samplerate(lpsampler_t * sampler, int * samplerate)
    int lpsampler_get_channels(lpsampler_t * sampler, int * channels)
    lpfloat_t lpsampler_read_sample(lpsampler_t * sampler, size_t frame, int channel)

    lpadcbuf_t * lpadc_create()
    lpadcbuf_t * lpadc_open()
    lpfloat_t lpadc_read_sample(lpadcbuf_t * adcbuf, size_t frame, int channel)

M libpippi/cython/cyrenderer.pyx => libpippi/cython/cyrenderer.pyx +29 -0
@@ 83,6 83,31 @@ cdef SoundBuffer read_from_adc(double length, double offset=0, int channels=2, i

    return snd

cdef SoundBuffer read_from_sampler(int bankid):
    cdef size_t i
    cdef size_t pos = 0
    cdef int c
    cdef lpsampler_t * sampler = lpsampler_open(bankid)

    cdef size_t framelength = 0
    cdef int samplerate = 0
    cdef int channels = 0

    lpsampler_get_length(sampler, &framelength)
    lpsampler_get_samplerate(sampler, &samplerate)
    lpsampler_get_channels(sampler, &channels)

    cdef SoundBuffer snd = SoundBuffer(length=framelength/<float>samplerate, channels=channels, samplerate=samplerate)

    for i in range(framelength):
        for c in range(channels):
            snd.frames[i,c] = lpsampler_read_sample(sampler, i, c)

    lpsampler_close(sampler)

    return snd


cdef class SessionParamBucket:
    """ params[key] to params.key
    """


@@ 150,6 175,10 @@ cdef class EventContext:
    def adc(self, length=1, offset=0, channels=2):
        return read_from_adc(length, offset=offset, channels=channels)

    def sampler(self, bankid=0):
        bankid %= 10000
        return read_from_sampler(bankid)

    def log(self, msg):
        logger.info(msg)


M libpippi/src/astrid.c => libpippi/src/astrid.c +23 -0
@@ 226,6 226,29 @@ lpsampler_t * lpsampler_dub(int bankid, lpbuffer_t * buf) {
    return sampler;
}

lpfloat_t lpsampler_read_sample(lpsampler_t * sampler, size_t frame, int channel) {
    lpfloat_t sample;
    size_t offset;
    size_t length = 0;
    int channels = 0;

    // get buf channels
    lpsampler_get_channels(sampler, &channels);
    lpsampler_get_length(sampler, &length);

    frame = frame % length;

    // get offset to buf
    offset = sampler->buffer_offset;
    offset += ((frame * channels + channel) * sizeof(lpfloat_t));

    // memcpy at offset to lpfloat_t
    sample = 0;
    memcpy(&sample, sampler->buf+offset, sizeof(lpfloat_t));

    return sample;
}

int lpsampler_close(lpsampler_t * sampler) {
    if(close(sampler->fd) == -1) {
        fprintf(stderr, "Could not close sampler fd.\n");

M libpippi/src/astrid.h => libpippi/src/astrid.h +1 -0
@@ 42,6 42,7 @@ int lpsampler_destroy(lpsampler_t *);
int lpsampler_get_length(lpsampler_t * sampler, size_t * length);
int lpsampler_get_samplerate(lpsampler_t * sampler, int * samplerate);
int lpsampler_get_channels(lpsampler_t * sampler, int * channels);
lpfloat_t lpsampler_read_sample(lpsampler_t * sampler, size_t frame, int channel);

typedef struct lpadcbuf_t {
    int fd;