Ignore:
Timestamp:
May 8, 2021, 3:44:24 AM (4 years ago)
Author:
geyser
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:
1 edited

Legend:

Unmodified
Added
Removed
  • OniSplit/Sound/WavFile.cs

    r1154 r1156  
    4040                var header = new WavFile()
    4141                {
    42                     sampleCount = 0
     42                    sampleCount = -1
    4343                };
    4444
     
    5656                        header.ReadDataChunk(reader, chunkSize);
    5757                }
    58 
    59                 header.ValidateSampleCount();
     58                header.TruncatePerFact();
    6059                return header;
    6160            }
     
    8685            soundData = reader.ReadBytes(chunkSize);
    8786        }
    88         private void ValidateSampleCount() // TODO: ACTUAL VALIDATION/CORRECTION
     87        private void TruncatePerFact() // TODO: MORE THOROUGH VALIDATION?
    8988        {
    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)
    9390            {
    9491                Console.WriteLine("The imported WAV file has no FACT chunk.");
    9592            }
    96             else // TODO: calculate sampleCountFromData, compare with sampleCount
     93            else if (format == WavFormat.Adpcm) // calculate truncated data size
    9794            {
    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);
    99109            }
    100110        }
     
    106116        public int BlockAlign => blockAlign;
    107117        public int BitsPerSample => bitsPerSample;
     118        public int SampleCount => sampleCount;
    108119        public byte[] ExtraData => extraData;
    109120        public byte[] SoundData => soundData;
Note: See TracChangeset for help on using the changeset viewer.