Wie kann man lernen, die Spuren zu fühlen? Visualisierung musikalischer Frequenzen in My wave

Entwickler auf der ganzen Welt haben Millionen von Stunden damit verbracht, Musikvisualisierungen in Apps und Playern zu erstellen. Viele von euch erinnern sich sicher noch an die Animationen im guten alten Winamp. Oder verschiedene JetAudio-Skins. Alte werden im Allgemeinen sagen: „Warte eine Minute, du hast Atari Video Music vergessen, es war erst 1976!“ – und sie werden Recht haben.

Meine Welle ist ein endloser, adaptiver und persönlicher Musikfluss, der auf Vorlieben basiert. Es erschien letztes Jahr in Yandex Music – mit einfacher Visualisierung. Aus dem Klangmuster der Komposition errechnete das Backend die Farbe und Rotationsgeschwindigkeit, und My wave wurde mit dieser Geschwindigkeit im gesamten Track animiert.

Aber ich wollte Dynamik hinzufügen, Verbindungen zwischen Ton und Bild, damit die Animation die Emotionen der Musik ergänzt. Wir haben uns entschieden, dass My wave nicht nur das Tempo, sondern auch die Musik selbst, also die Frequenzen, berücksichtigt. Schließlich ist dies der Hauptbildschirm der Anwendung, und es wäre seltsam, darauf eine einfache, seit langem bekannte Visualisierung zu zeigen.

Mein Name ist Andrey Bobkov, ich bin ein Android-Entwickler, und in diesem Beitrag erzähle ich Ihnen, wie wir My Wave mithilfe höherer Mathematik und digitaler Signalanalyse beigebracht haben, die Tracks zu fühlen, die Sie hören, und die Frequenzen zu visualisieren.


Für mich persönlich standen die Sterne in diesem Projekt – ich habe am Institut aktiv digitale Signalanalyse studiert. Es wurde uns als eine Art kugelförmiges Pferd im luftleeren Raum erklärt: Es scheint theoretisches Wissen zu geben, es gibt ein Verständnis für die Materie, aber wie und wo man das alles im wirklichen Leben und bei Aufgaben anwenden kann, ist eine Frage.

Was wir erreichen wollten

Unsere Hauptaufgabe war es, den Musikfluss schön zu visualisieren und ihn für das Gerät des Benutzers so energieeffizient wie möglich zu gestalten. Daher haben wir entschieden, dass die Fourier-Transformation die Grundlage für die Visualisierung von My wave bilden wird: Dann stellt sich heraus, dass die meiste Energie für die reine Mathematik und die Übertragung von PCM-Bytes aufgewendet wird. Beide Operationen stellen für moderne Geräte keine ernsthafte Belastung dar.

Darüber hinaus finden die Analyse des Flusses und das Rendern von My Wave nur statt, wenn die Anwendung geöffnet ist. Wenn Sie es minimieren und im Hintergrund Musik hören, wird die Animation nicht gerendert, der Stream nicht analysiert, was bedeutet, dass der Akku nicht verschwendet wird.

Für ähnliche Projekte gibt es in Android bereits eigene Umsetzung Audioanalyse und Fourier-Transformation, aber die Google-Bibliothek benötigt die Erlaubnis, Audio aufzunehmen. Es scheint uns, dass es übertrieben ist, dafür um Erlaubnis zu bitten. Außerdem hängt diese Methode von der Lautstärke des Tons ab.

Das passte nicht zu uns, also entschieden wir uns, eine eigene Lösung zu schreiben, die keinen Zugriff auf das Mikrofon benötigt.

Wie das alles funktioniert

Die Standard-Android-Musik-App verfügt über einen Player. Darin können wir uns mit dem Audiostrom verbinden, bevor er an den DAC ausgegeben wird, und Audiodaten in Form von PCM-Bytes erhalten (das Format bestimmt die geplante Klangcharakteristik, eine komplexe Zahl). So können wir diese Bytes analysieren, noch bevor das Signal zur Wiedergabe freigegeben wird. Verantwortlich für die Analyse

Schnelle Fourier-Transformation

der die Schallwelle in die von uns benötigten Frequenzen sowie deren Amplituden zerlegt.

Jeder Ton besteht also im Wesentlichen aus Frequenzen und Amplituden. Dies ist eine Standard-Wellenfunktion, eine Sinuskurve, die aus mathematischer Sicht nichts Kompliziertes darstellt. Daher können wir uns ein bestimmtes Zeitfenster setzen und in dessen Rahmen die Daten sammeln, die wir für die Arbeit benötigen. Dank der Sinusanalyse können wir Oktaven erkennen und verstehen, dass der Track Bässe, Drums und mehr enthält.

