Example #1
0
def linear_envelope(start_amp, end_amp, width):
    ''' Generate an envelope, which spans some line.

    Args:
        start_amp - starting amplitude of envelope
        end_amp - ending amplitude of envelope
        width - floating point #/chunks wide that the envelope is

    Yields:
        A numpy array representing a linear envelope.
    '''
    #FIXME: width should be a note duration, not a multiple of chunk size
    #FIXME: need a way to end attack early to start release, for short notes
    chunk_size = oscil.get_chunk_size()
    last_amp = start_amp
    slope = (end_amp - start_amp) / width
    for pos in it.count(chunk_size, chunk_size):
        amp =  slope * pos
        samples = np.linspace(last_amp, amp, chunk_size, False)

        if pos > width:
            overlap = slice(width - pos, None)
            samples[overlap] = 1
            yield samples
            raise StopIteration
        yield samples
        last_amp = amp
Example #2
0
def multiply(*args, **kwargs):
    '''Produces a wave that is the product of all supplied waves.

    Args:
        *args - see _do_op()
        **kwargs - see _do_op()
    Returns:
        Wave chunk yielded by _do_op() operation.
    '''
    fill = np.ones(oscil.get_chunk_size())
    return _do_op(functools.partial(np.prod, axis=0), "multiply", fill, *args, **kwargs)
Example #3
0
def add(*args, **kwargs):
    '''Produces a wave that is the sum of all supplied waves.

    Args:
        *args - see _do_op()
        **kwargs - see _do_op()
    Returns:
        Wave chunk yielded by _do_op() operation.
    '''
    fill = np.zeros(oscil.get_chunk_size())
    return _do_op(functools.partial(np.sum, axis=0), "add", fill, *args, **kwargs)
Example #4
0
def filter(wave, taps):
    '''This FIR filter *appproximation* is of too poor quality to be of use. '''
    highpass = 0
    if taps < 0:
        taps = -taps
        highpass = 1

    buff = np.zeros(taps)
    num_samples = oscil.get_chunk_size()
    moving_averages = np.zeros(num_samples)
    i = j = 0
    for chunk in wave:
        moving_averages = np.convolve(chunk, np.ones((taps,))/taps)[(taps-1):]
        # apply "filter"
        if (highpass):
            chunk -= moving_averages
        else:
            chunk = moving_averages
        yield chunk
Example #5
0
def echo(timer, wave, vol, delay):
    '''Apply an echo to a wave.
    Args:
        timer - used to calculate the delay
        wave - numpy array of base wave, which will be echoed
        vol - volume of echo [0,1]
              the volume of the wave will be reduced to (1 - vol)
        delay - delay of echo, in units of whole note duration
    Yields:
        Numpy array of original wave with echo applied.
    '''
    limits.validate.vol(vol)

    width = timer.samples_per_note(1) * delay
    chunk_size = oscil.get_chunk_size()
    num_chunks = ceil(width / chunk_size)

    buff = deque([np.zeros(chunk_size) for _ in range(num_chunks)])
    for chunk in wave:
        buff.append(chunk)
        yield chunk*(1-vol) + buff.popleft()*vol