Generated by Cython 0.28.4

Yellow lines hint at Python interaction.
Click on a line that starts with a "+" to see the C code that Cython generated for it.

Raw output: grains.c

+001: # cython: language_level=3
  __pyx_t_1 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 002: 
 003: from .soundbuffer cimport SoundBuffer, _cut, _dub, _speed, _pan, _env
 004: from . cimport wavetables
 005: from . cimport interpolation
 006: from libc.stdlib cimport rand, RAND_MAX
+007: import numpy as np
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_numpy, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 7, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_np, __pyx_t_1) < 0) __PYX_ERR(0, 7, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 008: from cpython cimport array
+009: import array
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_array, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 9, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_array, __pyx_t_1) < 0) __PYX_ERR(0, 9, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 010: 
 011: DEF MIN_DENSITY = 0.000001
 012: DEF MIN_SPEED = 0.000001
 013: DEF MIN_GRAIN_FRAMELENGTH = 441
 014: DEF DEFAULT_WTSIZE = 4096
 015: DEF DEFAULT_GRAINLENGTH = 60
 016: DEF DEFAULT_MAXGRAINLENGTH = 80
 017: DEF DEFAULT_SPEED = 1
 018: DEF DEFAULT_MAXSPEED = 2
 019: DEF DEFAULT_DENSITY = 1
 020: DEF DEFAULT_MINDENSITY = 0.5
 021: DEF DEFAULT_MAXDENSITY = 1.5
 022: 
+023: cdef double[:,:] _play(GrainCloud cloud, double[:,:] out, int framelength, double length):
static __Pyx_memviewslice __pyx_f_5pippi_6grains__play(struct __pyx_obj_5pippi_6grains_GrainCloud *__pyx_v_cloud, __Pyx_memviewslice __pyx_v_out, int __pyx_v_framelength, CYTHON_UNUSED double __pyx_v_length) {
  int __pyx_v_input_length;
  int __pyx_v_fi;
  int __pyx_v_ci;
  int __pyx_v_write_pos;
  int __pyx_v_write_inc;
  int __pyx_v_start;
  CYTHON_UNUSED int __pyx_v_end;
  double __pyx_v_panpos;
  double __pyx_v_read_frac_pos;
  double __pyx_v_grain_speed;
  double __pyx_v_density_frac_pos;
  double __pyx_v_grainlength_frac_pos;
  unsigned long __pyx_v_initial_grainlength;
  unsigned long __pyx_v_grainlength;
  unsigned long __pyx_v_preresample_grainlength;
  CYTHON_UNUSED unsigned long __pyx_v_target_grainlength;
  int __pyx_v_max_read_pos;
  double __pyx_v_read_pos;
  __Pyx_memviewslice __pyx_v_grain = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_grain_pre = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_grainchan = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_memviewslice __pyx_v_grainchan_pre = { 0, 0, { 0 }, { 0 }, { 0 } };
  double __pyx_v_playhead;
  double __pyx_v_density;
  __Pyx_memviewslice __pyx_r = { 0, 0, { 0 }, { 0 }, { 0 } };
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_play", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
  __pyx_r.data = NULL;
  __pyx_r.memview = NULL;
  __Pyx_AddTraceback("pippi.grains._play", __pyx_clineno, __pyx_lineno, __pyx_filename);

  goto __pyx_L2;
  __pyx_L0:;
  if (unlikely(!__pyx_r.memview)) {
    PyErr_SetString(PyExc_TypeError, "Memoryview return value is not initialized");
  }
  __pyx_L2:;
  __PYX_XDEC_MEMVIEW(&__pyx_v_grain, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_grain_pre, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_grainchan, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_grainchan_pre, 1);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
+024:     cdef int input_length = len(cloud.buf)
  __pyx_t_1 = ((PyObject *)__pyx_v_cloud->buf);
  __Pyx_INCREF(__pyx_t_1);
  __pyx_t_2 = PyObject_Length(__pyx_t_1); if (unlikely(__pyx_t_2 == ((Py_ssize_t)-1))) __PYX_ERR(0, 24, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_input_length = __pyx_t_2;
 025: 
+026:     cdef int fi = 0
  __pyx_v_fi = 0;
+027:     cdef int ci = 0
  __pyx_v_ci = 0;
 028: 
+029:     cdef int write_pos = 0
  __pyx_v_write_pos = 0;
+030:     cdef int write_inc = 0
  __pyx_v_write_inc = 0;
+031:     cdef int start = 0
  __pyx_v_start = 0;
+032:     cdef int end = 0
  __pyx_v_end = 0;
+033:     cdef double panpos = 0.5
  __pyx_v_panpos = 0.5;
 034: 
+035:     cdef double read_frac_pos = 0
  __pyx_v_read_frac_pos = 0.0;
+036:     cdef double grain_speed = 0
  __pyx_v_grain_speed = 0.0;
+037:     cdef double density_frac_pos = 0
  __pyx_v_density_frac_pos = 0.0;
+038:     cdef double grainlength_frac_pos = 0
  __pyx_v_grainlength_frac_pos = 0.0;
 039: 
+040:     cdef unsigned long initial_grainlength = <unsigned long>(<double>cloud.samplerate * cloud.grainlength * 0.001)
  __pyx_v_initial_grainlength = ((unsigned long)((((double)__pyx_v_cloud->samplerate) * __pyx_v_cloud->grainlength) * 0.001));
+041:     cdef unsigned long grainlength = initial_grainlength
  __pyx_v_grainlength = __pyx_v_initial_grainlength;
 042: 
+043:     cdef unsigned long preresample_grainlength = 0
  __pyx_v_preresample_grainlength = 0;
+044:     cdef unsigned long target_grainlength = 0
  __pyx_v_target_grainlength = 0;
 045: 
+046:     cdef int max_read_pos = input_length - grainlength
  __pyx_v_max_read_pos = (__pyx_v_input_length - __pyx_v_grainlength);
+047:     cdef double read_pos = 0
  __pyx_v_read_pos = 0.0;
 048:     cdef double[:,:] grain
 049:     cdef double[:,:] grain_pre
 050:     cdef double[:] grainchan
 051:     cdef double[:] grainchan_pre
 052: 
+053:     cdef double playhead = 0
  __pyx_v_playhead = 0.0;
 054: 
+055:     while write_pos < framelength - grainlength:
  while (1) {
    __pyx_t_3 = ((__pyx_v_write_pos < (__pyx_v_framelength - __pyx_v_grainlength)) != 0);
    if (!__pyx_t_3) break;
+056:         playhead = <double>write_pos / framelength
    if (unlikely(__pyx_v_framelength == 0)) {
      PyErr_SetString(PyExc_ZeroDivisionError, "float division");
      __PYX_ERR(0, 56, __pyx_L1_error)
    }
    __pyx_v_playhead = (((double)__pyx_v_write_pos) / ((double)__pyx_v_framelength));
 057: 
 058:         # Set (target) grain length
+059:         if cloud.grainlength_lfo is not None:
    if (unlikely(!__pyx_v_cloud->grainlength_lfo.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 59, __pyx_L1_error)}
    __pyx_t_3 = ((((PyObject *) __pyx_v_cloud->grainlength_lfo.memview) != Py_None) != 0);
    if (__pyx_t_3) {
/* … */
    }
+060:             grainlength_frac_pos = interpolation._linear_point(cloud.grainlength_lfo, playhead)
      if (unlikely(!__pyx_v_cloud->grainlength_lfo.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 60, __pyx_L1_error)}
      __pyx_v_grainlength_frac_pos = __pyx_f_5pippi_13interpolation__linear_point(__pyx_v_cloud->grainlength_lfo, __pyx_v_playhead);
 061: 
+062:             if cloud.jitter > 0:
      __pyx_t_3 = ((__pyx_v_cloud->jitter > 0.0) != 0);
      if (__pyx_t_3) {
/* … */
      }
+063:                 grainlength_frac_pos = grainlength_frac_pos * ((rand()/<double>RAND_MAX) * cloud.jitter + 1)
        __pyx_t_4 = rand();
        if (unlikely(((double)RAND_MAX) == 0)) {
          PyErr_SetString(PyExc_ZeroDivisionError, "float division");
          __PYX_ERR(0, 63, __pyx_L1_error)
        }
        __pyx_v_grainlength_frac_pos = (__pyx_v_grainlength_frac_pos * (((((double)__pyx_t_4) / ((double)RAND_MAX)) * __pyx_v_cloud->jitter) + 1.0));
 064: 
+065:             grainlength = <int>(((grainlength_frac_pos * (cloud.maxlength - cloud.minlength)) + cloud.minlength) * (cloud.samplerate / 1000.0))
      __pyx_v_grainlength = ((int)(((__pyx_v_grainlength_frac_pos * (__pyx_v_cloud->maxlength - __pyx_v_cloud->minlength)) + __pyx_v_cloud->minlength) * (((double)__pyx_v_cloud->samplerate) / 1000.0)));
+066:             max_read_pos = input_length - grainlength
      __pyx_v_max_read_pos = (__pyx_v_input_length - __pyx_v_grainlength);
 067: 
+068:         if grainlength < 0:
    __pyx_t_3 = ((__pyx_v_grainlength < 0) != 0);
    if (__pyx_t_3) {
/* … */
    }
+069:             print(grainlength, write_pos)
      __pyx_t_1 = __Pyx_PyInt_From_unsigned_long(__pyx_v_grainlength); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 69, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_5 = __Pyx_PyInt_From_int(__pyx_v_write_pos); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 69, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 69, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_GIVEREF(__pyx_t_1);
      PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_5);
      PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_5);
      __pyx_t_1 = 0;
      __pyx_t_5 = 0;
      __pyx_t_5 = __Pyx_PyObject_Call(__pyx_builtin_print, __pyx_t_6, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 69, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+070:             grainlength *= -1
      __pyx_v_grainlength = (__pyx_v_grainlength * -1L);
 071: 
 072:         # Get read position for _cut
+073:         if cloud.freeze >= 0:
    __pyx_t_3 = ((__pyx_v_cloud->freeze >= 0.0) != 0);
    if (__pyx_t_3) {
/* … */
      goto __pyx_L8;
    }
+074:             read_pos = (cloud.samplerate * cloud.freeze)
      __pyx_v_read_pos = (__pyx_v_cloud->samplerate * __pyx_v_cloud->freeze);
+075:             if read_pos > <double>max_read_pos:
      __pyx_t_3 = ((__pyx_v_read_pos > ((double)__pyx_v_max_read_pos)) != 0);
      if (__pyx_t_3) {
/* … */
      }
+076:                 read_pos = <double>max_read_pos
        __pyx_v_read_pos = ((double)__pyx_v_max_read_pos);
+077:             read_frac_pos = read_pos / <double>max_read_pos
      if (unlikely(((double)__pyx_v_max_read_pos) == 0)) {
        PyErr_SetString(PyExc_ZeroDivisionError, "float division");
        __PYX_ERR(0, 77, __pyx_L1_error)
      }
      __pyx_v_read_frac_pos = (__pyx_v_read_pos / ((double)__pyx_v_max_read_pos));
 078:         else:
+079:             read_frac_pos = interpolation._linear_point(cloud.read_lfo, playhead)
    /*else*/ {
      if (unlikely(!__pyx_v_cloud->read_lfo.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 79, __pyx_L1_error)}
      __pyx_v_read_frac_pos = __pyx_f_5pippi_13interpolation__linear_point(__pyx_v_cloud->read_lfo, __pyx_v_playhead);
    }
    __pyx_L8:;
 080: 
+081:         start = <int>(read_frac_pos * max_read_pos)
    __pyx_v_start = ((int)(__pyx_v_read_frac_pos * __pyx_v_max_read_pos));
 082: 
 083: 
 084:         # Get grain speed
+085:         if cloud.speed_lfo is not None:
    if (unlikely(!__pyx_v_cloud->speed_lfo.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 85, __pyx_L1_error)}
    __pyx_t_3 = ((((PyObject *) __pyx_v_cloud->speed_lfo.memview) != Py_None) != 0);
    if (__pyx_t_3) {
/* … */
    }
+086:             grain_speed = interpolation._linear_point(cloud.speed_lfo, playhead)
      if (unlikely(!__pyx_v_cloud->speed_lfo.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 86, __pyx_L1_error)}
      __pyx_v_grain_speed = __pyx_f_5pippi_13interpolation__linear_point(__pyx_v_cloud->speed_lfo, __pyx_v_playhead);
+087:             cloud.speed = (grain_speed * (cloud.maxspeed - cloud.minspeed)) + cloud.minspeed
      __pyx_v_cloud->speed = ((__pyx_v_grain_speed * (__pyx_v_cloud->maxspeed - __pyx_v_cloud->minspeed)) + __pyx_v_cloud->minspeed);
 088: 
 089: 
 090:         ############################
 091:         # Cut grain and pitch shift
+092:         if cloud.speed != 1:
    __pyx_t_3 = ((__pyx_v_cloud->speed != 1.0) != 0);
    if (__pyx_t_3) {
/* … */
      goto __pyx_L11;
    }
 093:             # Length of segment to copy from source buffer: grainlength * speed
 094:             #cloud.speed = cloud.speed if cloud.speed > cloud.minspeed else cloud.minspeed
 095:             #cloud.speed = cloud.speed if cloud.speed < cloud.maxspeed else cloud.maxspeed
+096:             preresample_grainlength = <unsigned long>(grainlength * cloud.speed)
      __pyx_v_preresample_grainlength = ((unsigned long)(__pyx_v_grainlength * __pyx_v_cloud->speed));
+097:             if preresample_grainlength > (framelength - start):
      __pyx_t_3 = ((__pyx_v_preresample_grainlength > (__pyx_v_framelength - __pyx_v_start)) != 0);
      if (__pyx_t_3) {
/* … */
      }
 098:                 # get min(available_length, preresample_length)
 099:                 # adjust target/grainlength to match speed based on available length
+100:                 preresample_grainlength = framelength - start
        __pyx_v_preresample_grainlength = (__pyx_v_framelength - __pyx_v_start);
+101:                 cloud.speed = <double>preresample_grainlength / grainlength
        if (unlikely(__pyx_v_grainlength == 0)) {
          PyErr_SetString(PyExc_ZeroDivisionError, "float division");
          __PYX_ERR(0, 101, __pyx_L1_error)
        }
        __pyx_v_cloud->speed = (((double)__pyx_v_preresample_grainlength) / ((double)__pyx_v_grainlength));
 102: 
 103: 
 104:             # TODO can probably init maxlength versions of these outside the loop,
 105:             # and reuse them in sequence (careful of gil-releasing...)
+106:             grain_pre = np.zeros((preresample_grainlength, cloud.channels), dtype='d')
      __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 106, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_zeros); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 106, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __pyx_t_5 = __Pyx_PyInt_From_unsigned_long(__pyx_v_preresample_grainlength); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 106, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_cloud->channels); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 106, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 106, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_GIVEREF(__pyx_t_5);
      PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5);
      __Pyx_GIVEREF(__pyx_t_1);
      PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_1);
      __pyx_t_5 = 0;
      __pyx_t_1 = 0;
      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 106, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_7);
      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_7);
      __pyx_t_7 = 0;
      __pyx_t_7 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 106, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_dtype, __pyx_n_u_d) < 0) __PYX_ERR(0, 106, __pyx_L1_error)
      __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_1, __pyx_t_7); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 106, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 106, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __PYX_XDEC_MEMVIEW(&__pyx_v_grain_pre, 1);
      __pyx_v_grain_pre = __pyx_t_8;
      __pyx_t_8.memview = NULL;
      __pyx_t_8.data = NULL;
