Färben einer Wellenform mit dem Spektralschwerpunkt oder auf andere Weise


8

Update 8

Ich bin unglücklich darüber, Tracks in den Dienst hochladen zu müssen und mir die neue Version von RekordBox 3 anzusehen. Ich habe mich entschlossen, einen weiteren Blick auf einen Offline-Ansatz und eine feinere Auflösung zu werfen: D.

Klingt vielversprechend, wenn auch noch in einem sehr Alpha-Zustand:

Johnick - Gute Zeit

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Beachten Sie, dass es weder eine logarithmische Skalierung noch eine Palettenoptimierung gibt, sondern nur eine Rohzuordnung von Frequenz zu HSL.

Die Idee : Jetzt hat ein Wellenform-Renderer einen Farbanbieter, der nach einer Farbe für eine bestimmte Position abgefragt wird. Die oben gezeigte erhält die Nulldurchgangsrate für die 1024 Samples neben dieser Position.

Natürlich gibt es noch viel zu tun, bevor man etwas Robustes bekommt, aber es scheint ein guter Weg zu sein ...

Aus RekordBox 3 :

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Update 7

Das endgültige Formular, das ich übernehmen werde, ähnlich wie in Update 3

Geben Sie hier die Bildbeschreibung ein

(Es war ein wenig Photoshopping, um sanfte Übergänge zwischen den Farben zu erhalten)

Fazit: Ich war vor Monaten in der Nähe, habe dieses Ergebnis aber nicht für schlecht gehalten. X)

Update 6

Ich habe das Projekt kürzlich ausgegraben, daher habe ich darüber nachgedacht, es hier zu aktualisieren: D.

Lied: Chic - Good Times 2001 (Stonebridge Club Mix)

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Es ist viel besser, IMO, Beats haben eine konstante Farbe usw. Es ist jedoch nicht optimiert.

Wie ?

Immer noch mit http://developer.echonest.com/docs/v4/_static/AnalyzeDocumentation.pdf (Seite 6)

Für jedes Segment:

public static int GetSegmentColorFromTimbre(Segment[] segments, Segment segment)
{
    var timbres = segment.Timbre;

    var avgLoudness = timbres[0];
    var avgLoudnesses = segments.Select(s => s.Timbre[0]).ToArray();
    double avgLoudnessNormalized = Normalize(avgLoudness, avgLoudnesses);

    var brightness = timbres[1];
    var brightnesses = segments.Select(s => s.Timbre[1]).ToArray();
    double brightnessNormalized = Normalize(brightness, brightnesses);

    ColorHSL hsl = new ColorHSL(brightnessNormalized, 1.0d, avgLoudnessNormalized);
    var i = hsl.ToInt32();
    return i;
}

public static double Normalize(double value, double[] values)
{
    var min = values.Min();
    var max = values.Max();
    return (value - min) / (max - min);
}

Natürlich wird viel mehr Code benötigt, bevor Sie hierher kommen (zum Service hochladen, JSON analysieren usw.), aber das ist nicht der Punkt dieser Site, also poste ich nur die relevanten Dinge, um das obige Ergebnis zu erhalten.

Ich verwende also die ersten beiden Funktionen des Analyseergebnisses. Es gibt sicherlich mehr damit zu tun, aber ich muss noch testen. Wenn ich jemals etwas cooleres als oben finde, komme ich zurück und aktualisiere hier.

Hinweise zum Thema sind wie immer herzlich willkommen!

Update 5

Ein Gradient mit harmonischen Reihen

Geben Sie hier die Bildbeschreibung ein

Die Farbglättung ist verhältnisempfindlich, ansonsten sieht sie schlecht aus und muss angepasst werden.

Update 4

Die Färbung an der Quelle wurde neu geschrieben und die Farben mit einem Alpha-Beta-Filter mit 0,08- und 0,02-Werten geglättet .

Geben Sie hier die Bildbeschreibung ein

Beim Verkleinern etwas besser

Geben Sie hier die Bildbeschreibung ein

Der nächste Schritt ist eine großartige Farbpalette!

Update 3

Geben Sie hier die Bildbeschreibung ein

Gelb steht für Medien Geben Sie hier die Bildbeschreibung ein

Noch nicht so toll, wenn es nicht gezoomt ist. Geben Sie hier die Bildbeschreibung ein

(Die Palette braucht ernsthafte Arbeit)

Update 2

Vorversuch mit zweitem ' Timbre' -Koeffizienten-Hinweis von Pichenetten Geben Sie hier die Bildbeschreibung ein

Update 1

Bei einem vorläufigen Test unter Verwendung eines Analyseergebnisses des EchoNest- Dienstes ist zu beachten, dass es nicht sehr gut ausgerichtet ist (meine Schuld), aber viel kohärenter als der obige Ansatz.

Geben Sie hier die Bildbeschreibung ein

Für Leute, die an der Verwendung dieser großartigen API interessiert sind, beginnen Sie hier: http://developer.echonest.com/docs/v4/track.html#profile

Lassen Sie sich auch nicht von diesen Wellenformen verwirren, da sie 3 verschiedene Songs darstellen.

Erste Frage

Bisher ist dies das Ergebnis, das ich mit einer FFT mit 256 Abtastwerten und der Berechnung des Spektralschwerpunkts jedes Chunks erhalte .

Rohes Ergebnis der Berechnungen Geben Sie hier die Bildbeschreibung ein

Etwas Glättung angewendet (Form sieht damit viel besser aus) Geben Sie hier die Bildbeschreibung ein

Wellenform erzeugt Geben Sie hier die Bildbeschreibung ein

Im Idealfall sollte es so aussehen (aus der Serato DJ- Software) Geben Sie hier die Bildbeschreibung ein

Wissen Sie, welche Technik / welchen Algorithmus ich verwenden könnte, um das Audio zu teilen, wenn sich die durchschnittliche Frequenz im Laufe der Zeit ändert? (wie das obige Bild)


1
Ich denke, Sie sind mit dem Spektralschwerpunkt auf dem richtigen Weg. Möglicherweise benötigen Sie nur eine nichtlineare Abbildung des Ergebnisses, um eine gute Farbverteilung zu erzielen. Es sieht so aus, als ob derzeit nur das blau / cyanfarbene Segment Ihrer Palette verwendet wird.
Pichenettes

1
Haben Sie Fragen zum Pseudofarbenalgorithmus oder zur automatisierten Aufteilung des Audios in Blöcke?
Björn Roche

@pichenettes: Richtig, ich werde dieses Problem mit einer logarithmischen Skala angehen.
Aybe

1
Genau das verwendet freesound.org, um ihre Wellenformen zu färben. Siehe ihren spectral_centroidCode . Was ich wirklich möchte, ist, das Audiospektrum auf das Farbspektrum abzubilden, also ist eine niedrige Frequenz rot, eine hohe Frequenz ist blau, eine Kombination aus beiden ist magenta, eine mittlere Frequenz ist grün, ein logarithmischer Sweep ist Regenbogen, weißes Rauschen ist weiß, rosa Rauschen ist rosa, rotes Rauschen ist rot, ... Ich kann allerdings nicht herausfinden, wie es geht, da ein Spektrum linear und das andere logarithmisch ist. :) flic.kr/p/7S8oHA
Endolith

1
@Aybe: Ja, ich weiß, wie man einen Log-Sweep wie einen Regenbogen aussehen lässt, aber wenn er mit dem Log-Frequenzabstand (proportionale Breitenbänder) gemessen wird, hat weißes Rauschen ein schräges Spektrum, kein flaches Spektrum, sodass es kein weißes Licht erzeugt . Unsere Namen für Rauschfarben basieren auf Bändern konstanter Breite (linearer Abstand), aber unsere Wahrnehmung von Tönen basiert auf einem logarithmischen Abstand (Bänder proportionaler Breite). Darf ich fragen, was Sie damit vorhaben, wenn Sie es zum Laufen bringen?
Endolith

Antworten:


4

Sie können zunächst Folgendes versuchen (keine Segmentierung):

  • Verarbeiten Sie das Signal in kleinen Stücken (z. B. 10 ms bis 50 ms) - ggf. mit einer Überlappung von 50% zwischen ihnen.
  • Berechnen Sie den Spektralschwerpunkt für jeden Block.
  • Wenden Sie eine nichtlineare Funktion auf den Spektralschwerpunkt an, um eine gleichmäßige Verteilung der verwendeten Palettenfarbe zu erhalten. Logarithmus ist ein guter Anfang. Eine andere Möglichkeit besteht darin, zuerst die Verteilung des Schwerpunktwerts in der gesamten Datei zu berechnen und dann die Farbe gemäß den Perzentilen dieser Verteilung ( CDF ) zu bestimmen . Dieser adaptive Ansatz garantiert, dass jede Farbe in der Palette zu gleichen Teilen verwendet wird. Der Nachteil ist, dass das, was in einer Datei blau dargestellt ist, nicht ähnlich klingt wie das, was in einer anderen Datei blau dargestellt ist, wenn dieser adaptive Ansatz verwendet wird!

