def render(self, buf): table_rate = self.incr mask = wavetable.TABLE_SIZE - 1 playback_rate = pow(2, self.detune / 1200.0) for i in range(buf.size): playback_pointer = i * playback_rate # Let x, y be indeces into what would be the intermediate buffer. x = int(floor(playback_pointer)) y = x + 1 # Let omega, theta be the interpolation factors for the # interpolation step on what would be read from the intermediate. theta = playback_pointer - float(x) omega = 1.0 - theta # So, assuming an existing intermediate buffer, E, we could compute # Si = buf[i] = (omega * E[x]) + (theta * E[y]) # We now derive E[x] and E[y] to avoid the intermediate buffer. # Remember from the StandardOscillator, # E[x] = (beta * table[a]) + (alpha * table[b]) a = int(floor(table_rate * x)) b = a + 1 alpha = (table_rate * x) - float(a) beta = 1.0 - alpha a_wrapped = a & mask b_wrapped = b & mask ex = (beta * wavetable.get(a_wrapped)) + \ (alpha * wavetable.get(b_wrapped)) # Now we need E[y], which we can derive the same way. _a = int(floor(table_rate * y)) _b = (_a + 1) _alpha = (table_rate * y) - float(_a) _beta = 1.0 - _alpha _a_wrapped = _a & mask _b_wrapped = _b & mask ey = (_beta * wavetable.get(_a_wrapped)) + \ (_alpha * wavetable.get(_b_wrapped)) # From above, we now compute Si si = (omega * ex) + (theta * ey) buf[i] += si * self.level
def render(self, buf): for i in range(buf.size): index = i * self.incr read_index = int(floor(index)) mask = wavetable.TABLE_SIZE - 1 read_index_wrapped_left = read_index & mask read_index_wrapped_right = (read_index + 1) & mask left = wavetable.get(read_index_wrapped_left) right = wavetable.get(read_index_wrapped_right) alpha = index - float(read_index) inv_alpha = 1.0 - alpha sample = (inv_alpha * left) + (alpha * right) buf[i] += sample * self.level