+107:             grainchan_pre = np.zeros(preresample_grainlength, dtype='d')
      __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 107, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_zeros); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 107, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __pyx_t_5 = __Pyx_PyInt_From_unsigned_long(__pyx_v_preresample_grainlength); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 107, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 107, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_5);
      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_5);
      __pyx_t_5 = 0;
      __pyx_t_5 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 107, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      if (PyDict_SetItem(__pyx_t_5, __pyx_n_s_dtype, __pyx_n_u_d) < 0) __PYX_ERR(0, 107, __pyx_L1_error)
      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_1, __pyx_t_5); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 107, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_6, PyBUF_WRITABLE); if (unlikely(!__pyx_t_9.memview)) __PYX_ERR(0, 107, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __PYX_XDEC_MEMVIEW(&__pyx_v_grainchan_pre, 1);
      __pyx_v_grainchan_pre = __pyx_t_9;
      __pyx_t_9.memview = NULL;
      __pyx_t_9.data = NULL;
+108:             grain = np.zeros((grainlength, cloud.channels), dtype='d')
      __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 108, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_zeros); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 108, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __pyx_t_6 = __Pyx_PyInt_From_unsigned_long(__pyx_v_grainlength); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 108, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_cloud->channels); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 108, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 108, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_GIVEREF(__pyx_t_6);
      PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6);
      __Pyx_GIVEREF(__pyx_t_1);
      PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_1);
      __pyx_t_6 = 0;
      __pyx_t_1 = 0;
      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 108, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_7);
      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_7);
      __pyx_t_7 = 0;
      __pyx_t_7 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 108, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_dtype, __pyx_n_u_d) < 0) __PYX_ERR(0, 108, __pyx_L1_error)
      __pyx_t_6 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_1, __pyx_t_7); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 108, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(__pyx_t_6, PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 108, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __PYX_XDEC_MEMVIEW(&__pyx_v_grain, 1);
      __pyx_v_grain = __pyx_t_8;
      __pyx_t_8.memview = NULL;
      __pyx_t_8.data = NULL;
+109:             grainchan = np.zeros(grainlength, dtype='d')
      __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 109, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_n_s_zeros); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 109, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __pyx_t_6 = __Pyx_PyInt_From_unsigned_long(__pyx_v_grainlength); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 109, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 109, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_6);
      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_6);
      __pyx_t_6 = 0;
      __pyx_t_6 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 109, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_n_u_d) < 0) __PYX_ERR(0, 109, __pyx_L1_error)
      __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_7, __pyx_t_1, __pyx_t_6); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 109, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __pyx_t_9 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_9.memview)) __PYX_ERR(0, 109, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __PYX_XDEC_MEMVIEW(&__pyx_v_grainchan, 1);
      __pyx_v_grainchan = __pyx_t_9;
      __pyx_t_9.memview = NULL;
      __pyx_t_9.data = NULL;
 110: 
+111:             grain_pre = _cut(cloud.buf.frames, framelength, start, preresample_grainlength)
      if (unlikely(!__pyx_v_cloud->buf->frames.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 111, __pyx_L1_error)}
      __pyx_t_8 = __pyx_f_5pippi_11soundbuffer__cut(__pyx_v_cloud->buf->frames, __pyx_v_framelength, __pyx_v_start, __pyx_v_preresample_grainlength); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 111, __pyx_L1_error)
      __PYX_XDEC_MEMVIEW(&__pyx_v_grain_pre, 1);
      __pyx_v_grain_pre = __pyx_t_8;
      __pyx_t_8.memview = NULL;
      __pyx_t_8.data = NULL;
+112:             grain = _speed(grain_pre, grain, grainchan_pre, grainchan, cloud.channels)
      __pyx_t_8 = __pyx_f_5pippi_11soundbuffer__speed(__pyx_v_grain_pre, __pyx_v_grain, __pyx_v_grainchan_pre, __pyx_v_grainchan, __pyx_v_cloud->channels); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 112, __pyx_L1_error)
      __PYX_XDEC_MEMVIEW(&__pyx_v_grain, 1);
      __pyx_v_grain = __pyx_t_8;
      __pyx_t_8.memview = NULL;
      __pyx_t_8.data = NULL;
 113:         else:
+114:             grain = np.zeros((grainlength, cloud.channels), dtype='d')
    /*else*/ {
      __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 114, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_zeros); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 114, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __pyx_t_5 = __Pyx_PyInt_From_unsigned_long(__pyx_v_grainlength); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 114, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_cloud->channels); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 114, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 114, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_GIVEREF(__pyx_t_5);
      PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_5);
      __Pyx_GIVEREF(__pyx_t_1);
      PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_t_1);
      __pyx_t_5 = 0;
      __pyx_t_1 = 0;
      __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 114, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_GIVEREF(__pyx_t_7);
      PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_7);
      __pyx_t_7 = 0;
      __pyx_t_7 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 114, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      if (PyDict_SetItem(__pyx_t_7, __pyx_n_s_dtype, __pyx_n_u_d) < 0) __PYX_ERR(0, 114, __pyx_L1_error)
      __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_1, __pyx_t_7); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 114, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __pyx_t_8 = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(__pyx_t_5, PyBUF_WRITABLE); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 114, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __PYX_XDEC_MEMVIEW(&__pyx_v_grain, 1);
      __pyx_v_grain = __pyx_t_8;
      __pyx_t_8.memview = NULL;
      __pyx_t_8.data = NULL;
+115:             grain = _cut(cloud.buf.frames, framelength, start, grainlength)
      if (unlikely(!__pyx_v_cloud->buf->frames.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 115, __pyx_L1_error)}
      __pyx_t_8 = __pyx_f_5pippi_11soundbuffer__cut(__pyx_v_cloud->buf->frames, __pyx_v_framelength, __pyx_v_start, __pyx_v_grainlength); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 115, __pyx_L1_error)
      __PYX_XDEC_MEMVIEW(&__pyx_v_grain, 1);
      __pyx_v_grain = __pyx_t_8;
      __pyx_t_8.memview = NULL;
      __pyx_t_8.data = NULL;
    }
    __pyx_L11:;
 116: 
 117: 
 118:         # Apply grain window
+119:         grain = _env(grain, cloud.channels, cloud.win)
    if (unlikely(!__pyx_v_cloud->win.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 119, __pyx_L1_error)}
    __pyx_t_8 = __pyx_f_5pippi_11soundbuffer__env(__pyx_v_grain, __pyx_v_cloud->channels, __pyx_v_cloud->win); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 119, __pyx_L1_error)
    __PYX_XDEC_MEMVIEW(&__pyx_v_grain, 1);
    __pyx_v_grain = __pyx_t_8;
    __pyx_t_8.memview = NULL;
    __pyx_t_8.data = NULL;
 120: 
 121:         # Pan grain if spread > 0
