ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/OniSplit/Sound/WavImporter.cs
Revision: 1156
Committed: Sat May 8 01:44:24 2021 UTC (4 years, 5 months ago) by geyser
File size: 4094 byte(s)
Log Message:
Fixed importing of "fact" chunk, as well as an unhandled fatal when attempting to transcode IMA4 to MS ADPCM. Also added missing padding to SNDD template and fixed the duration calculation for WAV-to-SNDD.

File Contents

# Content
1 using System;
2 using System.IO;
3
4 namespace Oni.Sound
5 {
6 internal class WavImporter : Importer
7 {
8 private readonly bool convertToDemo;
9
10 public WavImporter(bool toDemo)
11 : base(toDemo?InstanceFileHeader.OniMacTemplateChecksum:InstanceFileHeader.OniPCTemplateChecksum)
12 {
13 convertToDemo = toDemo;
14 }
15
16 public override void Import(string filePath, string outputDirPath)
17 {
18 var wav = WavFile.FromFile(filePath);
19
20 if (wav.Format != WavFormat.Pcm && wav.Format != WavFormat.Adpcm)
21 {
22 Console.Error.WriteLine("Unsupported WAV format (0x{0:X})", wav.Format);
23 return;
24 }
25
26 if (wav.ChannelCount != 1 && wav.ChannelCount != 2)
27 {
28 Console.Error.WriteLine("Unsupported number of channels ({0})", wav.ChannelCount);
29 return;
30 }
31
32 if (wav.SampleRate != 22050 && wav.SampleRate != 44100)
33 {
34 Console.Error.WriteLine("Unsupported sample rate ({0} Hz)", wav.SampleRate);
35 return;
36 }
37
38 if (wav.ExtraData.Length > 32)
39 throw new NotSupportedException(string.Format("Unsupported wave format extra data size ({0})", wav.ExtraData.Length));
40
41 BeginImport();
42 WriteSNDD(Path.GetFileNameWithoutExtension(filePath), wav);
43 Write(outputDirPath);
44 }
45
46 private void WriteSNDD(string name, WavFile wav)
47 {
48 float duration = wav.SampleCount * 60.0f / wav.SampleRate;
49
50 var sndd = CreateInstance(TemplateTag.SNDD, name);
51 if (convertToDemo)
52 {
53 // TODO: also validate other ADPCM parameters (coefficient table)?
54 if (wav.Format != WavFormat.Adpcm) // Or is PCM supported, actually?
55 Console.WriteLine("Cannot convert to PC demo: ADPCM format required!");
56 if (wav.SampleRate != 22050)
57 Console.WriteLine("Cannot convert to PC demo: 22050 kHz required!");
58 if (wav.BlockAlign != 512 * wav.ChannelCount)
59 Console.WriteLine("Cannot convert to PC demo: wrong block alignment!");
60 if (wav.BitsPerSample != 4)
61 Console.WriteLine("Cannot convert to PC demo: wrong bits per sample!");
62
63 using (var writer = sndd.OpenWrite())
64 {
65 if (wav.ChannelCount == 2)
66 writer.WriteInt16(3);
67 else
68 writer.WriteInt16(1);
69 writer.WriteInt16(0);
70 writer.Write((int)duration);
71 writer.Write(wav.SoundData.Length);
72 writer.Write(WriteRawPart(wav.SoundData));
73 writer.Skip(8);
74 }
75 }
76 else
77 {
78 using (var writer = sndd.OpenWrite())
79 {
80 if (wav.Format == WavFormat.Adpcm)
81 writer.WriteInt16(8);
82 else
83 writer.WriteInt16(0);
84 writer.WriteInt16(0);
85 writer.Write((short)wav.Format);
86 writer.WriteInt16(wav.ChannelCount);
87 writer.Write(wav.SampleRate);
88 writer.Write(wav.AverageBytesPerSecond);
89 writer.WriteInt16(wav.BlockAlign);
90 writer.WriteInt16(wav.BitsPerSample);
91 writer.WriteInt16(wav.ExtraData.Length);
92 writer.Write(wav.ExtraData);
93 writer.Skip(32 - wav.ExtraData.Length);
94 writer.Write((short)duration);
95 writer.Write(wav.SoundData.Length);
96 writer.Write(WriteRawPart(wav.SoundData));
97 writer.Skip(24);
98 }
99 }
100 }
101 }
102 }