Ich habe beschlossen, dieses Problem heute noch einmal zu versuchen, und es endlich geschafft, eine OGG-Datei zur Laufzeit in ein SoundEffect
Objekt zu laden . Folgendes habe ich getan! Laden Sie zuerst die folgende Bibliothek herunter, die eine Klasse enthält, die OGG-Dateien dekodieren kann:
Voraussetzung - Bibliothek herunterladen
Die Bibliothek hat bereits ein Beispiel, verwendet DynamicSoundEffectInstance
und streamt jedoch das Audio. Aber ich wollte alles auf einmal in ein normales SoundEffect
Objekt laden, damit der Prozess etwas anders war.
Schritt 1 - Datei dekodieren
Erstellen Sie zuerst eine Instanz von OggDecoder
und initialisieren Sie sie mit Ihrer Datei:
decoder = new OggDecoder();
decoder.Initialize(TitleContainer.OpenStream(@"sound.ogg"));
Schritt 2 - Dekodierte Daten abrufen
Lesen Sie alle Daten in einen Puffer. Dies sind die decodierten PCM-Rohdaten der Datei:
byte[] data = decoder.SelectMany(chunk => chunk.Bytes.Take(chunk.Length)).ToArray();
Schritt 3 - Erstellen Sie SoundEffect aus einem Stream mit dem vollständigen Wave-Datei-Header
Der SoundEffect
erforderliche Stream muss jedoch nicht nur die Rohdaten enthalten, sondern auch den vollständigen Header der Wave-Datei. Mit dieser Hilfsmethode können Sie den Header und die Daten schreiben:
private static void WriteWave(BinaryWriter writer, int channels, int rate, byte[] data)
{
writer.Write(new char[4] { 'R', 'I', 'F', 'F' });
writer.Write((int)(36 + data.Length));
writer.Write(new char[4] { 'W', 'A', 'V', 'E' });
writer.Write(new char[4] { 'f', 'm', 't', ' ' });
writer.Write((int)16);
writer.Write((short)1);
writer.Write((short)channels);
writer.Write((int)rate);
writer.Write((int)(rate * ((16 * channels) / 8)));
writer.Write((short)((16 * channels) / 8));
writer.Write((short)16);
writer.Write(new char[4] { 'd', 'a', 't', 'a' });
writer.Write((int)data.Length);
writer.Write(data);
}
Verwenden Sie diese Methode, um die Daten in einen Stream zu schreiben, dem Folgendes zugeführt werden kann SoundEffect.FromStream
:
using (MemoryStream stream = new MemoryStream())
using(BinaryWriter writer = new BinaryWriter(stream))
{
WriteWave(writer, decoder.Stereo ? 2 : 1, decoder.SampleRate, data);
stream.Position = 0;
soundEffect = SoundEffect.FromStream(stream);
}
Schritt 4 - Verwenden Sie den SoundEffect wie gewohnt
Ihre OGG-Datei ist jetzt geladen und kann wie jede andere Datei verwendet werden, SoundEffect
die über die Inhaltspipeline geladen wird:
soundEffect.Play();