- Timestamp:
- May 3, 2021, 5:22:15 PM (4 years ago)
- Location:
- OniSplit
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
OniSplit/Program.cs
r1132 r1154 844 844 case ".wav": 845 845 if (task.Type == TemplateTag.NONE || task.Type == TemplateTag.SNDD) 846 importer = new WavImporter( );846 importer = new WavImporter(args.Any(a => a == "-demo")); 847 847 break; 848 848 -
OniSplit/Sound/WavExporter.cs
r1131 r1154 154 154 using (var writer = new BinaryWriter(stream)) 155 155 { 156 var blockSizeADPCM = 512 * sound.ChannelCount * sound.SampleRate / 22050; 156 var blockSizeADPCM = sound.BlockAlignment; 157 157 158 int wholeBlocks = sound.Data.Length / blockSizeADPCM; 158 159 int leftoverBytes = sound.Data.Length - (wholeBlocks * blockSizeADPCM); 159 int leftoverSamples = 8 * (leftoverBytes - 7 * sound.ChannelCount) 160 / 4 / sound.ChannelCount + 2; // 4 bits per sample 160 int leftoverSamples = 0; 161 if(leftoverBytes > 14) 162 leftoverSamples = 2 + (leftoverBytes - 7 * sound.ChannelCount) 163 * 8 / sound.BitsPerSample / sound.ChannelCount; 161 164 int paddingBytes = 0; 162 165 if (leftoverBytes > 0) // incomplete trailing block 163 166 paddingBytes = blockSizeADPCM - leftoverBytes; 164 var samplesPerBlock = 2 + (blockSizeADPCM - sound.ChannelCount * 7) * 8 / sound.ChannelCount / 4;165 166 Int32 sampleCount = sampleCount =wholeBlocks * samplesPerBlock + leftoverSamples;167 var samplesPerBlock = 2 + (blockSizeADPCM - sound.ChannelCount * 7) * 8 / sound.ChannelCount / sound.BitsPerSample; 168 169 Int32 sampleCount = wholeBlocks * samplesPerBlock + leftoverSamples; 167 170 168 171 if (sound.IsIMA4) // IMA4 ADPCM format -
OniSplit/Sound/WavFile.cs
r1114 r1154 2 2 using System.Collections.Generic; 3 3 using System.IO; 4 //using System.Runtime.Remoting.Metadata.W3cXsd2001; 4 5 5 6 namespace Oni.Sound … … 10 11 private const int fcc_RIFF = 0x46464952; 11 12 private const int fcc_WAVE = 0x45564157; 12 private const int fcc_fmt = 0x20746d66; 13 private const int fcc_fmt = 0x20746d66; 14 private const int fcc_fact = 0x74636166; 13 15 private const int fcc_data = 0x61746164; 14 16 … … 19 21 private int blockAlign; 20 22 private int bitsPerSample; 23 private int sampleCount; 21 24 private byte[] extraData; 22 25 private byte[] soundData; … … 35 38 throw new InvalidDataException("Not a WAV file"); 36 39 37 var header = new WavFile(); 40 var header = new WavFile() 41 { 42 sampleCount = 0 43 }; 38 44 39 45 for (int chunkType, chunkSize, chunkStart; reader.Position < size; reader.Position = chunkStart + chunkSize) … … 45 51 if (chunkType == fcc_fmt) 46 52 header.ReadFormatChunk(reader, chunkSize); 47 else if (chunkType == fcc_data) 53 if (chunkType == fcc_fact) 54 header.ReadFactChunk(reader, chunkSize); 55 if (chunkType == fcc_data) 48 56 header.ReadDataChunk(reader, chunkSize); 49 57 } 50 58 59 header.ValidateSampleCount(); 51 60 return header; 52 61 } … … 68 77 } 69 78 79 private void ReadFactChunk(BinaryReader reader, int chunkSize) 80 { 81 sampleCount = reader.ReadInt32(); 82 } 83 70 84 private void ReadDataChunk(BinaryReader reader, int chunkSize) 71 85 { 72 86 soundData = reader.ReadBytes(chunkSize); 87 } 88 private void ValidateSampleCount() // TODO: ACTUAL VALIDATION/CORRECTION 89 { 90 int sampleCountFromData = 0; 91 int wholeBlocks = soundData.Length / blockAlign; 92 if(sampleCount == 0) // not explicitly set (no fact chunk present) 93 { 94 Console.WriteLine("The imported WAV file has no FACT chunk."); 95 } 96 else // TODO: calculate sampleCountFromData, compare with sampleCount 97 { 98 99 } 73 100 } 74 101 -
OniSplit/Sound/WavImporter.cs
r1114 r1154 6 6 internal class WavImporter : Importer 7 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 8 16 public override void Import(string filePath, string outputDirPath) 9 17 { … … 44 52 45 53 var sndd = CreateInstance(TemplateTag.SNDD, name); 54 if (convertToDemo) 55 { 56 // TODO: also validate other ADPCM parameters (coefficient table)? 57 if (wav.Format != WavFormat.Adpcm) // Or is PCM supported, actually? 58 Console.WriteLine("Cannot convert to PC demo: ADPCM format required!"); 59 if (wav.SampleRate != 22050) 60 Console.WriteLine("Cannot convert to PC demo: 22050 kHz required!"); 61 if (wav.BlockAlign != 512 * wav.ChannelCount) 62 Console.WriteLine("Cannot convert to PC demo: wrong block alignment!"); 63 if (wav.BitsPerSample != 4) 64 Console.WriteLine("Cannot convert to PC demo: wrong bits per sample!"); 46 65 47 using (var writer = sndd.OpenWrite(8)) 66 using (var writer = sndd.OpenWrite()) 67 { 68 if (wav.ChannelCount == 2) 69 writer.WriteInt16(3); 70 else 71 writer.WriteInt16(1); 72 writer.WriteInt16(0); 73 writer.Write((int)duration); 74 writer.Write(wav.SoundData.Length); 75 writer.Write(WriteRawPart(wav.SoundData)); 76 } 77 } 78 else 48 79 { 49 writer.Write((short)wav.Format); 50 writer.WriteInt16(wav.ChannelCount); 51 writer.Write(wav.SampleRate); 52 writer.Write(wav.AverageBytesPerSecond); 53 writer.WriteInt16(wav.BlockAlign); 54 writer.WriteInt16(wav.BitsPerSample); 55 writer.WriteInt16(wav.ExtraData.Length); 56 writer.Write(wav.ExtraData); 57 writer.Skip(32 - wav.ExtraData.Length); 58 writer.Write((short)duration); 59 writer.Write(wav.SoundData.Length); 60 writer.Write(WriteRawPart(wav.SoundData)); 80 using (var writer = sndd.OpenWrite()) 81 { 82 if (wav.Format == WavFormat.Adpcm) 83 writer.WriteInt16(8); 84 else 85 writer.WriteInt16(0); 86 writer.WriteInt16(0); 87 writer.Write((short)wav.Format); 88 writer.WriteInt16(wav.ChannelCount); 89 writer.Write(wav.SampleRate); 90 writer.Write(wav.AverageBytesPerSecond); 91 writer.WriteInt16(wav.BlockAlign); 92 writer.WriteInt16(wav.BitsPerSample); 93 writer.WriteInt16(wav.ExtraData.Length); 94 writer.Write(wav.ExtraData); 95 writer.Skip(32 - wav.ExtraData.Length); 96 writer.Write((short)duration); 97 writer.Write(wav.SoundData.Length); 98 writer.Write(WriteRawPart(wav.SoundData)); 99 } 61 100 } 62 101 }
Note:
See TracChangeset
for help on using the changeset viewer.