Ich habe beschlossen, dieses Problem heute noch einmal zu versuchen, und es endlich geschafft, eine OGG-Datei zur Laufzeit in ein SoundEffectObjekt 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 DynamicSoundEffectInstanceund streamt jedoch das Audio. Aber ich wollte alles auf einmal in ein normales SoundEffectObjekt laden, damit der Prozess etwas anders war.
Schritt 1 - Datei dekodieren
Erstellen Sie zuerst eine Instanz von OggDecoderund 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 SoundEffecterforderliche 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, SoundEffectdie über die Inhaltspipeline geladen wird:
soundEffect.Play();