Skip to content

Instantly share code, notes, and snippets.

@todbot
Last active May 6, 2025 23:21
Show Gist options
  • Save todbot/919ce20fec25a08163afdede827cfa08 to your computer and use it in GitHub Desktop.
Save todbot/919ce20fec25a08163afdede827cfa08 to your computer and use it in GitHub Desktop.
Test how adding adafruit_midi as a frozen module impacts M7 RAM usage in CircuitPython

Summary:

  • CircuitPython 9.2.7 on Metro M7 and CIRCUITPY/lib adafruit_midi: 39.9 kB free -> 23.2 kB free
  • CircuitPython 10.0.alpha3 on Metro M7 and frozen adafruit_midi: 31.3 free -> 21.3 kB free

Using adafruit_midi in CIRCUITPY/lib installed with circup:

Adafruit CircuitPython 9.2.7 on 2025-04-01; Metro MIMXRT1011 with IMXRT1011DAE5A
>>> 
>>> import gc
>>> gc.collect()
>>> gc.mem_free()
39968
>>> 
>>> import time, random, board, digitalio, analogio, usb_midi
>>> gc.collect()
>>> gc.mem_free()
39680
>>> 
>>> import adafruit_midi
>>> from adafruit_midi.note_on import NoteOn
>>> from adafruit_midi.note_off import NoteOff
>>> from adafruit_midi.timing_clock import TimingClock
>>> 
>>> gc.collect()
>>> gc.mem_free()
28032
>>> 
>>> import patterns_data
>>> 
>>> gc.collect()
>>> gc.mem_free()
23232

Using adafruit_midi in as a frozen module:

Adafruit CircuitPython 10.0.0-alpha.2-49-g4ecc0e70d4-dirty on 2025-05-04; Metro MIMXRT1011 with IMXRT1011DAE5A
>>> import gc
>>> gc.collect()
>>> gc.mem_free()
31616
>>> 
>>> import time, random, board, digitalio, analogio, usb_midi
>>> gc.collect()
>>> gc.mem_free()
31328
>>> 
>>> import adafruit_midi
>>> from adafruit_midi.note_on import NoteOn
>>> from adafruit_midi.note_off import NoteOff
>>> from adafruit_midi.timing_clock import TimingClock
>>> 
>>> gc.collect()
>>> gc.mem_free()
26272
>>> 
>>> import patterns_data
>>> 
>>> gc.collect()
>>> gc.mem_free()
21344

The patterns_data.py module contains simple defines and data structs, with comments. See attached.