Aus dem Bild ist nicht ersichtlich, ob Serato dies tut oder sogar einen Schritt weiter geht und versucht, das Signal zu segmentieren - es ist möglicherweise nicht verwunderlich, dass dies der Fall ist, da die Kenntnis der Zeitpunkte, zu denen Noten in einem Musiksignal vorhanden sind, zur Synchronisierung beitragen kann ! Die Schritte wären:

  • Berechnen Sie eine Kurzzeit-Fourier-Transformation (Spektrogramm) des Signals - unter Verwendung der FFT für kurze überlappende Segmente (beginnen Sie mit einer FFT-Größe von 1024 oder 2048 mit 44,1 kHz Audio).
  • Berechnen Sie eine Onset-Erkennungsfunktion. Ich empfehle Ihnen, sich dieses Dokument anzusehen - der vorgeschlagene Ansatz ist sehr effektiv und selbst eine C ++ - Implementierung benötigt weniger als 10 Zeilen. Eine Implementierung finden Sie in Yaafe - as ComplexDomainOnsetDetection.
  • Erkennen Sie Spitzen in der Onset-Erkennungsfunktion, um die Position des Notenbeginns zu ermitteln.
  • Berechnen Sie den Spektralschwerpunkt über alle Zeitsegmente, die durch die erkannten Einsätze begrenzt sind (vergessen Sie nicht, Fenster und / oder Null-Pad zu verwenden!).
  • Und vergessen Sie nicht die nichtlineare Karte! Beachten Sie, dass der Gradienteneffekt, der zwischen den einzelnen Noten in der Serato-Wellenform auftritt, möglicherweise künstlich erzeugt wird.

Sobald dies funktioniert, besteht eine "niedrig hängende Frucht" darin, einige andere Merkmale für jedes Segment zu berechnen (Momente, eine Handvoll MFCCs ...), k-means für diese Merkmalsvektoren auszuführen und die Farbe von zu bestimmen das Segment, das den Clusterindex verwendet. Siehe Abschnitt II von Ravellis Artikel .


Ich habe angefangen, an Ihrer Lösung Nummer 2 zu arbeiten. Glücklicherweise bietet der von mir verwendete Dienst (EchoNest) eine Erkennung des Beginns in ihrer Analyse. Das sind großartige Neuigkeiten und eine Echtzeitersparnis! Ich habe meine Antwort mit einem kleinen Test aktualisiert und sie sieht vielversprechend aus (beachten Sie, dass sie nicht richtig ausgerichtet ist, da sie sehr schnell und schmutzig ist). Ich werde ein besseres Ergebnis veröffentlichen, wenn ich bedeutende Fortschritte gemacht habe. Vielen Dank !
Aybe

1
Dann haben Sie keine Arbeit zu erledigen. Der zweite "Timbre" -Koeffizient in der EchoNest-Analyse hängt stark mit dem Schwerpunkt zusammen, sodass Sie keine Berechnung durchführen müssen (es sei denn, sie haben die DC-Komponente in ihrer Basis entfernt. In diesem Fall ist es der erste Koeffizient). Verwenden Sie einfach den Beat- oder Segment-Level-Wert des "Timbre" -Vektors.
Pichenettes

1
Die "Helligkeit", gemessen durch den zweiten "Timbre" -Koeffizienten in der EN-Analyse, hängt stark mit dem Spektralschwerpunkt zusammen (der Unterschied besteht darin, dass der EchoNest-Analysator eine Wahrnehmungsvorverarbeitung verwendet - Mittelohrfilterung, Zeit- / Frequenzmaskierung - anstatt eine rohe FFT nehmen). Die Farbcodierung unter Verwendung des maximalen Bin im 'Pitch'-Vektor wäre für sehr reines monophones, melodisches Material nützlich, für einen Drum-Loop jedoch eher bedeutungslos.
Pichenettes

1
Ubounded? Es ist immer noch durch die Signalenergie im analysierten Frame begrenzt ... Ich denke, für diese Funktion lohnt es sich, die Skalierung zwischen den Spuren konsistent zu halten. Was ich tun würde: ein Dutzend sehr unterschiedliche Songs sammeln, um ein Gefühl für die Verteilung des Wertes zu bekommen. Wenden Sie bei Bedarf eine einfache nichtlineare Karte an, damit sie gaußscher aussieht. Entfernen Sie dann den Mittelwert und dividieren Sie durch die Standardabweichung. Wenden Sie dann atan an, um es zu begrenzen - und bringen Sie Ausreißer näher an das 1. oder 9. Dezil zurück, ohne ein Abschneiden zu verursachen.
Pichenettes

1
Wenn die Wellenform verkleinert ist, segmentieren Sie Ihr Signal nach größeren Elementen wie Balken oder Abschnitten, anstatt zu versuchen, einzelne Noten / Beats einzufärben.
Pichenettes
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.