Tôi quyết định đưa ra vấn đề này một lần thử hôm nay và cuối cùng đã quản lý để tải một tệp OGG khi chạy vào một SoundEffect
đối tượng. Đây là những gì tôi đã làm! Trước tiên hãy tải xuống thư viện bên dưới có chứa một lớp có khả năng giải mã các tệp OGG:
Điều kiện tiên quyết - Tải xuống thư viện
Thư viện đã có một ví dụ, nhưng nó sử dụng DynamicSoundEffectInstance
và truyền phát âm thanh. Nhưng tôi muốn tải tất cả cùng một lúc vào một SoundEffect
đối tượng thông thường nên quá trình này hơi khác một chút.
Bước 1 - Giải mã tập tin
Đầu tiên tạo một thể hiện OggDecoder
và khởi tạo nó với tệp của bạn:
decoder = new OggDecoder();
decoder.Initialize(TitleContainer.OpenStream(@"sound.ogg"));
Bước 2 - Nhận dữ liệu được giải mã
Đọc tất cả các dữ liệu vào một bộ đệm. Đây là dữ liệu PCM thô được giải mã của tệp:
byte[] data = decoder.SelectMany(chunk => chunk.Bytes.Take(chunk.Length)).ToArray();
Bước 3 - Tạo SoundEffect từ luồng chứa tiêu đề tệp sóng hoàn chỉnh
Tuy nhiên, luồng SoundEffect
yêu cầu phải chứa không chỉ dữ liệu thô mà còn cả tiêu đề tệp sóng hoàn chỉnh. Bạn có thể sử dụng phương thức trợ giúp này để viết tiêu đề cộng với dữ liệu:
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);
}
Sử dụng phương pháp đó để ghi dữ liệu vào luồng có thể được cung cấp tới 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);
}
Bước 4 - Sử dụng SoundEffect như bình thường
Tệp OGG của bạn hiện đã được tải và có thể được sử dụng như mọi tệp khác được SoundEffect
tải thông qua đường ống nội dung:
soundEffect.Play();