# patterns_data.py - Speicher für Arpeggiator-Patterns und Konfiguration
# --- MIDI & System Konfiguration ---
MIDI_IN_CHANNEL = None # None für alle Kanäle, oder 0-15
MIDI_OUT_CHANNEL = 7 # Kanal 8 für User (0-15)
INTERNAL_BPM = 120
STEPS_PER_BEAT = 4
CLOCK_TIMEOUT_S = 2.0 # Sekunden ohne externe Clock bis Fallback auf interne
# --- Potentiometer Konfiguration ---
POT_PIN_PATTERN = "A2" # Pin für Melodie / Arp Mode / Progression
POT_PIN_TIMING = "A5" # Pin für Rhythmus / Gate
# --- Gate Konfiguration ---
DEFAULT_GATE_FACTOR = 0.9 # Standard-Gate-Faktor (wenn Pattern keinen liefert)
MIN_GATE_FACTOR = 0.05 # Minimaler Gate-Faktor
BASSLINE_PATTERNS = [
# Pattern 0: 16tel "Rolling Bassline"
[1.0, 1.0, 1.0, None],
# Pattern 1: 16tel "Swingy Bass" (simuliert 12tel/Triolen durch Gate)
# Lang auf 1&3, kurz auf 2&4 - oder umgekehrt? Probieren wir lang-kurz.
# Spielt auf jedem Step, variiert aber Länge.
# [1.5, 0.5, 1.5, 0.5], # Alternative 1: Lang-Kurz
[0.5, 1.5, 0.5, 1.5], # Alternative 2: Kurz-Lang (Offbeat betont)
# Pattern 2: 8tel "Offbeat Bass"
[None, None, 2.0, None] # Spielt lange Note auf Step 3 (der 'und' von 2)
]
# --- Rhythmische Patterns (Gate-Faktoren) ---
# Steuert die Länge der Note relativ zur NOMINAL_STEP_INTERVAL_S.
# 1.0 = normale Länge, 0.5 = halbe Länge, 2.0 = doppelte Länge, None = Pause
RHYTHMIC_PATTERNS = [
# ... (Deine Rhythmus-Patterns hier, z.B. aus Antwort #15) ...
[1.0, 1.0, 1.0, 1.0], # 0: Gleichmäßige 16tel (Standard-Gate)
[0.5, 0.5, 0.5, 0.5], # 1: Kurze 16tel (Staccato)
[1.5, 1.5, 1.5, 1.5], # 2: Längere Noten (Legato, überlappend)
[1.0, None, 1.0, None], # 3: Achtel-Gefühl (jede zweite Note Pause)
# ... (füge weitere hinzu) ...
]
# --- Melodische Patterns (Single Note Mode) ---
# (Intervalle relativ zur Basisnote)
MELODIC_PATTERNS = [
# ... (Deine Melodie-Patterns hier, z.B. aus Antwort #17) ...
[0, 4, 7, 12], # 0: Major Arp Up
[0, 3, 7, 12], # 1: Minor Arp Up
[0, 12, 7, 12], # 2: Octave, Fifth
[0, 2, 4, 5, 7, 9, 11, 12], # 3: Major Scale Up
# ... (füge weitere hinzu) ...
]
# --- NEU: Chord Progression Daten ---
# 1. Akkordtypen (Intervalle relativ zum Grundton des Akkords)
CHORD_DEFS = {
'maj': (0, 4, 7),
'min': (0, 3, 7),
# Optional mehr hinzufügen:
# 'dim': (0, 3, 6),
# 'aug': (0, 4, 8),
# 'maj7': (0, 4, 7, 11),
# 'min7': (0, 3, 7, 10),
# 'dom7': (0, 4, 7, 10),
}
# 2. Stufen (Intervall relativ zum Grundton der Tonart)
SCALE_DEGREES = {
'I': 0, 'i': 0,
'II': 2, 'ii': 2,
'III': 4, 'iii': 3,
'IV': 5, 'iv': 5,
'V': 7, 'v': 7,
'VI': 9, 'vi': 8,
'VII': 11, 'vii': 10
}
# 3. Progressionen (Liste von Tupeln: (Stufe_String, Akkordtyp_String))
PROGRESSIONS = {
'Pop I-V-vi-IV': [('I', 'maj'), ('V', 'maj'), ('vi', 'min'), ('IV', 'maj')],
# 'Jazz ii-V-I': [('ii', 'min'), ('V', 'maj'), ('I', 'maj')], # ENTFERNT
# 'Minor i-iv-V': [('i', 'min'), ('iv', 'min'), ('V', 'maj')], # ENTFERNT
# 'Andalusian': [('i', 'min'), ('VII', 'maj'), ('VI', 'maj'), ('V', 'maj')], # ENTFERNT
'Basic I-IV-V': [('I', 'maj'), ('IV', 'maj'), ('V', 'maj')],
'Just I': [('I', 'maj')],
'Just i': [('i', 'min')],
}
# 4. Standard-Tonart (wenn nicht aus Terz erkennbar)
DEFAULT_TONALITY = 'maj'
# --- Arpeggio Patterns ---
# Melodische Patterns (nur Intervalle)
MELODIC_PATTERNS = [
# --- Grundlegende Arpeggios (bereits bekannt) ---
[0, 4, 7, 12], # 0: Major Arp Up (C E G C')
[0, 3, 7, 12], # 1: Minor Arp Up (C Eb G C')
[0, 7, 12], # 2: Fifth & Octave Up (C G C')
[12, 7, 4, 0], # 3: Major Arp Down (C' G E C)
[12, 7, 3, 0], # 4: Minor Arp Down (C' G Eb C)
# --- Erweiterte Arpeggios (7ths, Sus) ---
[0, 4, 7, 10], # 5: Dominant 7th Arp (C E G Bb) - Typisch für Spannung
[0, 3, 7, 10], # 6: Minor 7th Arp (C Eb G Bb) - Klassischer House/Deep House Sound
[0, 4, 7, 11], # 7: Major 7th Arp (C E G B) - Eher jazzig/chill
[0, 5, 7, 12], # 8: Sus4 Arp (C F G C') - Offener Klang
[0, 2, 7, 12], # 9: Sus2 Arp (C D G C') - Auch offen, modern
# --- Sequenz-artige Muster ---
[0, 2, 4, 2], # 10: Auf-Ab-Bewegung (C D E D) - Einfache Sequenz
[0, 7, 5, 7], # 11: Quint-Sprung mit Nebennoten (C G F G)
[0, 12, 7, 12], # 12: Oktave, dann Quinte (C C' G C') - Klassischer Bassline-Move
[0, 3, 5, 7], # 13: Moll-Tonleiter Fragment (C Eb F G)
[0, 4, 7, 9], # 14: Dur-Tonleiter Fragment (C E G A)
[0, -2, 0, 3], # 15: Tief-Hoch Bewegung (C Bb C Eb) - Gut für Basslines
[0, 0, 7, 5], # 16: Repetierter Grundton, dann Bewegung (C C G F)
# --- Modale / Interessante Intervalle ---
[0, 3, 6, 10], # 17: Vermindert/Bluesy (C Eb Gb Bb) - Dissonanter
[0, 5, 7, 10], # 18: Quarte/Quinte/kleine Sept (C F G Bb) - Modal/Mixolydisch-Andeutung
[0, 1, 5, 7], # 19: Phrygisch-Andeutung (C Db F G) - Spanisch/Düster
[0, 4, 6, 11], # 20: Lydisch-Andeutung (C E F# B) - Schwebend/Filmmusik
# --- Oktav-Muster ---
[0, 12, 0, -12], # 21: Oktav-Sprünge hoch/runter (C C' C C_low)
[0, 12, 12, 7], # 22: Oben bleiben (C C' C' G)
[0, 7, 12, 19], # 23: Quint, Oktave, Oktave+Quint (C G C' G') - Weit
# --- Kürzere Muster / Techno-Style ---
[0, 3, 0, 7], # 24: Kurz, Moll-Dreiklang Andeutung (C Eb C G)
[0, 0, 3, 5], # 25: Repetitiv, Moll-Fragment (C C Eb F)
[0, 7, 0, 10], # 26: Quint/Septime Wechsel (C G C Bb)
]
RHYTHMIC_PATTERNS = [
# --- Grundmuster ---
[1.0, 1.0, 1.0, 1.0], # 0: Gleichmäßige 16tel (Standard-Gate)
[None, 1.0, 1.0, 1.0], # 0: Gleichmäßige 16tel (Standard-Gate)
#[0.5, 0.5, 0.5, 0.5], # 1: Kurze 16tel (Staccato)
#[0.25, 0.25, 0.25, 0.25], # 2: Sehr kurze 16tel (Sehr Staccato)
#[1.5, 1.5, 1.5, 1.5], # 3: Längere Noten (Legato, überlappend)
#[2.0, 2.0, 2.0, 2.0], # 4: Noch längere Noten (Mehr Legato)
# --- Muster mit Pausen ---
[1.0, None, 1.0, None], # 5: Achtel-Gefühl (jede zweite Note Pause)
#[1.0, 1.0, None, 1.0], # 6: 16tel mit einer Pause auf der '3'
# [0.5, None, 0.5, None], # 7: Kurze Achtel (Staccato)
#[1.0, None, None, None], # 8: Nur auf der '1' (Viertel-Gefühl)
# [1.5, None, 1.0, None], # 9: Akzent auf 1, dann Pause, dann normal auf 3
# --- Akzentuierte / Groove Muster ---
[1.5, 0.5, 0.75, 0.5], # 10: Akzent auf 1, kurz auf 2, etwas länger auf 3
#[0.5, 1.5, 0.5, 1.0], # 11: Akzent auf 2 und 4 (leicht synkopisch)
#[1.0, 0.25, 1.0, 0.5], # 12: Abwechslungsreich kurz/lang
[2.0, 0.5, None, 0.5], # 13: Langer Start, dann kurze Staccato-Antwort mit Pause dazwischen
# --- Längere Muster (8 Schritte = 2 Beats bei 4 Steps/Beat) ---
[1.0, 0.5, 0.75, 0.5, 1.5, 0.5, 0.75, 0.5], # 14: 8-Step Variation von #10
[1.0, None, 0.5, None, 1.0, None, 0.75, None], # 15: 8-Step Achtel-Pattern mit variierender Länge
# --- Experimentell ---
#[0.1, 0.2, 0.4, 0.8], # 16: Ansteigende Länge
#[1.5, 1.0, 0.5, 0.25], # 17: Abfallende Länge
]
# Pattern für Arpeggio (2 Noten)
ARPEGGIO_PATTERN_TWO_NOTES = [0, 1]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment