Aus One-Bit-Musik - Meowbit

Der bisherige Artikel gewidmet den Vorstand Meowbit Ausbildung und Python - Implementierungen für sie endete mit einer Erwähnung CircuitPython Unfähigkeit zu spielen Musik gleichzeitig mit dem Spiel: CircuitPython erlaubt keine Interrupt - Handler in Python geschrieben werden, und ohne dass dies eine Verzögerung für Bildschirm neu gezeichnet (ca. 0,15 s) "hängt" den Ton ... Trotzdem wird häufig der Hintergrundsound benötigt, und für die meisten unterstützten Boards (100 von 189) enthält CircuitPython ein Modul audioio



oder audiopwmio



implementiert den Hintergrundsound auf eine für das Board native Weise. Leider für Meowbit (und im Allgemeinen für STM32- basierte Boards ) weder das eine noch das andere Modul ist implementiert; In einem Open Source-Projekt kann dies jedoch behoben werden. Finden Sie das Osterei auf dem Foto Zunächst einmal: Warum gibt es zwei verschiedene Module zum Abspielen von Sound mit völlig identischen APIs, und entweder das eine oder das andere wird auf verschiedenen Boards unterstützt?













So sehen ⅒ Sekunden einer normalen (16-Bit)

WAV- Datei in einem Audio-Editor (wie Audacity) aus :





Der Wert ändert sich reibungslos im Bereich von etwa -0,2 bis +0,2 "konventionelle Einheiten". Wenn die dem elektrodynamischen Lautsprecher zugeführte Spannung auf die gleiche Weise geändert wird, schwingt die Membran ebenso gleichmäßig - von etwa 0,2 ihrer maximal möglichen Abweichung in eine Richtung bis zu 0,2 Abweichungen in die andere Richtung. Das Modul audioio



implementiert genau diese Klangwiedergabe - über den DAC ändert es sanft die Spannung am an den Lautsprecher angeschlossenen Ausgang.



In Meowbit gibt es jedoch anstelle eines Lautsprechers einen billigen Piezo-Hochtöner, der die Membran nicht in Zwischenpositionen ablenken kann: Er bewegt sich sehr schnell von einer Extremposition zu einer anderen Extremposition und bleibt dort bis zum nächsten Übergang. Stellen Sie sich das als Sound mit einer Auflösung von einem Bit pro Sample vor:





Auf diese Weise ist es unmöglich, die Änderung der Lautstärke zu übertragen, aber es ist theoretisch möglich, alle darin vorhandenen Harmonischen zu übertragen - wenn parallel zur 32768-fachen Verringerung der Auflösung die Abtastfrequenz um dieselbe erhöht wird Menge (dh bis zu Hunderten von Megahertz). Es ist unwahrscheinlich, dass eine Piezo-Hochtönermembran bei dieser Frequenz vibrieren kann. Dies kann jedoch zu Ihrem Vorteil genutzt werden - wenn Sie lernen, wie man die Spannung am Summer umschaltet, wenn sich die Membran auf halber Strecke befindet, können Sie Geräusche mit mittlerer Lautstärke erzeugen! Eine Patentrecherche bestätigt, dass tatsächlich die Möglichkeiten untersucht werden, den Piezo-Hochtöner auf diese Weise zu verwenden. Wir werden nicht tief in diesen Dschungel vordringen und die übliche WAV-Abtastrate von zehn Kilohertz belassen. Für Musik, bei der die Grundschwingungen im Kilohertzbereich liegen, ist dies ausreichend; Sprache wird jedoch zu einem kaum verständlichen Geräusch.Sie können vergleichen, wie das von mir verwendete Acht-Sekunden-Klangbeispiel, das auf einem Ein-Bit-Piezo-Echolot abgespielt wurde, wahrgenommen wird: zuerst das Original, dann die Ein-Bit-Version, dann die Meowbit-Aufnahme mit einem Mikrofon.





Das Modul audiopwmio



implementiert die Tonwiedergabe über einen digitalen Ausgang mit PWM : Eine Ein-Bit-Audioaufnahme führt zu einer Folge von Verzögerungen zwischen dem Umschalten des

Ausgangs auf den entgegengesetzten Wert.



Der allgemeine Implementierungsplan audiopwmio



für Meowbit lautet also wie folgt:



  1. Wir übersetzen die vom Benutzer übertragene Audioaufzeichnung in das PWM-Format (eine Liste der Verzögerungen zwischen den Schaltern).
  2. . pulseio



    , , – – Python .


Es war nicht sofort offensichtlich, dass es einen weiteren Aspekt der Implementierung gab, um den man sich kümmern musste - die Audiopufferung. Mein 8-Sekunden-Testmuster ist 8 * 22050 * 2 ≈ 340 KB - dreimal so groß wie der gesamte Meowbit-RAM. Daher muss es Stück für Stück in den Speicher geladen werden. Die Standardimplementierung audiocore.WaveFile



lädt die WAV-Datei in 256-Byte-Blöcken, was 128 Samples oder 5,8 ms Wiedergabezeit entspricht. Dies bedeutet, dass durchschnittlich alle 5,8 ms audiopwmio



muss das Nachfüllen des Puffers beantragen; Es gibt keinen Ausweg, außer diesen Anruf im selben Timer-Interrupt-Handler zu platzieren. Andernfalls kann das Neuzeichnen des Bildschirms das Füllen des Puffers um gut hundert Millisekunden verzögern. Dies löst das Problem jedoch nicht vollständig: Was passiert, wenn ein Timer-Interrupt auftritt, während der Bildschirm neu gezeichnet wird? Der Meowbit-Bildschirm ist über den SPI-Bus verbunden , das Flash-Laufwerk ist über diesen verbunden, was bedeutet, dass beim erneuten Zeichnen des Bildschirms immer noch kein Zugriff auf den Flash möglich ist!



Das Ergebnis ist eine Implementierung audiopwmio



fähig, Audioaufnahmen aus dem Speicher (oder prozedural erzeugt) in der höchstmöglichen Qualität auf Meowbit abzuspielen; Audioaufnahmen von Dateien werden jedoch nur abgespielt, wenn nicht gleichzeitig der Bildschirm und der Blitz aufgerufen werden. Dies ist völlig ausreichend für den Soundtrack einfacher Spiele. PR mit meiner Implementierung hat mehr als eine Woche auf eine Überprüfung gewartet, und es audiopwmio



ist nicht bekannt, wann Meowbit in der offiziellen Version von CircuitPython erscheinen wird. Aber das hindert niemanden daran, CircuitPython mit meinem Add-On für sich selbst zu kompilieren.










All Articles