+122:         if cloud.spread > 0:
    __pyx_t_3 = ((__pyx_v_cloud->spread > 0.0) != 0);
    if (__pyx_t_3) {
/* … */
    }
+123:             panpos = (rand()/<double>RAND_MAX) * cloud.spread + (0.5 - (cloud.spread * 0.5))
      __pyx_t_4 = rand();
      if (unlikely(((double)RAND_MAX) == 0)) {
        PyErr_SetString(PyExc_ZeroDivisionError, "float division");
        __PYX_ERR(0, 123, __pyx_L1_error)
      }
      __pyx_v_panpos = (((((double)__pyx_t_4) / ((double)RAND_MAX)) * __pyx_v_cloud->spread) + (0.5 - (__pyx_v_cloud->spread * 0.5)));
+124:             grain = _pan(grain, grainlength, cloud.channels, panpos, wavetables.CONSTANT)
      __pyx_t_8 = __pyx_f_5pippi_11soundbuffer__pan(__pyx_v_grain, __pyx_v_grainlength, __pyx_v_cloud->channels, __pyx_v_panpos, __pyx_v_5pippi_10wavetables_CONSTANT); if (unlikely(!__pyx_t_8.memview)) __PYX_ERR(0, 124, __pyx_L1_error)
      __PYX_XDEC_MEMVIEW(&__pyx_v_grain, 1);
      __pyx_v_grain = __pyx_t_8;
      __pyx_t_8.memview = NULL;
      __pyx_t_8.data = NULL;
 125: 
 126: 
 127:         # Dub grain to output
+128:         if write_pos + len(grain) < len(out):
    __pyx_t_10 = __Pyx_MemoryView_Len(__pyx_v_grain); 
    __pyx_t_11 = __Pyx_MemoryView_Len(__pyx_v_out); 
    __pyx_t_3 = (((__pyx_v_write_pos + __pyx_t_10) < __pyx_t_11) != 0);
    if (__pyx_t_3) {
/* … */
    }
+129:             for fi in range(len(grain)):
      __pyx_t_11 = __Pyx_MemoryView_Len(__pyx_v_grain); 
      __pyx_t_2 = __pyx_t_11;
      for (__pyx_t_4 = 0; __pyx_t_4 < __pyx_t_2; __pyx_t_4+=1) {
        __pyx_v_fi = __pyx_t_4;
+130:                 for ci in range(cloud.channels):
        __pyx_t_12 = __pyx_v_cloud->channels;
        __pyx_t_13 = __pyx_t_12;
        for (__pyx_t_14 = 0; __pyx_t_14 < __pyx_t_13; __pyx_t_14+=1) {
          __pyx_v_ci = __pyx_t_14;
+131:                     out[fi + write_pos, ci] += (grain[fi, ci] * cloud.amp)
          __pyx_t_15 = __pyx_v_fi;
          __pyx_t_16 = __pyx_v_ci;
          __pyx_t_17 = -1;
          if (__pyx_t_15 < 0) {
            __pyx_t_15 += __pyx_v_grain.shape[0];
            if (unlikely(__pyx_t_15 < 0)) __pyx_t_17 = 0;
          } else if (unlikely(__pyx_t_15 >= __pyx_v_grain.shape[0])) __pyx_t_17 = 0;
          if (__pyx_t_16 < 0) {
            __pyx_t_16 += __pyx_v_grain.shape[1];
            if (unlikely(__pyx_t_16 < 0)) __pyx_t_17 = 1;
          } else if (unlikely(__pyx_t_16 >= __pyx_v_grain.shape[1])) __pyx_t_17 = 1;
          if (unlikely(__pyx_t_17 != -1)) {
            __Pyx_RaiseBufferIndexError(__pyx_t_17);
            __PYX_ERR(0, 131, __pyx_L1_error)
          }
          __pyx_t_18 = (__pyx_v_fi + __pyx_v_write_pos);
          __pyx_t_19 = __pyx_v_ci;
          __pyx_t_17 = -1;
          if (__pyx_t_18 < 0) {
            __pyx_t_18 += __pyx_v_out.shape[0];
            if (unlikely(__pyx_t_18 < 0)) __pyx_t_17 = 0;
          } else if (unlikely(__pyx_t_18 >= __pyx_v_out.shape[0])) __pyx_t_17 = 0;
          if (__pyx_t_19 < 0) {
            __pyx_t_19 += __pyx_v_out.shape[1];
            if (unlikely(__pyx_t_19 < 0)) __pyx_t_17 = 1;
          } else if (unlikely(__pyx_t_19 >= __pyx_v_out.shape[1])) __pyx_t_17 = 1;
          if (unlikely(__pyx_t_17 != -1)) {
            __Pyx_RaiseBufferIndexError(__pyx_t_17);
            __PYX_ERR(0, 131, __pyx_L1_error)
          }
          *((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_out.data + __pyx_t_18 * __pyx_v_out.strides[0]) ) + __pyx_t_19 * __pyx_v_out.strides[1]) )) += ((*((double *) ( /* dim=1 */ (( /* dim=0 */ (__pyx_v_grain.data + __pyx_t_15 * __pyx_v_grain.strides[0]) ) + __pyx_t_16 * __pyx_v_grain.strides[1]) ))) * __pyx_v_cloud->amp);
        }
      }
 132: 
 133: 
 134:         # Get density for write_inc modulation
+135:         if cloud.density_lfo is not None:
    if (unlikely(!__pyx_v_cloud->density_lfo.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 135, __pyx_L1_error)}
    __pyx_t_3 = ((((PyObject *) __pyx_v_cloud->density_lfo.memview) != Py_None) != 0);
    if (__pyx_t_3) {
/* … */
      goto __pyx_L19;
    }
+136:             density_frac_pos = interpolation._linear_point(cloud.density_lfo, playhead)
      if (unlikely(!__pyx_v_cloud->density_lfo.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 136, __pyx_L1_error)}
      __pyx_v_density_frac_pos = __pyx_f_5pippi_13interpolation__linear_point(__pyx_v_cloud->density_lfo, __pyx_v_playhead);
+137:             density = (density_frac_pos * (cloud.maxdensity - cloud.mindensity)) + cloud.mindensity
      __pyx_v_density = ((__pyx_v_density_frac_pos * (__pyx_v_cloud->maxdensity - __pyx_v_cloud->mindensity)) + __pyx_v_cloud->mindensity);
 138:         else:
+139:             density = cloud.density
    /*else*/ {
      __pyx_t_20 = __pyx_v_cloud->density;
      __pyx_v_density = __pyx_t_20;
    }
    __pyx_L19:;
 140: 
 141:         # Increment write_pos based on grainlength & density
+142:         try:
    {
      /*try:*/ {
/* … */
      }
      __Pyx_XDECREF(__pyx_t_21); __pyx_t_21 = 0;
      __Pyx_XDECREF(__pyx_t_22); __pyx_t_22 = 0;
      __Pyx_XDECREF(__pyx_t_23); __pyx_t_23 = 0;
      goto __pyx_L27_try_end;
      __pyx_L20_error:;
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0;
      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
      __PYX_XDEC_MEMVIEW(&__pyx_t_8, 1);
      __PYX_XDEC_MEMVIEW(&__pyx_t_9, 1);
/* … */
      __Pyx_XGIVEREF(__pyx_t_21);
      __Pyx_XGIVEREF(__pyx_t_22);
      __Pyx_XGIVEREF(__pyx_t_23);
      __Pyx_ExceptionReset(__pyx_t_21, __pyx_t_22, __pyx_t_23);
      goto __pyx_L1_error;
      __pyx_L21_exception_handled:;
      __Pyx_XGIVEREF(__pyx_t_21);
      __Pyx_XGIVEREF(__pyx_t_22);
      __Pyx_XGIVEREF(__pyx_t_23);
      __Pyx_ExceptionReset(__pyx_t_21, __pyx_t_22, __pyx_t_23);
      __pyx_L27_try_end:;
    }
  }
+143:             cloud.grains_per_sec = <double>cloud.samplerate / (<double>len(grain) / 2.0)
        __pyx_t_11 = __Pyx_MemoryView_Len(__pyx_v_grain); 
        __pyx_t_20 = (((double)__pyx_t_11) / 2.0);
        if (unlikely(__pyx_t_20 == 0)) {
          PyErr_SetString(PyExc_ZeroDivisionError, "float division");
          __PYX_ERR(0, 143, __pyx_L20_error)
        }
        __pyx_v_cloud->grains_per_sec = (((double)__pyx_v_cloud->samplerate) / __pyx_t_20);
+144:             cloud.grains_per_sec *= density
        __pyx_v_cloud->grains_per_sec = (__pyx_v_cloud->grains_per_sec * __pyx_v_density);
+145:             write_inc = <int>(<double>cloud.samplerate / cloud.grains_per_sec)
        if (unlikely(__pyx_v_cloud->grains_per_sec == 0)) {
          PyErr_SetString(PyExc_ZeroDivisionError, "float division");
          __PYX_ERR(0, 145, __pyx_L20_error)
        }
        __pyx_v_write_inc = ((int)(((double)__pyx_v_cloud->samplerate) / __pyx_v_cloud->grains_per_sec));
+146:             if write_inc < MIN_GRAIN_FRAMELENGTH:
        __pyx_t_3 = ((__pyx_v_write_inc < 0x1B9) != 0);
        if (__pyx_t_3) {
/* … */
          goto __pyx_L28;
        }
+147:                 write_pos += MIN_GRAIN_FRAMELENGTH
          __pyx_v_write_pos = (__pyx_v_write_pos + 0x1B9);
 148:             else:
+149:                 write_pos += write_inc
        /*else*/ {
          __pyx_v_write_pos = (__pyx_v_write_pos + __pyx_v_write_inc);
        }
        __pyx_L28:;
+150:         except ZeroDivisionError:
      __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_ZeroDivisionError);
      if (__pyx_t_4) {
        __Pyx_AddTraceback("pippi.grains._play", __pyx_clineno, __pyx_lineno, __pyx_filename);
        if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_7, &__pyx_t_1) < 0) __PYX_ERR(0, 150, __pyx_L22_except_error)
        __Pyx_GOTREF(__pyx_t_5);
        __Pyx_GOTREF(__pyx_t_7);
        __Pyx_GOTREF(__pyx_t_1);
+151:             write_pos += MIN_GRAIN_FRAMELENGTH
        __pyx_v_write_pos = (__pyx_v_write_pos + 0x1B9);
        __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        goto __pyx_L21_exception_handled;
      }
      goto __pyx_L22_except_error;
      __pyx_L22_except_error:;
 152: 
+153:     return out
  __PYX_INC_MEMVIEW(&__pyx_v_out, 0);
  __pyx_r = __pyx_v_out;
  goto __pyx_L0;
 154: 
 155: 
