Skip to content

For more information about the examples, such as how the Python and Mojo files interact with each other, see the Examples Overview

MessengerExample

This example demonstrates the Messenger functionality in MMM-Audio, and the many kinds of messages that can be sent to control parameters in the audio graph.

We are able to send: - Boolean values - .send_bool() - Float values - .send_float() - Lists of floats - .send_floats() - Integer values - .send_int() - Lists of integers - .send_ints() - String values - .send_string() - Lists of strings - .send_strings() - Trigger messages - .send_trig()

Python Code

from mmm_python.MMMAudio import MMMAudio
from mmm_python.python_utils import midicps

a = MMMAudio(128, graph_name="MessengerExample", package_name="examples")

a.start_audio()

a.send_bool("bool",True)
a.send_bool("bool",False)

a.send_float("float", 440.0)
a.send_float("float", 880.0)

a.send_floats("floats", [440.0, 550.0, 660.0])
a.send_floats("floats", [880.0, 990.0, 1100.0])

a.send_int("int", 42)
a.send_int("int", 84)

a.send_ints("ints", [1, 22, 3, 4, 5])
a.send_ints("ints", [5, 4, 3, 2, 1])
a.send_ints("ints", [100,200])

a.send_string("string", "Hello, World!")
a.send_string("string", "Goodbye, World!")

a.send_strings("strings", ["hello", "there", "general", "kenobi"])
a.send_strings("strings", ["goodbye", "there", "general", "grievous"])

a.send_trig("trig")

a.send_bool("tone_0.gate",True)
a.send_bool("tone_1.gate",True)
a.send_float("tone_0.freq",440 * 1.059)
a.send_float("tone_1.freq",midicps(74))
a.send_bool("tone_0.gate",False)
a.send_bool("tone_1.gate",False)

a.stop_audio()

Mojo Code

from mmm_audio import *

struct Tone(Movable,Copyable):
    var world: UnsafePointer[MMMWorld]
    var osc: Osc
    var freq: Float64
    var m: Messenger
    var gate: Bool

    fn __init__(out self, world: UnsafePointer[MMMWorld], namespace: String):
        self.world = world
        self.osc = Osc(self.world)
        self.freq = 440.0
        self.m = Messenger(self.world,namespace)
        self.gate = False

    fn next(mut self) -> Float64:

        if self.m.notify_update(self.freq,"freq"):
            print("Tone freq updated to ", self.freq)

        if self.m.notify_update(self.gate,"gate"):
            print("Tone gate updated to ", self.gate)

        sig = self.osc.next(self.freq) if self.gate else 0.0

        return sig

struct MessengerExample(Copyable, Movable):
    var world: UnsafePointer[MMMWorld]
    var m: Messenger
    var tones: List[Tone]

    var bool: Bool
    var bools: List[Bool]
    var float: Float64
    var floats: List[Float64]
    var int: Int64
    var ints: List[Int64]
    var string: String
    var strings: List[String]

    fn __init__(out self, world: UnsafePointer[MMMWorld]):
        self.world = world
        self.m = Messenger(self.world)

        self.tones = List[Tone]()
        for i in range(2):
            self.tones.append(Tone(self.world, "tone_" + String(i)))

        self.bool = False
        self.bools = List[Bool](False, False)
        self.float = 0.0
        self.floats = List[Float64](0.0, 0.0)
        self.int = 0
        self.ints = List[Int64](0, 0)
        self.string = ""
        self.strings = List[String]("", "")

    fn next(mut self) -> SIMD[DType.float64, 2]:


        if self.m.notify_update(self.bool,"bool"):
            print("Bool value is now: " + String(self.bool))

        if self.m.notify_update(self.float,"float"):
            print("Float value is now: " + String(self.float))

        if self.m.notify_update(self.floats,"floats"):
            print("Updated floats to ")
            for f in self.floats:
                print("  ", f)

        if self.m.notify_update(self.int,"int"):
            print("Updated int to ", self.int)

        if self.m.notify_update(self.ints,"ints"):
            print("Updated ints to:", end="")
            for i in self.ints:
                print("  ", i, end="")
            print("")

        if self.m.notify_update(self.string,"string"):
            print("Updated string to ", self.string)

        if self.m.notify_update(self.strings,"strings"):
            print("Updated strings to ")
            for s in self.strings:
                print("  ", s)

        if self.m.notify_trig("trig"):
            print("Received trig")

        out = SIMD[DType.float64, 2](0.0, 0.0)
        for i in range(2):
            out[i] = self.tones[i].next()

        return out * dbamp(-20.0)