예제 #1
0
 private static void WriteXMAFile(BlamSound blamSound)
 {
     using (EndianWriter output = new EndianWriter(new FileStream(XMAFile, FileMode.Create, FileAccess.Write, FileShare.None), EndianFormat.BigEndian))
     {
         XMAFile XMAfile = new XMAFile(blamSound);
         XMAfile.Write(output);
     }
 }
예제 #2
0
        public void ExtractXMA(CacheFile.IndexItem blamTag, string directory)
        {
            if (BlamSoundGestalt == null)
            {
                BlamSoundGestalt = PortingContextFactory.LoadSoundGestalt(CacheContext, ref BlamCache);
            }

            var blamContext = new CacheSerializationContext(ref BlamCache, blamTag);

            var sound = BlamCache.Deserializer.Deserialize <Sound>(blamContext);


            var xmaFileSize = BlamSoundGestalt.GetFileSize(sound.SoundReference.PitchRangeIndex, sound.SoundReference.PitchRangeCount);

            if (xmaFileSize < 0)
            {
                return;
            }

            var xmaData = BlamCache.GetSoundRaw(sound.SoundReference.ZoneAssetHandle, xmaFileSize);

            if (xmaData == null)
            {
                Console.WriteLine($"ERROR: Failed to find sound data!");
                return;
            }

            var    parts    = blamTag.Name.Split('\\');
            string baseName = parts[parts.Length - 1];

            for (int pitchRangeIndex = sound.SoundReference.PitchRangeIndex; pitchRangeIndex < sound.SoundReference.PitchRangeIndex + sound.SoundReference.PitchRangeCount; pitchRangeIndex++)
            {
                var relativePitchRangeIndex = pitchRangeIndex - sound.SoundReference.PitchRangeIndex;
                var permutationCount        = BlamSoundGestalt.GetPermutationCount(pitchRangeIndex);

                for (int i = 0; i < permutationCount; i++)
                {
                    BlamSound blamSound       = SoundConverter.GetXMA(BlamCache, BlamSoundGestalt, sound, relativePitchRangeIndex, i, xmaData);
                    string    permutationName = $"{baseName}_{relativePitchRangeIndex}_{i}";
                    var       fileName        = $"{directory}\\{permutationName}.xma";

                    using (EndianWriter output = new EndianWriter(new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None), EndianFormat.BigEndian))
                    {
                        XMAFile XMAfile = new XMAFile(blamSound);
                        XMAfile.Write(output);
                    }
                }
            }
        }
예제 #3
0
        public void ExtractXMA(string directory)
        {
            if (BlamSoundGestalt == null)
            {
                using (var stream = Cache.OpenCacheRead())
                    BlamSoundGestalt = PortingContextFactory.LoadSoundGestalt(Cache, stream);
            }


            var resourceDefinition = Cache.ResourceCache.GetSoundResourceDefinition(Sound.Resource);
            var xmaFileSize        = BlamSoundGestalt.GetFileSize(Sound.SoundReference.PitchRangeIndex, Sound.SoundReference.PitchRangeCount);

            if (xmaFileSize < 0)
            {
                return;
            }

            var xmaData = resourceDefinition.Data.Data;

            if (xmaData == null)
            {
                Console.WriteLine($"ERROR: Failed to find sound data!");
                return;
            }

            var    parts    = Tag.Name.Split('\\');
            string baseName = parts[parts.Length - 1];

            for (int pitchRangeIndex = Sound.SoundReference.PitchRangeIndex; pitchRangeIndex < Sound.SoundReference.PitchRangeIndex + Sound.SoundReference.PitchRangeCount; pitchRangeIndex++)
            {
                var relativePitchRangeIndex = pitchRangeIndex - Sound.SoundReference.PitchRangeIndex;
                var permutationCount        = BlamSoundGestalt.GetPermutationCount(pitchRangeIndex);

                for (int i = 0; i < permutationCount; i++)
                {
                    BlamSound blamSound       = SoundConverter.GetXMA(Cache, BlamSoundGestalt, Sound, relativePitchRangeIndex, i, xmaData);
                    string    permutationName = $"{baseName}_{relativePitchRangeIndex}_{i}";
                    var       fileName        = $"{directory}\\{permutationName}.xma";

                    using (EndianWriter output = new EndianWriter(new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None), EndianFormat.BigEndian))
                    {
                        XMAFile XMAfile = new XMAFile(blamSound);
                        XMAfile.Write(output);
                    }
                }
            }
        }
