Changeset 1156
- Timestamp:
- May 8, 2021, 3:44:24 AM (4 years ago)
- Location:
- OniSplit/Sound
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
OniSplit/Sound/AifExporter.cs
r1131 r1156 31 31 { 32 32 var sound = SoundData.Read(descriptor, do_pc_demo_test); 33 if (!(sound.IsIMA4)) 34 throw new NotSupportedException("Transcoding from MS ADPCM (PC) to IMA4 ADPCM (Mac) not supported!"); 33 35 34 36 using (var stream = File.Create(Path.Combine(OutputDirPath, descriptor.FullName + ".aif"))) 35 37 using (var writer = new BinaryWriter(stream)) 36 38 { 37 if (!(sound.IsIMA4))38 {39 throw new NotSupportedException("Transcoding from MS ADPCM (PC) to IMA4 ADPCM (Mac) not supported!");40 }41 39 writer.Write(Utils.ByteSwap(fcc_FORM)); 42 40 writer.Write(Utils.ByteSwap(50 + sound.Data.Length)); -
OniSplit/Sound/AifImporter.cs
r1114 r1156 53 53 writer.Write(aif.SoundData.Length); 54 54 writer.Write(WriteRawPart(aif.SoundData)); 55 writer.Skip(8); 55 56 } 56 57 } -
OniSplit/Sound/SoundData.cs
r1155 r1156 158 158 } 159 159 } 160 // Console.WriteLine("Sample count:");161 // Console.WriteLine(sound.SampleCount);162 163 160 return sound; 164 161 } -
OniSplit/Sound/WavExporter.cs
r1154 r1156 154 154 using (var writer = new BinaryWriter(stream)) 155 155 { 156 var blockSizeADPCM = sound.BlockAlignment; 157 158 int wholeBlocks = sound.Data.Length / blockSizeADPCM; 159 int leftoverBytes = sound.Data.Length - (wholeBlocks * blockSizeADPCM); 160 int leftoverSamples = 0; 161 if(leftoverBytes > 14) 162 leftoverSamples = 2 + (leftoverBytes - 7 * sound.ChannelCount) 163 * 8 / sound.BitsPerSample / sound.ChannelCount; 164 int paddingBytes = 0; 165 if (leftoverBytes > 0) // incomplete trailing block 166 paddingBytes = blockSizeADPCM - leftoverBytes; 167 var samplesPerBlock = 2 + (blockSizeADPCM - sound.ChannelCount * 7) * 8 / sound.ChannelCount / sound.BitsPerSample; 168 169 Int32 sampleCount = wholeBlocks * samplesPerBlock + leftoverSamples; 170 156 int blockSizeADPCM, samplesPerBlock, sampleCount, paddingBytes = 0; 171 157 if (sound.IsIMA4) // IMA4 ADPCM format 172 158 { … … 174 160 samplesPerBlock = 64; 175 161 sampleCount = (sound.Data.Length / blockSizeADPCM) * samplesPerBlock; 162 } 163 else 164 { 165 blockSizeADPCM = sound.BlockAlignment; 166 int wholeBlocks = sound.Data.Length / blockSizeADPCM; 167 int leftoverBytes = sound.Data.Length - (wholeBlocks * blockSizeADPCM); 168 int leftoverSamples = 0; 169 if (leftoverBytes > 7 * sound.ChannelCount) 170 leftoverSamples = 2 + (leftoverBytes - 7 * sound.ChannelCount) 171 * 8 / sound.BitsPerSample / sound.ChannelCount; 172 else 173 Console.Error.WriteLine("Improper trailing bytes/samples!"); 174 if (leftoverBytes > 0) // incomplete trailing block 175 paddingBytes = blockSizeADPCM - leftoverBytes; 176 samplesPerBlock = 2 + (blockSizeADPCM - sound.ChannelCount * 7) * 8 / sound.ChannelCount / sound.BitsPerSample; 177 sampleCount = wholeBlocks * samplesPerBlock + leftoverSamples; 176 178 } 177 179 if (!convert_to_PCM) -
OniSplit/Sound/WavFile.cs
r1154 r1156 40 40 var header = new WavFile() 41 41 { 42 sampleCount = 042 sampleCount = -1 43 43 }; 44 44 … … 56 56 header.ReadDataChunk(reader, chunkSize); 57 57 } 58 59 header.ValidateSampleCount(); 58 header.TruncatePerFact(); 60 59 return header; 61 60 } … … 86 85 soundData = reader.ReadBytes(chunkSize); 87 86 } 88 private void ValidateSampleCount() // TODO: ACTUAL VALIDATION/CORRECTION87 private void TruncatePerFact() // TODO: MORE THOROUGH VALIDATION? 89 88 { 90 int sampleCountFromData = 0; 91 int wholeBlocks = soundData.Length / blockAlign; 92 if(sampleCount == 0) // not explicitly set (no fact chunk present) 89 if(sampleCount == -1) // not explicitly set (no fact chunk present) 93 90 { 94 91 Console.WriteLine("The imported WAV file has no FACT chunk."); 95 92 } 96 else // TODO: calculate sampleCountFromData, compare with sampleCount93 else if (format == WavFormat.Adpcm) // calculate truncated data size 97 94 { 98 95 var blockSizeADPCM = blockAlign; 96 var samplesPerBlock = 2 + (blockSizeADPCM - channelCount * 7) * 8 / channelCount / bitsPerSample; 97 int wholeBlocks = sampleCount / samplesPerBlock; 98 if (wholeBlocks * blockAlign > soundData.Length) 99 Console.Error.WriteLine("Sample count exceeds the range of sound data."); 100 int leftoverSamples = sampleCount - wholeBlocks * samplesPerBlock; 101 if (leftoverSamples < 2) // a block always starts with at least two samples? 102 Console.Error.WriteLine("Improper trailing bytes/samples!"); 103 if (bitsPerSample != 4) // are MS ADPCM nibbles always 4-bit-sized? 104 Console.Error.WriteLine("Nibble size is expected to be 4 bits!"); 105 int leftoverNibbles = (leftoverSamples - 2) * channelCount; 106 int leftoverBytes = 7 * channelCount 107 + (int)Math.Ceiling((leftoverNibbles * bitsPerSample) * 0.125); 108 Array.Resize(ref soundData, wholeBlocks * blockAlign + leftoverBytes); 99 109 } 100 110 } … … 106 116 public int BlockAlign => blockAlign; 107 117 public int BitsPerSample => bitsPerSample; 118 public int SampleCount => sampleCount; 108 119 public byte[] ExtraData => extraData; 109 120 public byte[] SoundData => soundData; -
OniSplit/Sound/WavImporter.cs
r1154 r1156 46 46 private void WriteSNDD(string name, WavFile wav) 47 47 { 48 float duration = wav.SoundData.Length * 8.0f / wav.BitsPerSample; 49 duration /= wav.SampleRate; 50 duration /= wav.ChannelCount; 51 duration *= 60.0f; 48 float duration = wav.SampleCount * 60.0f / wav.SampleRate; 52 49 53 50 var sndd = CreateInstance(TemplateTag.SNDD, name); … … 74 71 writer.Write(wav.SoundData.Length); 75 72 writer.Write(WriteRawPart(wav.SoundData)); 73 writer.Skip(8); 76 74 } 77 75 } … … 97 95 writer.Write(wav.SoundData.Length); 98 96 writer.Write(WriteRawPart(wav.SoundData)); 97 writer.Skip(24); 99 98 } 100 99 }
Note:
See TracChangeset
for help on using the changeset viewer.