+156: cdef class GrainCloud:
struct __pyx_vtabstruct_5pippi_6grains_GrainCloud {
  struct __pyx_obj_5pippi_11soundbuffer_SoundBuffer *(*play)(struct __pyx_obj_5pippi_6grains_GrainCloud *, int __pyx_skip_dispatch, struct __pyx_opt_args_5pippi_6grains_10GrainCloud_play *__pyx_optional_args);
};
static struct __pyx_vtabstruct_5pippi_6grains_GrainCloud *__pyx_vtabptr_5pippi_6grains_GrainCloud;

+157:     def __init__(self,
/* Python wrapper */
static int __pyx_pw_5pippi_6grains_10GrainCloud_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static int __pyx_pw_5pippi_6grains_10GrainCloud_1__init__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  struct __pyx_obj_5pippi_11soundbuffer_SoundBuffer *__pyx_v_buf = 0;
  int __pyx_v_win;
  __Pyx_memviewslice __pyx_v_win_wt = { 0, 0, { 0 }, { 0 }, { 0 } };
  int __pyx_v_win_length;
  PyObject *__pyx_v_mask = 0;
  double __pyx_v_freeze;
  int __pyx_v_read_lfo;
  PyObject *__pyx_v_read_lfo_wt = 0;
  double __pyx_v_read_lfo_speed;
  unsigned int __pyx_v_read_lfo_length;
  int __pyx_v_speed_lfo;
  __Pyx_memviewslice __pyx_v_speed_lfo_wt = { 0, 0, { 0 }, { 0 }, { 0 } };
  unsigned int __pyx_v_speed_lfo_length;
  double __pyx_v_speed;
  double __pyx_v_minspeed;
  double __pyx_v_maxspeed;
  int __pyx_v_density_lfo;
  __Pyx_memviewslice __pyx_v_density_lfo_wt = { 0, 0, { 0 }, { 0 }, { 0 } };
  int __pyx_v_density_lfo_length;
  double __pyx_v_density_lfo_speed;
  double __pyx_v_density;
  double __pyx_v_mindensity;
  double __pyx_v_maxdensity;
  double __pyx_v_grainlength;
  int __pyx_v_grainlength_lfo;
  __Pyx_memviewslice __pyx_v_grainlength_lfo_wt = { 0, 0, { 0 }, { 0 }, { 0 } };
  unsigned int __pyx_v_grainlength_lfo_length;
  double __pyx_v_grainlength_lfo_speed;
  double __pyx_v_minlength;
  double __pyx_v_maxlength;
  double __pyx_v_spread;
  double __pyx_v_jitter;
  double __pyx_v_amp;
  int __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__init__ (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_buf,&__pyx_n_s_win,&__pyx_n_s_win_wt,&__pyx_n_s_win_length,&__pyx_n_s_mask,&__pyx_n_s_freeze,&__pyx_n_s_read_lfo,&__pyx_n_s_read_lfo_wt,&__pyx_n_s_read_lfo_speed,&__pyx_n_s_read_lfo_length,&__pyx_n_s_speed_lfo,&__pyx_n_s_speed_lfo_wt,&__pyx_n_s_speed_lfo_length,&__pyx_n_s_speed,&__pyx_n_s_minspeed,&__pyx_n_s_maxspeed,&__pyx_n_s_density_lfo,&__pyx_n_s_density_lfo_wt,&__pyx_n_s_density_lfo_length,&__pyx_n_s_density_lfo_speed,&__pyx_n_s_density,&__pyx_n_s_mindensity,&__pyx_n_s_maxdensity,&__pyx_n_s_grainlength,&__pyx_n_s_grainlength_lfo,&__pyx_n_s_grainlength_lfo_wt,&__pyx_n_s_grainlength_lfo_length,&__pyx_n_s_grainlength_lfo_speed,&__pyx_n_s_minlength,&__pyx_n_s_maxlength,&__pyx_n_s_spread,&__pyx_n_s_jitter,&__pyx_n_s_amp,0};
    PyObject* values[33] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
/* … */
  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = -1;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static int __pyx_pf_5pippi_6grains_10GrainCloud___init__(struct __pyx_obj_5pippi_6grains_GrainCloud *__pyx_v_self, struct __pyx_obj_5pippi_11soundbuffer_SoundBuffer *__pyx_v_buf, int __pyx_v_win, __Pyx_memviewslice __pyx_v_win_wt, int __pyx_v_win_length, PyObject *__pyx_v_mask, double __pyx_v_freeze, int __pyx_v_read_lfo, PyObject *__pyx_v_read_lfo_wt, double __pyx_v_read_lfo_speed, unsigned int __pyx_v_read_lfo_length, int __pyx_v_speed_lfo, __Pyx_memviewslice __pyx_v_speed_lfo_wt, unsigned int __pyx_v_speed_lfo_length, double __pyx_v_speed, double __pyx_v_minspeed, double __pyx_v_maxspeed, int __pyx_v_density_lfo, __Pyx_memviewslice __pyx_v_density_lfo_wt, int __pyx_v_density_lfo_length, double __pyx_v_density_lfo_speed, double __pyx_v_density, double __pyx_v_mindensity, double __pyx_v_maxdensity, double __pyx_v_grainlength, int __pyx_v_grainlength_lfo, __Pyx_memviewslice __pyx_v_grainlength_lfo_wt, unsigned int __pyx_v_grainlength_lfo_length, double __pyx_v_grainlength_lfo_speed, double __pyx_v_minlength, double __pyx_v_maxlength, double __pyx_v_spread, double __pyx_v_jitter, double __pyx_v_amp) {
  arrayobject *__pyx_v_cmask = 0;
  int __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__init__", 0);
/* … */
  /* function exit code */
  __pyx_r = 0;
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __PYX_XDEC_MEMVIEW(&__pyx_t_6, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1);
  __Pyx_XDECREF(__pyx_t_9);
  __Pyx_XDECREF(__pyx_t_10);
  __PYX_XDEC_MEMVIEW(&__pyx_t_11, 1);
  __Pyx_AddTraceback("pippi.grains.GrainCloud.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = -1;
  __pyx_L0:;
  __Pyx_XDECREF((PyObject *)__pyx_v_cmask);
  __PYX_XDEC_MEMVIEW(&__pyx_v_win_wt, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_speed_lfo_wt, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_density_lfo_wt, 1);
  __PYX_XDEC_MEMVIEW(&__pyx_v_grainlength_lfo_wt, 1);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 158:             SoundBuffer buf,
 159: 
 160:             int win=-1,
+161:             double[:] win_wt=None,
  __pyx_t_2 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(Py_None, PyBUF_WRITABLE); if (unlikely(!__pyx_t_2.memview)) __PYX_ERR(0, 161, __pyx_L1_error)
  __pyx_k_ = __pyx_t_2;
  __pyx_t_2.memview = NULL;
  __pyx_t_2.data = NULL;
 162:             int win_length=DEFAULT_WTSIZE,
 163: 
+164:             list mask=None,
    values[4] = ((PyObject*)Py_None);
 165: 
 166:             double freeze=-1,
 167:             int read_lfo=-1,
+168:             object read_lfo_wt=None,
    values[7] = ((PyObject *)Py_None);
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case 33: values[32] = PyTuple_GET_ITEM(__pyx_args, 32);
        CYTHON_FALLTHROUGH;
        case 32: values[31] = PyTuple_GET_ITEM(__pyx_args, 31);
        CYTHON_FALLTHROUGH;
        case 31: values[30] = PyTuple_GET_ITEM(__pyx_args, 30);
        CYTHON_FALLTHROUGH;
        case 30: values[29] = PyTuple_GET_ITEM(__pyx_args, 29);
        CYTHON_FALLTHROUGH;
        case 29: values[28] = PyTuple_GET_ITEM(__pyx_args, 28);
        CYTHON_FALLTHROUGH;
        case 28: values[27] = PyTuple_GET_ITEM(__pyx_args, 27);
        CYTHON_FALLTHROUGH;
        case 27: values[26] = PyTuple_GET_ITEM(__pyx_args, 26);
        CYTHON_FALLTHROUGH;
        case 26: values[25] = PyTuple_GET_ITEM(__pyx_args, 25);
        CYTHON_FALLTHROUGH;
        case 25: values[24] = PyTuple_GET_ITEM(__pyx_args, 24);
        CYTHON_FALLTHROUGH;
        case 24: values[23] = PyTuple_GET_ITEM(__pyx_args, 23);
        CYTHON_FALLTHROUGH;
        case 23: values[22] = PyTuple_GET_ITEM(__pyx_args, 22);
        CYTHON_FALLTHROUGH;
        case 22: values[21] = PyTuple_GET_ITEM(__pyx_args, 21);
        CYTHON_FALLTHROUGH;
        case 21: values[20] = PyTuple_GET_ITEM(__pyx_args, 20);
        CYTHON_FALLTHROUGH;
        case 20: values[19] = PyTuple_GET_ITEM(__pyx_args, 19);
        CYTHON_FALLTHROUGH;
        case 19: values[18] = PyTuple_GET_ITEM(__pyx_args, 18);
        CYTHON_FALLTHROUGH;
        case 18: values[17] = PyTuple_GET_ITEM(__pyx_args, 17);
        CYTHON_FALLTHROUGH;
        case 17: values[16] = PyTuple_GET_ITEM(__pyx_args, 16);
        CYTHON_FALLTHROUGH;
        case 16: values[15] = PyTuple_GET_ITEM(__pyx_args, 15);
        CYTHON_FALLTHROUGH;
        case 15: values[14] = PyTuple_GET_ITEM(__pyx_args, 14);
        CYTHON_FALLTHROUGH;
        case 14: values[13] = PyTuple_GET_ITEM(__pyx_args, 13);
        CYTHON_FALLTHROUGH;
        case 13: values[12] = PyTuple_GET_ITEM(__pyx_args, 12);
        CYTHON_FALLTHROUGH;
        case 12: values[11] = PyTuple_GET_ITEM(__pyx_args, 11);
        CYTHON_FALLTHROUGH;
        case 11: values[10] = PyTuple_GET_ITEM(__pyx_args, 10);
        CYTHON_FALLTHROUGH;
        case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9);
        CYTHON_FALLTHROUGH;
        case  9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
        CYTHON_FALLTHROUGH;
        case  8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
        CYTHON_FALLTHROUGH;
        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
        CYTHON_FALLTHROUGH;
        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
        CYTHON_FALLTHROUGH;
        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_buf)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_win);
          if (value) { values[1] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_win_wt);
          if (value) { values[2] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_win_length);
          if (value) { values[3] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  4:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mask);
          if (value) { values[4] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  5:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_freeze);
          if (value) { values[5] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  6:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_read_lfo);
          if (value) { values[6] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  7:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_read_lfo_wt);
          if (value) { values[7] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  8:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_read_lfo_speed);
          if (value) { values[8] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  9:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_read_lfo_length);
          if (value) { values[9] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 10:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_speed_lfo);
          if (value) { values[10] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 11:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_speed_lfo_wt);
          if (value) { values[11] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 12:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_speed_lfo_length);
          if (value) { values[12] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 13:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_speed);
          if (value) { values[13] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 14:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_minspeed);
          if (value) { values[14] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 15:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_maxspeed);
          if (value) { values[15] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 16:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_density_lfo);
          if (value) { values[16] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 17:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_density_lfo_wt);
          if (value) { values[17] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 18:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_density_lfo_length);
          if (value) { values[18] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 19:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_density_lfo_speed);
          if (value) { values[19] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 20:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_density);
          if (value) { values[20] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 21:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_mindensity);
          if (value) { values[21] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 22:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_maxdensity);
          if (value) { values[22] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 23:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_grainlength);
          if (value) { values[23] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 24:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_grainlength_lfo);
          if (value) { values[24] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 25:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_grainlength_lfo_wt);
          if (value) { values[25] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 26:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_grainlength_lfo_length);
          if (value) { values[26] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 27:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_grainlength_lfo_speed);
          if (value) { values[27] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 28:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_minlength);
          if (value) { values[28] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 29:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_maxlength);
          if (value) { values[29] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 30:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_spread);
          if (value) { values[30] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 31:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_jitter);
          if (value) { values[31] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case 32:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_amp);
          if (value) { values[32] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__init__") < 0)) __PYX_ERR(0, 157, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case 33: values[32] = PyTuple_GET_ITEM(__pyx_args, 32);
        CYTHON_FALLTHROUGH;
        case 32: values[31] = PyTuple_GET_ITEM(__pyx_args, 31);
        CYTHON_FALLTHROUGH;
        case 31: values[30] = PyTuple_GET_ITEM(__pyx_args, 30);
        CYTHON_FALLTHROUGH;
        case 30: values[29] = PyTuple_GET_ITEM(__pyx_args, 29);
        CYTHON_FALLTHROUGH;
        case 29: values[28] = PyTuple_GET_ITEM(__pyx_args, 28);
        CYTHON_FALLTHROUGH;
        case 28: values[27] = PyTuple_GET_ITEM(__pyx_args, 27);
        CYTHON_FALLTHROUGH;
        case 27: values[26] = PyTuple_GET_ITEM(__pyx_args, 26);
        CYTHON_FALLTHROUGH;
        case 26: values[25] = PyTuple_GET_ITEM(__pyx_args, 25);
        CYTHON_FALLTHROUGH;
        case 25: values[24] = PyTuple_GET_ITEM(__pyx_args, 24);
        CYTHON_FALLTHROUGH;
        case 24: values[23] = PyTuple_GET_ITEM(__pyx_args, 23);
        CYTHON_FALLTHROUGH;
        case 23: values[22] = PyTuple_GET_ITEM(__pyx_args, 22);
        CYTHON_FALLTHROUGH;
        case 22: values[21] = PyTuple_GET_ITEM(__pyx_args, 21);
        CYTHON_FALLTHROUGH;
        case 21: values[20] = PyTuple_GET_ITEM(__pyx_args, 20);
        CYTHON_FALLTHROUGH;
        case 20: values[19] = PyTuple_GET_ITEM(__pyx_args, 19);
        CYTHON_FALLTHROUGH;
        case 19: values[18] = PyTuple_GET_ITEM(__pyx_args, 18);
        CYTHON_FALLTHROUGH;
        case 18: values[17] = PyTuple_GET_ITEM(__pyx_args, 17);
        CYTHON_FALLTHROUGH;
        case 17: values[16] = PyTuple_GET_ITEM(__pyx_args, 16);
        CYTHON_FALLTHROUGH;
        case 16: values[15] = PyTuple_GET_ITEM(__pyx_args, 15);
        CYTHON_FALLTHROUGH;
        case 15: values[14] = PyTuple_GET_ITEM(__pyx_args, 14);
        CYTHON_FALLTHROUGH;
        case 14: values[13] = PyTuple_GET_ITEM(__pyx_args, 13);
        CYTHON_FALLTHROUGH;
        case 13: values[12] = PyTuple_GET_ITEM(__pyx_args, 12);
        CYTHON_FALLTHROUGH;
        case 12: values[11] = PyTuple_GET_ITEM(__pyx_args, 11);
        CYTHON_FALLTHROUGH;
        case 11: values[10] = PyTuple_GET_ITEM(__pyx_args, 10);
        CYTHON_FALLTHROUGH;
        case 10: values[9] = PyTuple_GET_ITEM(__pyx_args, 9);
        CYTHON_FALLTHROUGH;
        case  9: values[8] = PyTuple_GET_ITEM(__pyx_args, 8);
        CYTHON_FALLTHROUGH;
        case  8: values[7] = PyTuple_GET_ITEM(__pyx_args, 7);
        CYTHON_FALLTHROUGH;
        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
        CYTHON_FALLTHROUGH;
        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
        CYTHON_FALLTHROUGH;
        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_buf = ((struct __pyx_obj_5pippi_11soundbuffer_SoundBuffer *)values[0]);
    if (values[1]) {
      __pyx_v_win = __Pyx_PyInt_As_int(values[1]); if (unlikely((__pyx_v_win == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 160, __pyx_L3_error)
    } else {
      __pyx_v_win = ((int)-1);
    }
    if (values[2]) {
      __pyx_v_win_wt = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[2], PyBUF_WRITABLE); if (unlikely(!__pyx_v_win_wt.memview)) __PYX_ERR(0, 161, __pyx_L3_error)
    } else {
      __pyx_v_win_wt = __pyx_k_;
      __PYX_INC_MEMVIEW(&__pyx_v_win_wt, 1);
    }
    if (values[3]) {
      __pyx_v_win_length = __Pyx_PyInt_As_int(values[3]); if (unlikely((__pyx_v_win_length == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 162, __pyx_L3_error)
    } else {
      __pyx_v_win_length = ((int)0x1000);
    }
    __pyx_v_mask = ((PyObject*)values[4]);
    if (values[5]) {
      __pyx_v_freeze = __pyx_PyFloat_AsDouble(values[5]); if (unlikely((__pyx_v_freeze == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 166, __pyx_L3_error)
    } else {
      __pyx_v_freeze = ((double)-1.0);
    }
    if (values[6]) {
      __pyx_v_read_lfo = __Pyx_PyInt_As_int(values[6]); if (unlikely((__pyx_v_read_lfo == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 167, __pyx_L3_error)
    } else {
      __pyx_v_read_lfo = ((int)-1);
    }
    __pyx_v_read_lfo_wt = values[7];
    if (values[8]) {
      __pyx_v_read_lfo_speed = __pyx_PyFloat_AsDouble(values[8]); if (unlikely((__pyx_v_read_lfo_speed == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 169, __pyx_L3_error)
    } else {
      __pyx_v_read_lfo_speed = ((double)1.0);
    }
    if (values[9]) {
      __pyx_v_read_lfo_length = __Pyx_PyInt_As_unsigned_int(values[9]); if (unlikely((__pyx_v_read_lfo_length == (unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 170, __pyx_L3_error)
    } else {
      __pyx_v_read_lfo_length = ((unsigned int)0x1000);
    }
    if (values[10]) {
      __pyx_v_speed_lfo = __Pyx_PyInt_As_int(values[10]); if (unlikely((__pyx_v_speed_lfo == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 172, __pyx_L3_error)
    } else {
      __pyx_v_speed_lfo = ((int)-1);
    }
    if (values[11]) {
      __pyx_v_speed_lfo_wt = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[11], PyBUF_WRITABLE); if (unlikely(!__pyx_v_speed_lfo_wt.memview)) __PYX_ERR(0, 173, __pyx_L3_error)
    } else {
      __pyx_v_speed_lfo_wt = __pyx_k__2;
      __PYX_INC_MEMVIEW(&__pyx_v_speed_lfo_wt, 1);
    }
    if (values[12]) {
      __pyx_v_speed_lfo_length = __Pyx_PyInt_As_unsigned_int(values[12]); if (unlikely((__pyx_v_speed_lfo_length == (unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 174, __pyx_L3_error)
    } else {
      __pyx_v_speed_lfo_length = ((unsigned int)0x1000);
    }
    if (values[13]) {
      __pyx_v_speed = __pyx_PyFloat_AsDouble(values[13]); if (unlikely((__pyx_v_speed == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 175, __pyx_L3_error)
    } else {
      __pyx_v_speed = ((double)1.0);
    }
    if (values[14]) {
      __pyx_v_minspeed = __pyx_PyFloat_AsDouble(values[14]); if (unlikely((__pyx_v_minspeed == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 176, __pyx_L3_error)
    } else {
      __pyx_v_minspeed = ((double)1.0);
    }
    if (values[15]) {
      __pyx_v_maxspeed = __pyx_PyFloat_AsDouble(values[15]); if (unlikely((__pyx_v_maxspeed == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 177, __pyx_L3_error)
    } else {
      __pyx_v_maxspeed = ((double)2.0);
    }
    if (values[16]) {
      __pyx_v_density_lfo = __Pyx_PyInt_As_int(values[16]); if (unlikely((__pyx_v_density_lfo == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 179, __pyx_L3_error)
    } else {
      __pyx_v_density_lfo = ((int)-1);
    }
    if (values[17]) {
      __pyx_v_density_lfo_wt = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[17], PyBUF_WRITABLE); if (unlikely(!__pyx_v_density_lfo_wt.memview)) __PYX_ERR(0, 180, __pyx_L3_error)
    } else {
      __pyx_v_density_lfo_wt = __pyx_k__3;
      __PYX_INC_MEMVIEW(&__pyx_v_density_lfo_wt, 1);
    }
    if (values[18]) {
      __pyx_v_density_lfo_length = __Pyx_PyInt_As_int(values[18]); if (unlikely((__pyx_v_density_lfo_length == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 181, __pyx_L3_error)
    } else {
      __pyx_v_density_lfo_length = ((int)0x1000);
    }
    if (values[19]) {
      __pyx_v_density_lfo_speed = __pyx_PyFloat_AsDouble(values[19]); if (unlikely((__pyx_v_density_lfo_speed == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 182, __pyx_L3_error)
    } else {
      __pyx_v_density_lfo_speed = ((double)1.0);
    }
    if (values[20]) {
      __pyx_v_density = __pyx_PyFloat_AsDouble(values[20]); if (unlikely((__pyx_v_density == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 183, __pyx_L3_error)
    } else {
      __pyx_v_density = ((double)1.0);
    }
    if (values[21]) {
      __pyx_v_mindensity = __pyx_PyFloat_AsDouble(values[21]); if (unlikely((__pyx_v_mindensity == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 184, __pyx_L3_error)
    } else {
      __pyx_v_mindensity = ((double)0.5);
    }
    if (values[22]) {
      __pyx_v_maxdensity = __pyx_PyFloat_AsDouble(values[22]); if (unlikely((__pyx_v_maxdensity == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 185, __pyx_L3_error)
    } else {
      __pyx_v_maxdensity = ((double)1.5);
    }
    if (values[23]) {
      __pyx_v_grainlength = __pyx_PyFloat_AsDouble(values[23]); if (unlikely((__pyx_v_grainlength == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 187, __pyx_L3_error)
    } else {
      __pyx_v_grainlength = ((double)60.0);
    }
    if (values[24]) {
      __pyx_v_grainlength_lfo = __Pyx_PyInt_As_int(values[24]); if (unlikely((__pyx_v_grainlength_lfo == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 188, __pyx_L3_error)
    } else {
      __pyx_v_grainlength_lfo = ((int)-1);
    }
    if (values[25]) {
      __pyx_v_grainlength_lfo_wt = __Pyx_PyObject_to_MemoryviewSlice_ds_double(values[25], PyBUF_WRITABLE); if (unlikely(!__pyx_v_grainlength_lfo_wt.memview)) __PYX_ERR(0, 189, __pyx_L3_error)
    } else {
      __pyx_v_grainlength_lfo_wt = __pyx_k__4;
      __PYX_INC_MEMVIEW(&__pyx_v_grainlength_lfo_wt, 1);
    }
    if (values[26]) {
      __pyx_v_grainlength_lfo_length = __Pyx_PyInt_As_unsigned_int(values[26]); if (unlikely((__pyx_v_grainlength_lfo_length == (unsigned int)-1) && PyErr_Occurred())) __PYX_ERR(0, 190, __pyx_L3_error)
    } else {
      __pyx_v_grainlength_lfo_length = ((unsigned int)0x1000);
    }
    if (values[27]) {
      __pyx_v_grainlength_lfo_speed = __pyx_PyFloat_AsDouble(values[27]); if (unlikely((__pyx_v_grainlength_lfo_speed == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 191, __pyx_L3_error)
    } else {
      __pyx_v_grainlength_lfo_speed = ((double)1.0);
    }
    if (values[28]) {
      __pyx_v_minlength = __pyx_PyFloat_AsDouble(values[28]); if (unlikely((__pyx_v_minlength == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 193, __pyx_L3_error)
    } else {
      __pyx_v_minlength = ((double)60.0);
    }
    if (values[29]) {
      __pyx_v_maxlength = __pyx_PyFloat_AsDouble(values[29]); if (unlikely((__pyx_v_maxlength == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 194, __pyx_L3_error)
    } else {
      __pyx_v_maxlength = ((double)80.0);
    }
    if (values[30]) {
      __pyx_v_spread = __pyx_PyFloat_AsDouble(values[30]); if (unlikely((__pyx_v_spread == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 195, __pyx_L3_error)
    } else {
      __pyx_v_spread = ((double)0.0);
    }
    if (values[31]) {
      __pyx_v_jitter = __pyx_PyFloat_AsDouble(values[31]); if (unlikely((__pyx_v_jitter == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 196, __pyx_L3_error)
    } else {
      __pyx_v_jitter = ((double)0.0);
    }
    if (values[32]) {
      __pyx_v_amp = __pyx_PyFloat_AsDouble(values[32]); if (unlikely((__pyx_v_amp == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 197, __pyx_L3_error)
    } else {
      __pyx_v_amp = ((double)1.0);
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("__init__", 0, 1, 33, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 157, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("pippi.grains.GrainCloud.__init__", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return -1;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_buf), __pyx_ptype_5pippi_11soundbuffer_SoundBuffer, 1, "buf", 0))) __PYX_ERR(0, 158, __pyx_L1_error)
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_mask), (&PyList_Type), 1, "mask", 1))) __PYX_ERR(0, 164, __pyx_L1_error)
  __pyx_r = __pyx_pf_5pippi_6grains_10GrainCloud___init__(((struct __pyx_obj_5pippi_6grains_GrainCloud *)__pyx_v_self), __pyx_v_buf, __pyx_v_win, __pyx_v_win_wt, __pyx_v_win_length, __pyx_v_mask, __pyx_v_freeze, __pyx_v_read_lfo, __pyx_v_read_lfo_wt, __pyx_v_read_lfo_speed, __pyx_v_read_lfo_length, __pyx_v_speed_lfo, __pyx_v_speed_lfo_wt, __pyx_v_speed_lfo_length, __pyx_v_speed, __pyx_v_minspeed, __pyx_v_maxspeed, __pyx_v_density_lfo, __pyx_v_density_lfo_wt, __pyx_v_density_lfo_length, __pyx_v_density_lfo_speed, __pyx_v_density, __pyx_v_mindensity, __pyx_v_maxdensity, __pyx_v_grainlength, __pyx_v_grainlength_lfo, __pyx_v_grainlength_lfo_wt, __pyx_v_grainlength_lfo_length, __pyx_v_grainlength_lfo_speed, __pyx_v_minlength, __pyx_v_maxlength, __pyx_v_spread, __pyx_v_jitter, __pyx_v_amp);
 169:             double read_lfo_speed=1,
 170:             unsigned int read_lfo_length=DEFAULT_WTSIZE,
 171: 
 172:             int speed_lfo=-1,
+173:             double[:] speed_lfo_wt=None,
  __pyx_t_2 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(Py_None, PyBUF_WRITABLE); if (unlikely(!__pyx_t_2.memview)) __PYX_ERR(0, 173, __pyx_L1_error)
  __pyx_k__2 = __pyx_t_2;
  __pyx_t_2.memview = NULL;
  __pyx_t_2.data = NULL;
 174:             unsigned int speed_lfo_length=DEFAULT_WTSIZE,
 175:             double speed=DEFAULT_SPEED,
 176:             double minspeed=DEFAULT_SPEED,
 177:             double maxspeed=DEFAULT_MAXSPEED,
 178: 
 179:             int density_lfo=-1,
+180:             double[:] density_lfo_wt=None,
  __pyx_t_2 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(Py_None, PyBUF_WRITABLE); if (unlikely(!__pyx_t_2.memview)) __PYX_ERR(0, 180, __pyx_L1_error)
  __pyx_k__3 = __pyx_t_2;
  __pyx_t_2.memview = NULL;
  __pyx_t_2.data = NULL;
 181:             int density_lfo_length=DEFAULT_WTSIZE,
 182:             double density_lfo_speed=1,
 183:             double density=DEFAULT_DENSITY,
 184:             double mindensity=DEFAULT_MINDENSITY,
 185:             double maxdensity=DEFAULT_MAXDENSITY,
 186: 
 187:             double grainlength=DEFAULT_GRAINLENGTH,
 188:             int grainlength_lfo=-1,
+189:             double[:] grainlength_lfo_wt=None,
  __pyx_t_2 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(Py_None, PyBUF_WRITABLE); if (unlikely(!__pyx_t_2.memview)) __PYX_ERR(0, 189, __pyx_L1_error)
  __pyx_k__4 = __pyx_t_2;
  __pyx_t_2.memview = NULL;
  __pyx_t_2.data = NULL;
 190:             unsigned int grainlength_lfo_length=DEFAULT_WTSIZE,
 191:             double grainlength_lfo_speed=1,
 192: 
 193:             double minlength=DEFAULT_GRAINLENGTH,    # min grain length in ms
 194:             double maxlength=DEFAULT_MAXGRAINLENGTH,    # max grain length in ms
 195:             double spread=0,        # 0 = no panning, 1 = max random panning
 196:             double jitter=0,        # rhythm 0=regular, 1=totally random
 197:             double amp=1,
 198:         ):
 199: 
+200:         if spread < 0:
  __pyx_t_1 = ((__pyx_v_spread < 0.0) != 0);
  if (__pyx_t_1) {
/* … */
    goto __pyx_L3;
  }
+201:             spread = 0
    __pyx_v_spread = 0.0;
+202:         elif spread > 1:
  __pyx_t_1 = ((__pyx_v_spread > 1.0) != 0);
  if (__pyx_t_1) {
/* … */
  }
  __pyx_L3:;
+203:             spread = 1
    __pyx_v_spread = 1.0;
 204: 
+205:         self.buf = buf
  __Pyx_INCREF(((PyObject *)__pyx_v_buf));
  __Pyx_GIVEREF(((PyObject *)__pyx_v_buf));
  __Pyx_GOTREF(__pyx_v_self->buf);
  __Pyx_DECREF(((PyObject *)__pyx_v_self->buf));
  __pyx_v_self->buf = __pyx_v_buf;
+206:         self.channels = buf.channels
  __pyx_t_2 = __pyx_v_buf->channels;
  __pyx_v_self->channels = __pyx_t_2;
+207:         self.samplerate = buf.samplerate
  __pyx_t_2 = __pyx_v_buf->samplerate;
  __pyx_v_self->samplerate = __pyx_t_2;
+208:         self.spread = spread
  __pyx_v_self->spread = __pyx_v_spread;
+209:         self.jitter = jitter
  __pyx_v_self->jitter = __pyx_v_jitter;
+210:         self.freeze = freeze
  __pyx_v_self->freeze = __pyx_v_freeze;
+211:         self.amp = amp
  __pyx_v_self->amp = __pyx_v_amp;
 212: 
 213:         cdef array.array cmask
+214:         if mask is not None:
  __pyx_t_1 = (__pyx_v_mask != ((PyObject*)Py_None));
  __pyx_t_3 = (__pyx_t_1 != 0);
  if (__pyx_t_3) {
/* … */
  }
+215:             cmask = array.array('i', mask)
    __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 215, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_INCREF(__pyx_n_u_i);
    __Pyx_GIVEREF(__pyx_n_u_i);
    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_n_u_i);
    __Pyx_INCREF(__pyx_v_mask);
    __Pyx_GIVEREF(__pyx_v_mask);
    PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_v_mask);
    __pyx_t_5 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_7cpython_5array_array), __pyx_t_4, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 215, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_v_cmask = ((arrayobject *)__pyx_t_5);
    __pyx_t_5 = 0;
+216:             self.mask = cmask
    __pyx_t_6 = __Pyx_PyObject_to_MemoryviewSlice_ds_int(((PyObject *)__pyx_v_cmask), PyBUF_WRITABLE); if (unlikely(!__pyx_t_6.memview)) __PYX_ERR(0, 216, __pyx_L1_error)
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->mask, 0);
    __pyx_v_self->mask = __pyx_t_6;
    __pyx_t_6.memview = NULL;
    __pyx_t_6.data = NULL;
 217: 
 218:         # Window is always a wavetable, defaults to Hann
+219:         if win > -1:
  __pyx_t_3 = ((__pyx_v_win > -1L) != 0);
  if (__pyx_t_3) {
/* … */
    goto __pyx_L5;
  }
+220:             self.win = wavetables._window(win, win_length)
    __pyx_t_7 = __pyx_f_5pippi_10wavetables__window(__pyx_v_win, __pyx_v_win_length); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 220, __pyx_L1_error)
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->win, 0);
    __pyx_v_self->win = __pyx_t_7;
    __pyx_t_7.memview = NULL;
    __pyx_t_7.data = NULL;
+221:         elif win_wt is not None:
  __pyx_t_3 = ((((PyObject *) __pyx_v_win_wt.memview) != Py_None) != 0);
  if (__pyx_t_3) {
/* … */
    goto __pyx_L5;
  }
+222:             self.win = win_wt
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->win, 0);
    __PYX_INC_MEMVIEW(&__pyx_v_win_wt, 0);
    __pyx_v_self->win = __pyx_v_win_wt;
 223:         else:
+224:             self.win = wavetables._window(wavetables.HANN, win_length)
  /*else*/ {
    __pyx_t_7 = __pyx_f_5pippi_10wavetables__window(__pyx_v_5pippi_10wavetables_HANN, __pyx_v_win_length); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 224, __pyx_L1_error)
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->win, 0);
    __pyx_v_self->win = __pyx_t_7;
    __pyx_t_7.memview = NULL;
    __pyx_t_7.data = NULL;
  }
  __pyx_L5:;
+225:         self.win_length = len(self.win)
  if (unlikely(!__pyx_v_self->win.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 225, __pyx_L1_error)}
  __pyx_t_8 = __Pyx_MemoryView_Len(__pyx_v_self->win); 
  __pyx_v_self->win_length = __pyx_t_8;
 226: 
 227:         # Read lfo is always a wavetable, defaults to phasor
+228:         if read_lfo > -1:
  __pyx_t_3 = ((__pyx_v_read_lfo > -1L) != 0);
  if (__pyx_t_3) {
/* … */
    goto __pyx_L6;
  }
+229:             self.read_lfo = wavetables._window(read_lfo, read_lfo_length)
    __pyx_t_7 = __pyx_f_5pippi_10wavetables__window(__pyx_v_read_lfo, __pyx_v_read_lfo_length); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 229, __pyx_L1_error)
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->read_lfo, 0);
    __pyx_v_self->read_lfo = __pyx_t_7;
    __pyx_t_7.memview = NULL;
    __pyx_t_7.data = NULL;
+230:         elif read_lfo_wt is not None:
  __pyx_t_3 = (__pyx_v_read_lfo_wt != Py_None);
  __pyx_t_1 = (__pyx_t_3 != 0);
  if (__pyx_t_1) {
/* … */
    goto __pyx_L6;
  }
+231:             self.read_lfo = interpolation._linear(np.asarray(read_lfo_wt, dtype='d'), read_lfo_length)
    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 231, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_asarray); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 231, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_t_5 = PyTuple_New(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 231, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_INCREF(__pyx_v_read_lfo_wt);
    __Pyx_GIVEREF(__pyx_v_read_lfo_wt);
    PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_v_read_lfo_wt);
    __pyx_t_9 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 231, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_9);
    if (PyDict_SetItem(__pyx_t_9, __pyx_n_s_dtype, __pyx_n_u_d) < 0) __PYX_ERR(0, 231, __pyx_L1_error)
    __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_5, __pyx_t_9); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 231, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_10);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
    __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(__pyx_t_10, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 231, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
    __pyx_t_11 = __pyx_f_5pippi_13interpolation__linear(__pyx_t_7, __pyx_v_read_lfo_length); if (unlikely(!__pyx_t_11.memview)) __PYX_ERR(0, 231, __pyx_L1_error)
    __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1);
    __pyx_t_7.memview = NULL;
    __pyx_t_7.data = NULL;
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->read_lfo, 0);
    __pyx_v_self->read_lfo = __pyx_t_11;
    __pyx_t_11.memview = NULL;
    __pyx_t_11.data = NULL;
 232:         else:
+233:             self.read_lfo = wavetables._window(wavetables.PHASOR, read_lfo_length)
  /*else*/ {
    __pyx_t_11 = __pyx_f_5pippi_10wavetables__window(__pyx_v_5pippi_10wavetables_PHASOR, __pyx_v_read_lfo_length); if (unlikely(!__pyx_t_11.memview)) __PYX_ERR(0, 233, __pyx_L1_error)
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->read_lfo, 0);
    __pyx_v_self->read_lfo = __pyx_t_11;
    __pyx_t_11.memview = NULL;
    __pyx_t_11.data = NULL;
  }
  __pyx_L6:;
 234: 
+235:         self.read_lfo_speed = read_lfo_speed
  __pyx_v_self->read_lfo_speed = __pyx_v_read_lfo_speed;
+236:         self.read_lfo_length = read_lfo_length
  __pyx_v_self->read_lfo_length = __pyx_v_read_lfo_length;
 237: 
 238:         # If speed_lfo < 0 and speed_lfo_wt is None, then use fixed speed
 239:         # No transposition is done if speed == 1
+240:         if speed_lfo > -1:
  __pyx_t_1 = ((__pyx_v_speed_lfo > -1L) != 0);
  if (__pyx_t_1) {
/* … */
    goto __pyx_L7;
  }
+241:             self.speed_lfo = wavetables._window(speed_lfo, speed_lfo_length)
    __pyx_t_11 = __pyx_f_5pippi_10wavetables__window(__pyx_v_speed_lfo, __pyx_v_speed_lfo_length); if (unlikely(!__pyx_t_11.memview)) __PYX_ERR(0, 241, __pyx_L1_error)
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->speed_lfo, 0);
    __pyx_v_self->speed_lfo = __pyx_t_11;
    __pyx_t_11.memview = NULL;
    __pyx_t_11.data = NULL;
+242:         elif speed_lfo_wt is not None:
  __pyx_t_1 = ((((PyObject *) __pyx_v_speed_lfo_wt.memview) != Py_None) != 0);
  if (__pyx_t_1) {
/* … */
    goto __pyx_L7;
  }
+243:             self.speed_lfo = speed_lfo_wt
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->speed_lfo, 0);
    __PYX_INC_MEMVIEW(&__pyx_v_speed_lfo_wt, 0);
    __pyx_v_self->speed_lfo = __pyx_v_speed_lfo_wt;
 244:         else:
+245:             self.speed_lfo = None
  /*else*/ {
    __pyx_t_11 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(Py_None, PyBUF_WRITABLE); if (unlikely(!__pyx_t_11.memview)) __PYX_ERR(0, 245, __pyx_L1_error)
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->speed_lfo, 0);
    __pyx_v_self->speed_lfo = __pyx_t_11;
    __pyx_t_11.memview = NULL;
    __pyx_t_11.data = NULL;
  }
  __pyx_L7:;
 246: 
+247:         if self.speed_lfo is not None:
  if (unlikely(!__pyx_v_self->speed_lfo.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 247, __pyx_L1_error)}
  __pyx_t_1 = ((((PyObject *) __pyx_v_self->speed_lfo.memview) != Py_None) != 0);
  if (__pyx_t_1) {
/* … */
  }
+248:             self.speed_lfo_length = len(self.speed_lfo)
    if (unlikely(!__pyx_v_self->speed_lfo.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 248, __pyx_L1_error)}
    __pyx_t_8 = __Pyx_MemoryView_Len(__pyx_v_self->speed_lfo); 
    __pyx_v_self->speed_lfo_length = __pyx_t_8;
 249: 
+250:         if speed <= 0:
  __pyx_t_1 = ((__pyx_v_speed <= 0.0) != 0);
  if (__pyx_t_1) {
/* … */
  }
+251:             speed = MIN_SPEED
    __pyx_v_speed = 1e-06;
 252: 
+253:         if minspeed <= 0:
  __pyx_t_1 = ((__pyx_v_minspeed <= 0.0) != 0);
  if (__pyx_t_1) {
/* … */
  }
+254:             minspeed = MIN_SPEED
    __pyx_v_minspeed = 1e-06;
 255: 
+256:         if maxspeed <= 0:
  __pyx_t_1 = ((__pyx_v_maxspeed <= 0.0) != 0);
  if (__pyx_t_1) {
/* … */
  }
+257:             maxspeed = MIN_SPEED
    __pyx_v_maxspeed = 1e-06;
 258: 
+259:         self.speed = speed
  __pyx_v_self->speed = __pyx_v_speed;
+260:         self.minspeed = minspeed
  __pyx_v_self->minspeed = __pyx_v_minspeed;
+261:         self.maxspeed = maxspeed
  __pyx_v_self->maxspeed = __pyx_v_maxspeed;
 262: 
+263:         self.density = density
  __pyx_v_self->density = __pyx_v_density;
+264:         self.mindensity = mindensity
  __pyx_v_self->mindensity = __pyx_v_mindensity;
+265:         self.maxdensity = maxdensity
  __pyx_v_self->maxdensity = __pyx_v_maxdensity;
+266:         if density_lfo > -1:
  __pyx_t_1 = ((__pyx_v_density_lfo > -1L) != 0);
  if (__pyx_t_1) {
/* … */
    goto __pyx_L12;
  }
+267:             self.density_lfo = wavetables._window(density_lfo, density_lfo_length)
    __pyx_t_11 = __pyx_f_5pippi_10wavetables__window(__pyx_v_density_lfo, __pyx_v_density_lfo_length); if (unlikely(!__pyx_t_11.memview)) __PYX_ERR(0, 267, __pyx_L1_error)
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->density_lfo, 0);
    __pyx_v_self->density_lfo = __pyx_t_11;
    __pyx_t_11.memview = NULL;
    __pyx_t_11.data = NULL;
+268:         elif density_lfo_wt is not None:
  __pyx_t_1 = ((((PyObject *) __pyx_v_density_lfo_wt.memview) != Py_None) != 0);
  if (__pyx_t_1) {
/* … */
    goto __pyx_L12;
  }
+269:             self.density_lfo = density_lfo_wt
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->density_lfo, 0);
    __PYX_INC_MEMVIEW(&__pyx_v_density_lfo_wt, 0);
    __pyx_v_self->density_lfo = __pyx_v_density_lfo_wt;
 270:         else:
+271:             self.density_lfo = None
  /*else*/ {
    __pyx_t_11 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(Py_None, PyBUF_WRITABLE); if (unlikely(!__pyx_t_11.memview)) __PYX_ERR(0, 271, __pyx_L1_error)
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->density_lfo, 0);
    __pyx_v_self->density_lfo = __pyx_t_11;
    __pyx_t_11.memview = NULL;
    __pyx_t_11.data = NULL;
  }
  __pyx_L12:;
 272: 
+273:         self.density_lfo_speed = density_lfo_speed
  __pyx_v_self->density_lfo_speed = __pyx_v_density_lfo_speed;
+274:         if self.density_lfo is not None:
  if (unlikely(!__pyx_v_self->density_lfo.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 274, __pyx_L1_error)}
  __pyx_t_1 = ((((PyObject *) __pyx_v_self->density_lfo.memview) != Py_None) != 0);
  if (__pyx_t_1) {
/* … */
  }
+275:             self.density_lfo_length = len(self.density_lfo)
    if (unlikely(!__pyx_v_self->density_lfo.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 275, __pyx_L1_error)}
    __pyx_t_8 = __Pyx_MemoryView_Len(__pyx_v_self->density_lfo); 
    __pyx_v_self->density_lfo_length = __pyx_t_8;
 276: 
+277:         if grainlength_lfo > -1:
  __pyx_t_1 = ((__pyx_v_grainlength_lfo > -1L) != 0);
  if (__pyx_t_1) {
/* … */
    goto __pyx_L14;
  }
+278:             self.grainlength_lfo = wavetables._window(grainlength_lfo, grainlength_lfo_length)
    __pyx_t_11 = __pyx_f_5pippi_10wavetables__window(__pyx_v_grainlength_lfo, __pyx_v_grainlength_lfo_length); if (unlikely(!__pyx_t_11.memview)) __PYX_ERR(0, 278, __pyx_L1_error)
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->grainlength_lfo, 0);
    __pyx_v_self->grainlength_lfo = __pyx_t_11;
    __pyx_t_11.memview = NULL;
    __pyx_t_11.data = NULL;
+279:             self.grainlength = -1
    __pyx_v_self->grainlength = -1.0;
+280:         elif grainlength_lfo_wt is not None:
  __pyx_t_1 = ((((PyObject *) __pyx_v_grainlength_lfo_wt.memview) != Py_None) != 0);
  if (__pyx_t_1) {
/* … */
    goto __pyx_L14;
  }
+281:             self.grainlength_lfo = grainlength_lfo_wt
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->grainlength_lfo, 0);
    __PYX_INC_MEMVIEW(&__pyx_v_grainlength_lfo_wt, 0);
    __pyx_v_self->grainlength_lfo = __pyx_v_grainlength_lfo_wt;
 282:         else:
+283:             self.grainlength_lfo = None
  /*else*/ {
    __pyx_t_11 = __Pyx_PyObject_to_MemoryviewSlice_ds_double(Py_None, PyBUF_WRITABLE); if (unlikely(!__pyx_t_11.memview)) __PYX_ERR(0, 283, __pyx_L1_error)
    __PYX_XDEC_MEMVIEW(&__pyx_v_self->grainlength_lfo, 0);
    __pyx_v_self->grainlength_lfo = __pyx_t_11;
    __pyx_t_11.memview = NULL;
    __pyx_t_11.data = NULL;
  }
  __pyx_L14:;
 284: 
+285:         self.grainlength = grainlength
  __pyx_v_self->grainlength = __pyx_v_grainlength;
+286:         self.minlength = minlength
  __pyx_v_self->minlength = __pyx_v_minlength;
+287:         self.maxlength = maxlength
  __pyx_v_self->maxlength = __pyx_v_maxlength;
+288:         self.grainlength_lfo_speed = grainlength_lfo_speed
  __pyx_v_self->grainlength_lfo_speed = __pyx_v_grainlength_lfo_speed;
+289:         if self.grainlength_lfo is not None:
  if (unlikely(!__pyx_v_self->grainlength_lfo.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 289, __pyx_L1_error)}
  __pyx_t_1 = ((((PyObject *) __pyx_v_self->grainlength_lfo.memview) != Py_None) != 0);
  if (__pyx_t_1) {
/* … */
  }
+290:             self.grainlength_lfo_length = len(self.grainlength_lfo)
    if (unlikely(!__pyx_v_self->grainlength_lfo.memview)) {PyErr_SetString(PyExc_AttributeError,"Memoryview is not initialized");__PYX_ERR(0, 290, __pyx_L1_error)}
    __pyx_t_8 = __Pyx_MemoryView_Len(__pyx_v_self->grainlength_lfo); 
    __pyx_v_self->grainlength_lfo_length = __pyx_t_8;
 291: 
+292:     cpdef SoundBuffer play(GrainCloud self, double length=10):
static PyObject *__pyx_pw_5pippi_6grains_10GrainCloud_3play(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static struct __pyx_obj_5pippi_11soundbuffer_SoundBuffer *__pyx_f_5pippi_6grains_10GrainCloud_play(struct __pyx_obj_5pippi_6grains_GrainCloud *__pyx_v_self, int __pyx_skip_dispatch, struct __pyx_opt_args_5pippi_6grains_10GrainCloud_play *__pyx_optional_args) {
  double __pyx_v_length = ((double)10.0);
  int __pyx_v_framelength;
  __Pyx_memviewslice __pyx_v_out = { 0, 0, { 0 }, { 0 }, { 0 } };
  struct __pyx_obj_5pippi_11soundbuffer_SoundBuffer *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("play", 0);
  if (__pyx_optional_args) {
    if (__pyx_optional_args->__pyx_n > 0) {
      __pyx_v_length = __pyx_optional_args->length;
    }
  }
  /* Check if called by wrapper */
  if (unlikely(__pyx_skip_dispatch)) ;
  /* Check if overridden in Python */
  else if (unlikely(Py_TYPE(((PyObject *)__pyx_v_self))->tp_dictoffset != 0)) {
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_play); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 292, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    if (!PyCFunction_Check(__pyx_t_1) || (PyCFunction_GET_FUNCTION(__pyx_t_1) != (PyCFunction)__pyx_pw_5pippi_6grains_10GrainCloud_3play)) {
      __Pyx_XDECREF(((PyObject *)__pyx_r));
      __pyx_t_3 = PyFloat_FromDouble(__pyx_v_length); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 292, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_1);
      __pyx_t_4 = __pyx_t_1; __pyx_t_5 = NULL;
      if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
        __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4);
        if (likely(__pyx_t_5)) {
          PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
          __Pyx_INCREF(__pyx_t_5);
          __Pyx_INCREF(function);
          __Pyx_DECREF_SET(__pyx_t_4, function);
        }
      }
      if (!__pyx_t_5) {
        __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 292, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        __Pyx_GOTREF(__pyx_t_2);
      } else {
        #if CYTHON_FAST_PYCALL
        if (PyFunction_Check(__pyx_t_4)) {
          PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
          __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 292, __pyx_L1_error)
          __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
          __Pyx_GOTREF(__pyx_t_2);
          __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        } else
        #endif
        #if CYTHON_FAST_PYCCALL
        if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
          PyObject *__pyx_temp[2] = {__pyx_t_5, __pyx_t_3};
          __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 292, __pyx_L1_error)
          __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
          __Pyx_GOTREF(__pyx_t_2);
          __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
        } else
        #endif
        {
          __pyx_t_6 = PyTuple_New(1+1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 292, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_6);
          __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_5); __pyx_t_5 = NULL;
          __Pyx_GIVEREF(__pyx_t_3);
          PyTuple_SET_ITEM(__pyx_t_6, 0+1, __pyx_t_3);
          __pyx_t_3 = 0;
          __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 292, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_2);
          __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
        }
      }
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      if (!(likely(((__pyx_t_2) == Py_None) || likely(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5pippi_11soundbuffer_SoundBuffer))))) __PYX_ERR(0, 292, __pyx_L1_error)
      __pyx_r = ((struct __pyx_obj_5pippi_11soundbuffer_SoundBuffer *)__pyx_t_2);
      __pyx_t_2 = 0;
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      goto __pyx_L0;
    }
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  }
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __PYX_XDEC_MEMVIEW(&__pyx_t_7, 1);
  __Pyx_AddTraceback("pippi.grains.GrainCloud.play", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = 0;
  __pyx_L0:;
  __PYX_XDEC_MEMVIEW(&__pyx_v_out, 1);
  __Pyx_XGIVEREF((PyObject *)__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

/* Python wrapper */
static PyObject *__pyx_pw_5pippi_6grains_10GrainCloud_3play(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyObject *__pyx_pw_5pippi_6grains_10GrainCloud_3play(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  double __pyx_v_length;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("play (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_length,0};
    PyObject* values[1] = {0};
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_length);
          if (value) { values[0] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "play") < 0)) __PYX_ERR(0, 292, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    if (values[0]) {
      __pyx_v_length = __pyx_PyFloat_AsDouble(values[0]); if (unlikely((__pyx_v_length == (double)-1) && PyErr_Occurred())) __PYX_ERR(0, 292, __pyx_L3_error)
    } else {
      __pyx_v_length = ((double)10.0);
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("play", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 292, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("pippi.grains.GrainCloud.play", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_5pippi_6grains_10GrainCloud_2play(((struct __pyx_obj_5pippi_6grains_GrainCloud *)__pyx_v_self), __pyx_v_length);

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_5pippi_6grains_10GrainCloud_2play(struct __pyx_obj_5pippi_6grains_GrainCloud *__pyx_v_self, double __pyx_v_length) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("play", 0);
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_2.__pyx_n = 1;
  __pyx_t_2.length = __pyx_v_length;
  __pyx_t_1 = ((PyObject *)__pyx_vtabptr_5pippi_6grains_GrainCloud->play(__pyx_v_self, 1, &__pyx_t_2)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 292, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_AddTraceback("pippi.grains.GrainCloud.play", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
+293:         cdef int framelength = <int>(self.samplerate * length)
  __pyx_v_framelength = ((int)(__pyx_v_self->samplerate * __pyx_v_length));
+294:         cdef double[:,:] out = np.zeros((framelength, self.channels), dtype='d')
  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_np); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 294, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_zeros); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 294, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyInt_From_int(__pyx_v_framelength); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 294, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_self->channels); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 294, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_6 = PyTuple_New(2); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 294, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_4);
  __pyx_t_1 = 0;
  __pyx_t_4 = 0;
  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 294, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_6);
  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_6);
  __pyx_t_6 = 0;
  __pyx_t_6 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 294, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  if (PyDict_SetItem(__pyx_t_6, __pyx_n_s_dtype, __pyx_n_u_d) < 0) __PYX_ERR(0, 294, __pyx_L1_error)
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 294, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_t_7 = __Pyx_PyObject_to_MemoryviewSlice_dsds_double(__pyx_t_1, PyBUF_WRITABLE); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 294, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_v_out = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
+295:         out = _play(self, out, framelength, length)
  __pyx_t_7 = __pyx_f_5pippi_6grains__play(__pyx_v_self, __pyx_v_out, __pyx_v_framelength, __pyx_v_length); if (unlikely(!__pyx_t_7.memview)) __PYX_ERR(0, 295, __pyx_L1_error)
  __PYX_XDEC_MEMVIEW(&__pyx_v_out, 1);
  __pyx_v_out = __pyx_t_7;
  __pyx_t_7.memview = NULL;
  __pyx_t_7.data = NULL;
+296:         return SoundBuffer(out, length=length, channels=self.channels, samplerate=self.samplerate)
  __Pyx_XDECREF(((PyObject *)__pyx_r));
  __pyx_t_1 = __pyx_memoryview_fromslice(__pyx_v_out, 2, (PyObject *(*)(char *)) __pyx_memview_get_double, (int (*)(char *, PyObject *)) __pyx_memview_set_double, 0);; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 296, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_6 = PyTuple_New(1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 296, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 296, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_4 = PyFloat_FromDouble(__pyx_v_length); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 296, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_length, __pyx_t_4) < 0) __PYX_ERR(0, 296, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_self->channels); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 296, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_channels, __pyx_t_4) < 0) __PYX_ERR(0, 296, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyInt_From_int(__pyx_v_self->samplerate); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 296, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_samplerate, __pyx_t_4) < 0) __PYX_ERR(0, 296, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = __Pyx_PyObject_Call(((PyObject *)__pyx_ptype_5pippi_11soundbuffer_SoundBuffer), __pyx_t_6, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 296, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_r = ((struct __pyx_obj_5pippi_11soundbuffer_SoundBuffer *)__pyx_t_4);
  __pyx_t_4 = 0;
  goto __pyx_L0;
 297: 
 298: 
 299: