For more information about the examples, such as how the Python and Mojo files interact with each other, see the Examples Overview
DefaultGraph¶
Python Code¶
from mmm_src.MMMAudio import MMMAudio
# instantiate and load the graph
mmm_audio = MMMAudio(128, graph_name="DefaultGraph", package_name="examples")
mmm_audio.start_audio()
# set the frequency to a random value
from random import random
mmm_audio.send_float("freq", random() * 500 + 100) # set the frequency to a random value
Mojo Code¶
"""use this as a template for your own graphs"""
from mmm_src.MMMWorld import MMMWorld
from mmm_utils.Messenger import *
from mmm_utils.functions import *
from mmm_src.MMMTraits import *
from mmm_dsp.Osc import *
from mmm_dsp.Filters import SVF, SVFModes
struct Default_Synth(Representable, Movable, Copyable):
var world: UnsafePointer[MMMWorld]
var osc: Osc[1,2,1]
var filt: SVF
var messenger: Messenger
var freq: Float64
fn __init__(out self, world: UnsafePointer[MMMWorld]):
self.world = world
self.osc = Osc[1,2,1](self.world)
self.filt = SVF(self.world)
self.messenger = Messenger(self.world)
self.freq = 440.0
fn __repr__(self) -> String:
return String("Default")
fn next(mut self) -> Float64:
self.messenger.update(self.freq,"freq")
osc = self.osc.next(self.freq, osc_type=OscType.bandlimited_saw)
osc = self.filt.next[filter_type=SVFModes.lowpass](osc, 2000.0, 1.0)
return osc * 0.3
# there can only be one graph in an MMMAudio instance
# a graph can have as many synths as you want
struct DefaultGraph(Representable, Movable, Copyable):
var world: UnsafePointer[MMMWorld]
var synth: Default_Synth
fn __init__(out self, world: UnsafePointer[MMMWorld]):
self.world = world
self.synth = Default_Synth(self.world)
fn __repr__(self) -> String:
return String("Default_Graph")
fn next(mut self) -> SIMD[DType.float64, 2]:
return self.synth.next() # Get the next sample from the synth