For more information about the examples, such as how the Python and Mojo files interact with each other, see the Examples Overview
PitchShiftExample¶
this uses the mouse to control granular playback of the buffer left and right moves around in the buffer. up and down controls rate of triggers.
Python Code¶
from mmm_src.MMMAudio import MMMAudio
mmm_audio = MMMAudio(128, num_input_channels = 12, graph_name="PitchShiftExample", package_name="examples")
mmm_audio.start_audio() # start the audio thread - or restart it where it left off
mmm_audio.send_float("which_input", 0)
mmm_audio.send_float("pitch_shift", 1.25)
mmm_audio.send_float("grain_size", 0.4)
mmm_audio.send_float("pitch_dispersion", 0.4)
mmm_audio.send_float("time_dispersion", 0.5)
mmm_audio.stop_audio() # stop the audio thread
Mojo Code¶
from mmm_src.MMMWorld import MMMWorld
from mmm_utils.functions import *
from mmm_dsp.PlayBuf import *
from mmm_dsp.Filters import VAMoogLadder
from mmm_utils.functions import linexp
from random import random_float64
from mmm_utils.Messenger import Messenger
# THE SYNTH
struct PitchShiftExample(Representable, Movable, Copyable):
var world: UnsafePointer[MMMWorld]
var pitch_shift: PitchShift[num_chans=2]
var messenger: Messenger
var shift: Float64
var grain_size: Float64
var pitch_dispersion: Float64
var time_dispersion: Float64
var which_input: Float64
fn __init__(out self, world: UnsafePointer[MMMWorld]):
self.world = world
self.pitch_shift = PitchShift[num_chans=2](world, 1.0) # the duration of the buffer needs to == grain size*(max_pitch_shift-1).
self.messenger = Messenger(world)
self.shift = 1.0
self.grain_size = 0.2
self.pitch_dispersion = 0.0
self.time_dispersion = 0.0
self.which_input = 0.0
@always_inline
fn next(mut self) -> SIMD[DType.float64, 2]:
self.messenger.update(self.which_input, "which_input")
temp = self.world[].sound_in[0]
input_sig = select(self.which_input, [SIMD[DType.float64, 2](temp, temp), SIMD[DType.float64, 2](temp, 0.0), SIMD[DType.float64, 2](0.0, temp)])
self.messenger.update(self.shift,"pitch_shift")
self.messenger.update(self.grain_size,"grain_size")
self.messenger.update(self.pitch_dispersion,"pitch_dispersion")
self.messenger.update(self.time_dispersion,"time_dispersion")
# shift = linexp(self.world[].mouse_y, 0.0, 1.0, 0.25, 4.0)
# grain_size = linexp(self.world[].mouse_x, 0.0, 1.0, 0.05, 0.3)
out = self.pitch_shift.next(input_sig, self.grain_size, self.shift, self.pitch_dispersion, self.time_dispersion)
return out
fn __repr__(self) -> String:
return String("PitchShift")