Also fangen wir an, einen bestimmten Song zu analysieren. Wir müssen 100 Millisekunden Sound akkumulieren und die Fourier-Transformation ausführen, wonach wir mit Sicherheit sagen können – ja, Schlagzeug erklang in diesem Segment (Geigen, Gitarre gewaschen). Wir können ein bestimmtes Instrument erkennen, weil wir verstehen, welche Frequenz in dem Moment klingt, in dem wir uns entscheiden.

Leider ist die Methode nicht ideal, da es Strecken mit sehr hoher Geschwindigkeit gibt. Zum Beispiel die Arbeit der Gruppe Dragonforce, wo die heruntergespülte Gitarre zwischen Fenstern von 100 ms fallen kann. Die Welle kann bei 90 ms beginnen und bei 120 ms enden – wir werden sie also überspringen und nicht berücksichtigen. Und im Hard Rock gibt es viele Instrumente, also stellt sich heraus, dass alle Frequenzen gefüllt sind und es fast keine Tropfen gibt.

class PCMAudioStreamAudioProcessor : BaseAudioProcessor() { // Eigenschaften überschreiben Spaß onConfigure(inputAudioFormat: AudioProcessor.AudioFormat): AudioProcessor.AudioFormat { // Format prüfen, Kanalanzahl speichern, Abtastrate und andere Daten zurückgeben inputAudioFormat } Spaß überschreiben queueInput(inputBuffeer: ByteBuffer) { // PCM-Bytes zur Analyse senden } }

Wie ich oben geschrieben habe, erhalten wir Daten vom AudioProcessor ExoPlayer. Eigentlich kann man damit den Sound verändern, aber wir kopieren einfach die PCM-Bytes und geben sie unverändert weiter.

Wir übertragen Bytes in einen anderen Stream, damit es keine Tonverzögerung gibt. Der Puffer enthält Daten von allen Kanälen, sodass der Index die Kanalmaske ist und ziemlich einfach zu berücksichtigen ist.

Es lohnt sich auch, daran zu denken, damit zu arbeiten FormateBeispielsweise ist PCM_16_BIT linear und es sind keine speziellen Manipulationen damit erforderlich. Grob gesagt, jeder Kurzdie aus dem Puffer entnommen wurde, ist ein diskreter Wert der Amplitude des digitalisierten analogen Signals zu einem bestimmten Zeitpunkt (Hier ist der Artikel mit einer detaillierten Beschreibung, wie man mit reinen Daten in SilenceSkippingAudioProcessor arbeitet).

Bleibt die Frage – um die durchschnittliche Amplitude für alle Kanäle oder für einen zu berechnen? Vielleicht ist es einfacher, den Kanal mit dem maximalen Wert zu nehmen und ihn der schnellen Fourier-Transformationsfunktion zu geben?

Es ist schwierig, etwas Neues über die schnelle Fourier-Transformation zu sagen, es gibt viele gute Artikel zu diesem Thema, wir haben bereits etwas zu Habré beschrieben. Wir mussten keine absolut genaue Frequenz erhalten – 200 MHz, 1 kHz und so weiter. Wir haben Mitten und Tiefen eingezeichnet, das heißt, wir haben einfach überprüft, ob die Frequenz in dem von uns benötigten Bereich liegt oder nicht, und dann die Amplituden summiert.

Aber es reicht nicht aus, dies alles in den ersten Phasen zu schreiben – Sie müssen überprüfen, ob alles wie beabsichtigt funktioniert.

Hier verhält es sich wie bei richtiger Musik: zB beim Stimmen einer Gitarre. Es gibt gute Gitarristen, die schön spielen, aber sie ziehen es vor, die Gitarre vom Stimmgerät zu stimmen und nicht nach Gehör. Jemand hat sich einfach daran gewöhnt, aber jemand kann es einfach nicht richtig alleine machen, weil das Gehör gut ist, aber nicht gut genug. Wenn ich ein Gitarrist wäre, wäre ich von Letzterem: Nach meinem Gehör unterscheide ich Frequenzen nicht gut genug, um zu verstehen, ob mein Code funktioniert oder nicht.

Daher habe ich einfach die benötigten Samples gefunden, einen bestimmten Ton für 1 Kilohertz ausgewählt und ihn dann in den Analysator geladen. Die Ausgabe zeigte, dass es tatsächlich 1 Kilohertz war, und ich stellte fest, dass alles so funktionierte, wie es sollte.

Visualisierung


(Farbfülltiefe – niedrige Frequenzen, Wellenbiegung – mittel.)

Am Beispiel des Schemas unten werden wir kurz analysieren, wie das funktioniert.

PcmAudioProcessor akkumuliert einfach über 100 ms und gibt PCM-Bytes zurück.

AudoVisualizationCenter, das diese Bytes empfängt, konvertiert sie in das richtige Format und führt eine schnelle Fourier-Transformation durch, und dann suchen wir in einem komplexen Array nach den Bereichen, die wir benötigen, und erhalten die Anzahl der Vorkommen und Frequenzamplituden.

Dann senden wir Daten an Flow und für jeden Emit in WaveAnimation senden wir einen neuen Wert.

Der VaweAnimationRenderer animiert bei jeder Wave-Animation-Frame-Anfrage den vorherigen AudioData-Wert zum neuen, basierend auf der verstrichenen Zeit, bei einem Datenfenster von 100 ms. Wir haben den ValueAnimator aufgegeben und für jeden Frame selbst neue Animationswerte berechnet, was sich als wesentlich effizienter herausstellte, da der ValueAnimator für jeden neuen animierten Wert erstellt werden muss. Und da der Wert alle 100 ms aktualisiert wird, mussten wir den Animator alle 100 ms spawnen, während die Daten kamen.

Ich möchte separat darauf hinweisen, dass die visuelle Sichtbarkeit des Renderings und beispielsweise seine Reinheit stark von dem Musikgenre abhängen, das Sie hören. Das hat meine Sammlung von Rückmeldungen von Kollegen ein wenig verdorben – ich habe sie gebeten, My wave zu testen und mir ihre Meinung zu sagen. Wir kamen mit dem Feedback zurück, dass im Allgemeinen jeder alles mag, es ist klar, dass Meine Welle tatsächlich Frequenzen wahrnimmt, aber es gibt keine Begeisterung, sie fängt nicht an. Es stellte sich heraus, dass alle Befragten einfach Hard Rock hörten. Und es hat viele mittlere und hohe Frequenzen, sodass der Analysator verstopft wird und die Ausgabe nicht die deutlichste Visualisierung ist.

Aber Country und Rap zeigten sich gut. Überhaupt ist im Country alles in Ordnung, klare Einzeltrommeln, helle Gitarren, Banjo – es ist sehr schön angelegt und dadurch auch genauso schön visualisiert. Rap war für mich diesbezüglich eine Offenbarung – überhaupt nicht mein Musikstil, aber es wird sehr schön visualisiert, eine gewisse rhythmische Genauigkeit, wie das Rezitativ tatsächlich in den Rhythmus fällt und tiefe Frequenzen durchschimmert (die Sprache der Person selbst ist in die Mitte).

Auch klassische Musik ist leider noch nicht so auffällig – uns sind wenige tiefe Frequenzen vertraut, dafür viele mittlere und hohe. Da wir noch keine hohen rendern (wir haben uns noch nicht entschieden, wie wir es in Bezug auf das Design machen sollen), bleiben nur mittlere übrig. Mit modernen Klassikern in puncto Visualisierung läuft es deutlich besser.

Reflexionen über die Zukunft

Früher ging ich selbst ständig zu meinen Lieblingstiteln, aber jetzt höre ich Musik über Meine Welle. Jetzt wird es von 70 % aller Musikhörer mindestens einmal pro Woche eingeschaltet. Live-Animation in Verbindung mit My Wave-Algorithmen sorgt für ein unterhaltsames Benutzererlebnis: Sie hören nicht nur, was Ihnen gefällt, sondern Sie können es auch sehen. Zumindest was die Frequenz angeht.

Ich persönlich habe ein paar Wünsche, die ich gerne umsetzen möchte.

Erstens ist die Audioanalyse aufgrund der festen Größe des Zeitfensters möglicherweise nicht so genau, wie wir es uns wünschen, und einige Instrumente können von Zeit zu Zeit abstürzen. Zum Beispiel ein scharfer und kurzer Schlag auf der Trommel, der einfach nicht in das analysierte Intervall kam, und ähnliches. Eine Kleinigkeit, kann aber abgeschlossen werden.

Zweitens möchte ich die Wiedergabe von hohen Frequenzen verfeinern. Sie sind auch Teil der Musik, und es ist eine Schande, dass die gleichen Liebhaber der Klassiker es in My Wave noch nicht sehen.

Wenn du auch Wünsche und Wünsche für die Arbeit von Meine Welle im Speziellen und Musik im Allgemeinen hast – schreib mir in den Kommentaren oder in einer persönlichen Nachricht, ich beantworte sie gerne.

Similar Posts

Leave a Reply

Your email address will not be published.