M banner.png => banner.png +0 -0
D pippi/grains.pxd => pippi/grains.pxd +0 -25
@@ 1,25 0,0 @@
-#cython: language_level=3
-
-#from pippi.ugens.core cimport ugen_t
-
-cdef class Cloud:
- cdef double[:,:] snd
- cdef unsigned int framelength
- cdef double length
- cdef unsigned int channels
- cdef unsigned int samplerate
-
- cdef unsigned int wtsize
-
- cdef double[:] window
- cdef double[:] position
- cdef double[:] amp
- cdef double[:] speed
- cdef double[:] spread
- cdef double[:] jitter
- cdef double[:] grainlength
- cdef double[:] grid
-
- cdef int[:] mask
- cdef bint has_mask
-
D pippi/grains.pyx => pippi/grains.pyx +0 -224
@@ 1,224 0,0 @@
-#cython: language_level=3
-
-from pippi.wavetables cimport HANN, PHASOR, to_window, to_wavetable, Wavetable
-from pippi cimport interpolation
-from pippi.soundbuffer cimport SoundBuffer
-from libc.stdlib cimport rand, RAND_MAX, malloc, free
-import numpy as np
-cimport cython
-from cpython cimport array
-import array
-
-@cython.boundscheck(False)
-@cython.wraparound(False)
-cdef inline double _linear_pos(double[:] data, double phase) nogil:
- cdef int dlength = <int>len(data)
- phase *= <double>(dlength-1)
-
- if dlength == 1:
- return data[0]
-
- elif dlength < 1:
- return 0
-
- cdef double frac = phase - <long>phase
- cdef long i = <long>phase
- cdef double a, b
-
- if i >= dlength-1:
- return 0
-
- a = data[i]
- b = data[i+1]
-
- return (1.0 - frac) * a + (frac * b)
-
-@cython.boundscheck(False)
-@cython.wraparound(False)
-@cython.cdivision(True)
-cdef double[:,:] _speed(double speed, double[:,:] original, double[:,:] out, int channels) nogil:
- cdef unsigned int inlength = len(original)
- cdef unsigned int outlength = len(out)
- cdef double phase_inc = (1.0/inlength) * (inlength-1) * speed
- cdef double phase = 0, pos = 0
- cdef int c = 0, i = 0
-
- for i in range(outlength):
- for c in range(channels):
- out[i,c] = interpolation._linear_point(original[:,c], phase)
-
- phase += phase_inc * speed
- if phase >= inlength:
- break
-
- return out
-
-cdef class Cloud:
- def __cinit__(self,
- SoundBuffer snd,
- object window=None,
- object position=None,
- object amp=1.0,
- object speed=1.0,
- object spread=0.0,
- object jitter=0.0,
- object grainlength=0.2,
- object grid=None,
- object mask=None,
- unsigned int wtsize=4096,
- ):
-
- self.snd = snd.frames
- self.framelength = <unsigned int>len(snd)
- self.length = <double>(self.framelength / <double>snd.samplerate)
- self.channels = <unsigned int>snd.channels
- self.samplerate = <unsigned int>snd.samplerate
-
- self.wtsize = wtsize
-
- if window is None:
- window = 'sine'
- self.window = to_window(window)
-
- if position is None:
- self.position = Wavetable('phasor', 0, 1, window=True).data
- else:
- self.position = to_window(position)
-
- self.amp = to_window(amp)
- self.speed = to_window(speed)
- self.spread = to_window(spread)
- self.jitter = to_wavetable(jitter)
- self.grainlength = to_window(grainlength)
-
- if grid is None:
- self.grid = np.multiply(self.grainlength, 0.3)
- else:
- self.grid = to_window(grid)
-
- if mask is None:
- self.has_mask = False
- else:
- self.has_mask = True
- self.mask = array.array('i', mask)
-
- def play(self, double length):
- cdef double[:] grid = np.divide(self.grid, length)
- cdef unsigned int outframelength = <unsigned int>(self.samplerate * length)
- cdef double[:,:] out = np.zeros((outframelength, self.channels), dtype='d')
- cdef unsigned int write_pos=0
- cdef unsigned int read_pos=0
- cdef unsigned int grainlength
- cdef double pos = 0
- cdef double grainpos = 0
- cdef double panpos = 0
- cdef double sample = 0
- cdef double spread = 0
- cdef double speed, amp
- cdef unsigned int write_boundry = outframelength-1
- cdef unsigned int read_boundry = len(self.snd)-1
- cdef unsigned int masklength = 0
- cdef unsigned int count = 0
-
- cdef int i, c
-
- cdef double minspeed = min(self.speed)
- cdef unsigned long maxgrainlength = <unsigned long>(max(self.grainlength) * self.samplerate)
- cdef double[:,:] grain = np.zeros((maxgrainlength, self.channels), dtype='d')
- cdef double[:,:] grainresamp
- cdef unsigned int resamplength
-
- if self.has_mask:
- masklength = <unsigned int>len(self.mask)
-
- cdef int grain_window_index
- cdef double grain_window_pos
- cdef double grain_window_frac
-
- while pos <= 1:
- write_pos = <unsigned int>(pos * write_boundry)
- write_jitter = <int>(_linear_pos(self.jitter, pos) * (rand()/<double>RAND_MAX) * self.samplerate)
- write_pos += max(-write_jitter, write_jitter)
-
- if self.has_mask and self.mask[<int>(count % masklength)] == 0:
- pos += _linear_pos(grid, pos)
- count += 1
- continue
-
- grainlength = <unsigned int>(_linear_pos(self.grainlength, pos) * self.samplerate)
- if write_pos + grainlength > write_boundry:
- break
-
- speed = _linear_pos(self.speed, pos)
- read_pos = <unsigned int>(_linear_pos(self.position, pos) * (read_boundry-grainlength))
- spread = _linear_pos(self.spread, pos)
- panpos = (rand()/<double>RAND_MAX) * spread + (0.5 - (spread * 0.5))
- pans = [panpos, 1-panpos]
-
- for i in range(grainlength):
- grainpos = <double>i / (grainlength-1)
- amp = <double>_linear_pos(self.amp, pos)
-
- """
- cdef int dlength = <int>len(data)
- phase *= <double>(dlength-1)
-
- if dlength == 1:
- return data[0]
-
- elif dlength < 1:
- return 0
-
- cdef double frac = phase - <long>phase
- cdef long i = <long>phase
- cdef double a, b
-
- if i >= dlength-1:
- return 0
-
- a = data[i]
- b = data[i+1]
-
- return (1.0 - frac) * a + (frac * b)
- """
-
- grain_window_pos = grainpos * (len(self.window)-2)
- grain_window_index = <int>grain_window_pos
- grain_window_frac = grain_window_pos - grain_window_index
-
- amp *= (1.0 - grain_window_frac) * self.window[grain_window_index] + (grain_window_frac * self.window[grain_window_index+1])
-
- #amp *= _linear_pos(self.window, grainpos)
-
- if read_pos + i > read_boundry:
- break
-
- for c in range(self.channels):
- panpos = pans[c % 2]
- grain[i,c] = self.snd[read_pos+i, c] * amp
-
- if speed != 1:
- resamplength = <unsigned int>(grainlength * (1.0/speed))
- grainresamp = np.zeros((resamplength, self.channels), dtype='d')
-
- grainresamp = _speed(speed, grain, grainresamp, <int>self.channels)
- grainlength = <unsigned int>(grainlength * (1.0/speed))
-
- for i in range(resamplength):
- if write_pos+i > write_boundry:
- break
-
- for c in range(self.channels):
- out[write_pos+i, c] += grainresamp[i,c]
-
- else:
- for i in range(grainlength):
- for c in range(self.channels):
- out[write_pos+i, c] += grain[i,c]
-
- pos += _linear_pos(grid, pos)
- count += 1
-
- return SoundBuffer(out, channels=self.channels, samplerate=self.samplerate)
-
-
M pippi/soundbuffer.pyx => pippi/soundbuffer.pyx +0 -2
@@ 20,7 20,6 @@ from pippi cimport fft
from pippi import graph
from pippi.defaults cimport DEFAULT_SAMPLERATE, DEFAULT_CHANNELS, DEFAULT_SOUNDFILE, PI
from pippi cimport grains2
-from pippi cimport grains
from pippi cimport soundpipe
np.import_array()
@@ 716,7 715,6 @@ cdef class SoundBuffer:
""" Create a new Cloud from this SoundBuffer
"""
return grains2.Cloud2(self, *args, **kwargs).play(length)
- #return grains.Cloud(self, *args, **kwargs).play(length)
def copy(self):
""" Return a new copy of this SoundBuffer.
M setup.py => setup.py +0 -7
@@ 68,12 68,6 @@ ext_modules = cythonize([
include_dirs=INCLUDES + ['libpippi/vendor/fft'],
define_macros=MACROS
),
- Extension('pippi.grains', ['pippi/grains.pyx'],
- libraries=['soundpipe'],
- library_dirs=['/usr/local/lib'],
- include_dirs=INCLUDES,
- define_macros=MACROS
- ),
Extension('pippi.grains2', [
'libpippi/src/pippicore.c',
'libpippi/src/oscs.tape.c',
@@ 83,7 77,6 @@ ext_modules = cythonize([
include_dirs=INCLUDES,
define_macros=MACROS
),
-
Extension('pippi.lists', ['pippi/lists.pyx'],
include_dirs=INCLUDES,
define_macros=MACROS
M tests/test_graincloud.py => tests/test_graincloud.py +3 -29
@@ 5,7 5,7 @@ import tempfile
from unittest import TestCase
from pippi.soundbuffer import SoundBuffer
-from pippi import dsp, grains, grains2, fx, shapes
+from pippi import dsp, grains2, fx, shapes
class TestCloud(TestCase):
def setUp(self):
@@ 36,40 36,24 @@ class TestCloud(TestCase):
out.write('tests/renders/graincloud_libpippi_grainlength_modulated.wav')
def test_user_window(self):
- # Alix Dobkin
snd = dsp.read('tests/sounds/living.wav')
- length = 12
+ length = 2
- # right half of a sharply tapered hann window, basically
win = dsp.win('pluckout').taper(dsp.randint(10, 100))
-
- # empty buffer 2x the length of the sample
out = dsp.buffer(length=length, channels=snd.channels, samplerate=snd.samplerate)
- # four layers of grains
for _ in range(4):
- # grain playback speed
speed = shapes.win('sine', dsp.rand(0.125, 0.5), dsp.rand(1, 2))
-
amp = shapes.win('sine', 0.3, 1)
-
- # stereo spread
spread = shapes.win('sine', 0, 1)
-
- # start increment in seconds
grid = shapes.win('sine', -1, 1, length=dsp.rand(1, 10))
-
- # length of the grain in seconds
grainlength = shapes.win('sine', dsp.MS*1, 0.4, length=dsp.rand(1, 10))
gridjitter = shapes.win('sine', 0, 1)
grainjitter = shapes.win('sine', 0, 1)
-
- # pulsewidth of the grain window between 0 & 1
pulsewidth = shapes.win('sine', 0.5, 2)
- # render the layer
layer = snd.cloud(length,
amp=amp,
window=win,
@@ 84,22 68,15 @@ class TestCloud(TestCase):
gridmaxjitter=dsp.rand(0.01,1),
gridjitter=gridjitter,
)
-
- # and dub it into the output buffer
out.dub(layer)
- # squish
out = fx.compressor(out*8, -15, 15)
out = fx.norm(out, 1)
-
- # done
out.write('tests/renders/graincloud_libpippi_user_window.wav')
def test_phase_modulation(self):
snd = dsp.read('tests/sounds/living.wav')
- phase = [1,0.5,1,0,0.5]
- phase = 3
- out = snd.cloud(snd.dur*2, grainlength=0.1, phase=phase)
+ out = snd.cloud(snd.dur*2, grainlength=0.1, phase=0.3)
out = fx.norm(out, 1)
out.write('tests/renders/graincloud_libpippi_phase_modulated.wav')
@@ 116,8 93,6 @@ class TestCloud(TestCase):
out = fx.norm(out, 1)
out.write('tests/renders/graincloud_libpippi_speed_modulated.wav')
-
- """
def test_libpippi_pulsed_graincloud(self):
sound = SoundBuffer(filename='tests/sounds/living.wav')
out = sound.cloud(10, grainlength=0.06, grid=0.12)
@@ 185,4 160,3 @@ class TestCloud(TestCase):
)
out.write('tests/renders/graincloud_libpippi_grainsize.wav')
- """
M tests/test_shapes.py => tests/test_shapes.py +1 -1
@@ 47,7 47,7 @@ class TestShapes(TestCase):
grid=grid,
speed=dsp.win(shapes.win('sine', length=1), 0.03, 2),
spread='rnd',
- jitter='rnd'
+ grainjitter='rnd'
)
out.write('tests/renders/shape_pulsar.wav')