MIDI Bibliothek für .NET/Mono

Für ein kleines Experiment war ich auf der Suche nach einer .NET Bibliothek mit welcher sich MIDI Dateien schreiben lassen. Auf den ersten Blick findet man dabei nur Bibliotheken welche das MIDI Interface ansprechen, aber solche welche Midi Dateien schreiben können sind eher selten. Abhilfe schuf hier die Bibliothek NAudio, welche unter http://naudio.codeplex.com/ zu finden ist. Das Problem an der Bibliothek ist ihre schiere Größe und die fehlende Plattformunabhägigkeit, da für einige Stellen P-Invokes in native DLLs benötigt werden. Daneben bietet NAudio wesentlich mehr als nur MIDI-Support, so das die Bibliothek für meinen Zweck nicht zum tragen kam.

Dank der freien Lizenz (unter der Ms-Pl) stellte dies kein Problem da und so wurde libmidi.net aus der Taufe gehoben. Die Bibliothek bestand am Anfang aus dem Midi Teil von NAudio. Im Laufe der Entwicklung wurde alle Möglichkeiten für den Zugriff auf MIDI-Geräte entfernt. Die Bibliothek ist damit zu einer kleinen Bibliothek zum Lesen und Schreiben von MIDI-Dateien geworden. Dazu wurden auch einige Dinge wie die „MidiNote“-Enumeration hinzugefügt, anhand deren man die Noten als Noten anstatt als Nummern angeben kann. Im Gegensatz zum Original, welches hauptsächlich auf die Bearbeitung bereits existierender MIDIs abziehlt, soll die Bibliothek so gestaltet werden, das auch das Erzeugen neuer MIDIs leicht von der Hand geht. Zu finden ist das Projekt unter https://github.com/seeseekey/libmidi.net.

de4dot

Ein Programm welches in C# geschrieben wird, wird beim kompilieren in ein Intermediate-Assembly umgewandelt. Das bedeutet das der Code in einer Zwischensprache darauf wartet auf seinem Zielsystem in nativen Code umgewandelt zu werden. Der Vor- und auch Nachteil dieser Vorgehensweise ist, das sich der Quellcode sehr einfach aus dem IL-Code zurückwandeln lässt. Im Idealfall verliert man bloß einige Variablennamen.

Um das zu verhindern gibt es sogenannte Obfuscatoren, welche versuchen den entsprechenden Quelltext zu verschleiern, so das er nicht mehr einfach zurückgewandelt werden kann. Aber wie so oft im Leben gibt es auch hier einen Wettlauf mit der Zeit. So gibt es einige Tools welche den obfuskierten Quelltext wieder deobfuskieren. Eines dieser Projekte ist „de4dot“ welches unter https://bitbucket.org/0xd4d/de4dot/ zu finden ist. Das unter der GPL stehende Projekte, erkennt dabei den verwendeten Obfuscator und versucht seine Änderungen soweit wie möglich rückgängig zu machen. Dabei werden eine stattliche Anzahl von Obfuscatoren, wie der Dotfuscator, Goliath.NET und Skater.NET unterstützt.

Controls im Visual Studio zur Designzeit debuggen

Die Entwicklung von Controls unter .NET und Windows Form geht eigentlich relativ leicht von der Hand. Kompliziert wird das ganze immer dann wenn Fehler auftreten. So lassen sich Controls welche im Designmodus Exceptions werfen, nur schwer debuggen. Aber wie immer gilt, wo ein Wille ist, da ist auch ein Weg.

Das Attach to Process Fenster

Das Attach to Process Fenster

Um ein Control zu debuggen, sollte man das entsprechende Projekt bzw. die Solution zwei mal öffnen. In dem einen Visual Studio öffnet man nun den Designer. Im anderen Visual Studio wählt man im Debugmenü den Punkt „Attach to Process…“ aus. Das sich öffnende Fenster zeigt alle Prozesse an, an welche sich der Debugger anhängen kann. Hier wird das erste Visual Studio (das mit dem Designer) ausgewählt. Nun kann man im Quelltext des Controls Breakpoints setzen und somit die Ausführung überwachen. Allerdings sollte man sich dabei nicht wundern, das dass Control im Debugger größer erscheint als es eigentlich ist. Der Grund dafür liegt darin, das genau genommen nicht das Control sondern das gesamte Visual Studio debuggt wird.

Threadsicheres Dictionary unter .NET

Das Dictionary unter .NET ist eine schöne Datenstruktur mit der man effizient Schlüssel- und Wertepaare verwalten kann:

Dictionary<uint, byte[]> idToValues=new Dictionary<uint, byte[]>();
idToValues.Add(1, data);

Problematisch wird das ganze, sobald in mehreren Threads gearbeitet wird, welche alle auf das gleiche Dictionary zugreifen. Hier müssen die Zugriffe auf das Wörterbuch kontrolliert und entsprechend gesperrt werden. Einfacher wird es mit der 4er .NET Framework. Dort gibt es ein ConcurrentDictionary welches von Haus aus threadsicher ist und dem Entwickler eine Menge Arbeit erspart.

ConcurrentDictionary<uint, byte[]> idToValues=new ConcurrentDictionary<uint, byte[]>();
idToValues.TryAdd(1, data);

Das „ConcurrentDictionary“ kann dabei im Großen und Ganzen wie ein normales Dictionary genutzt werden, so das die Umstellung nicht allzu schwer fallen sollte.

Hash von einem beliebigen .NET Objekt erzeugen

Unter .NET gibt es an jedem Objekt die Methode „GetHashCode“ welche einen HashCode zurückliefert. Das Problem an dieser Methode ist jedoch das sie vom Objekt selbst implementiert werden muss. Möchte man nun eine Methode mit der man jedes Objekt generisch hashen kann, so ist diese Funktion hilfreich:

public string GetSHA1HashFromObject(object obj)
{
	SHA1CryptoServiceProvider sha1Provider=new SHA1CryptoServiceProvider();
	DataContractSerializer serializer=new DataContractSerializer(obj.GetType());

	using(MemoryStream memoryStream=new MemoryStream())
	{
		serializer.WriteObject(memoryStream, obj);
		sha1Provider.ComputeHash(memoryStream.ToArray());
		return Convert.ToBase64String(sha1Provider.Hash);
	}
}

Die Funktion serialisiert dabei das Objekt und hasht anschließend das serialisierte Objekt. Damit ist es egal, welches Objekt in die Funktion gegeben wird.