예제 #4
0
        public static string ConvertXMAPermutation(byte[] buffer, int channelCount, int sampleRate, bool loopingSound, bool useCache, string permutationName)
        {
            if (!File.Exists(@"Tools\ffmpeg.exe"))
            {
                Console.WriteLine("Missing tools, please install all the required tools before porting sounds.");
                return(null);
            }

            var gui       = Guid.NewGuid();
            var audioFile = permutationName;
            var tempXMA   = $"{audioFile}.xma";
            var tempWAV   = $"{audioFile}_temp.wav";
            var fixedWAV  = $"{audioFile}_truncated.wav";
            var tempMP3   = $"{audioFile}_temp.mp3";
            var resultWAV = $"{audioFile}.wav";
            var resultMP3 = $"{audioFile}.mp3";

CLEAN_FILES:
            try
            {
                if (File.Exists(tempXMA))
                {
                    File.Delete(tempXMA);
                }
                if (File.Exists(tempWAV))
                {
                    File.Delete(tempWAV);
                }
                if (File.Exists(fixedWAV))
                {
                    File.Delete(fixedWAV);
                }
                if (File.Exists(resultWAV))
                {
                    File.Delete(resultWAV);
                }
                if (File.Exists(resultMP3))
                {
                    File.Delete(resultMP3);
                }
                if (File.Exists(tempMP3))
                {
                    File.Delete(tempMP3);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                goto CLEAN_FILES;
            }

            using (EndianWriter output = new EndianWriter(new FileStream(tempXMA, FileMode.Create, FileAccess.Write, FileShare.None), EndianFormat.BigEndian))
            {
                XMAFile XMAfile = new XMAFile(buffer, channelCount, sampleRate);
                XMAfile.Write(output);
            }

            if (!ConvertXMAToWAV(tempXMA, tempWAV))
            {
                return(null);
            }

            // Convert to MP3 and remove header
            if (loopingSound && channelCount <= 2)
            {
                if (!ConvertWAVToMP3Looping(tempWAV, tempMP3))
                {
                    return(null);
                }
            }
            else
            {
                // truncate file
                byte[] originalWAVdata  = File.ReadAllBytes(tempWAV);
                byte[] truncatedWAVdata = TruncateWAVFile(originalWAVdata, sampleRate, channelCount, 0x2C);

                using (EndianWriter writer = new EndianWriter(new FileStream(fixedWAV, FileMode.Create, FileAccess.Write, FileShare.None), EndianFormat.BigEndian))
                {
                    WAVFile WAVfile = new WAVFile(truncatedWAVdata, channelCount, sampleRate);
                    WAVfile.Write(writer);
                }

                // add code to handle looping sounds with more than 2 channels here. Mp3Loop does not handle that kind of file.

                if (!ConvertWAVToMP3(fixedWAV, tempMP3))
                {
                    return(null);
                }
            }


            int size = (int)(new FileInfo(tempMP3).Length - 0x2D);

            byte[] MP3stream = File.ReadAllBytes(tempMP3);

            using (var output = new FileStream(resultMP3, FileMode.Create, FileAccess.Write, FileShare.None))
                output.Write(MP3stream, 0x2D, size);

CLEAN_FILES2:
            try
            {
                if (File.Exists(tempXMA))
                {
                    File.Delete(tempXMA);
                }
                if (File.Exists(tempWAV))
                {
                    File.Delete(tempWAV);
                }
                if (File.Exists(fixedWAV))
                {
                    File.Delete(fixedWAV);
                }
                if (File.Exists(resultWAV))
                {
                    File.Delete(resultWAV);
                }
                if (File.Exists(tempMP3))
                {
                    File.Delete(tempMP3);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                goto CLEAN_FILES2;
            }

            return(resultMP3);
        }