Beispiel #1
0
        public byte[] SoundToWav(Sound sound)
        {
            var result = sound.getFormat(out _, out _, out int channels, out int bits);

            if (result != RESULT.OK)
            {
                return(null);
            }
            result = sound.getDefaults(out var frequency, out _);
            if (result != RESULT.OK)
            {
                return(null);
            }
            var sampleRate = (int)frequency;

            result = sound.getLength(out var length, TIMEUNIT.PCMBYTES);
            if (result != RESULT.OK)
            {
                return(null);
            }
            result = sound.@lock(0, length, out var ptr1, out var ptr2, out var len1, out var len2);
            if (result != RESULT.OK)
            {
                return(null);
            }
            byte[] buffer = new byte[len1 + 44];
            //添加wav头
            Encoding.UTF8.GetBytes("RIFF").CopyTo(buffer, 0);
            BitConverter.GetBytes(len1 + 36).CopyTo(buffer, 4);
            Encoding.UTF8.GetBytes("WAVEfmt ").CopyTo(buffer, 8);
            BitConverter.GetBytes(16).CopyTo(buffer, 16);
            BitConverter.GetBytes((short)1).CopyTo(buffer, 20);
            BitConverter.GetBytes((short)channels).CopyTo(buffer, 22);
            BitConverter.GetBytes(sampleRate).CopyTo(buffer, 24);
            BitConverter.GetBytes(sampleRate * channels * bits / 8).CopyTo(buffer, 28);
            BitConverter.GetBytes((short)(channels * bits / 8)).CopyTo(buffer, 32);
            BitConverter.GetBytes((short)bits).CopyTo(buffer, 34);
            Encoding.UTF8.GetBytes("data").CopyTo(buffer, 36);
            BitConverter.GetBytes(len1).CopyTo(buffer, 40);
            Marshal.Copy(ptr1, buffer, 44, (int)len1);
            result = sound.unlock(ptr1, ptr2, len1, len2);
            if (result != RESULT.OK)
            {
                return(null);
            }
            return(buffer);
        }
        private static void ExportAudioClip(IExportContainer container, Stream fileStream, AudioClip clip)
        {
            CREATESOUNDEXINFO exinfo = new CREATESOUNDEXINFO();

            FMOD.System system   = null;
            Sound       sound    = null;
            Sound       subsound = null;

            try
            {
                RESULT result = Factory.System_Create(out system);
                if (result != RESULT.OK)
                {
                    Logger.Instance.Log(LogType.Error, LogCategory.Export, $"Can't create factory for AudioClip {clip.Name}");
                    return;
                }

                result = system.init(1, INITFLAGS.NORMAL, IntPtr.Zero);
                if (result != RESULT.OK)
                {
                    Logger.Instance.Log(LogType.Error, LogCategory.Export, $"Can't init system for AudioClip {clip.Name}");
                    return;
                }

                byte[] data;
                using (MemoryStream memStream = new MemoryStream())
                {
                    clip.ExportBinary(container, memStream);
                    data = memStream.ToArray();
                }
                if (data.Length == 0)
                {
                    return;
                }

                exinfo.cbsize = Marshal.SizeOf(exinfo);
                exinfo.length = (uint)data.Length;
                result        = system.createSound(data, MODE.OPENMEMORY, ref exinfo, out sound);
                if (result != RESULT.OK)
                {
                    Logger.Instance.Log(LogType.Error, LogCategory.Export, $"Can't create sound for AudioClip {clip.Name}");
                    return;
                }

                result = sound.getSubSound(0, out subsound);
                if (result != RESULT.OK)
                {
                    Logger.Instance.Log(LogType.Error, LogCategory.Export, $"Can't get subsound for AudioClip {clip.Name}");
                    return;
                }

                result = subsound.getFormat(out SOUND_TYPE type, out SOUND_FORMAT format, out int numChannels, out int bitsPerSample);
                if (result != RESULT.OK)
                {
                    Logger.Instance.Log(LogType.Error, LogCategory.Export, $"Can't get format for AudioClip {clip.Name}");
                    return;
                }

                result = subsound.getDefaults(out float frequency, out int priority);
                if (result != RESULT.OK)
                {
                    Logger.Instance.Log(LogType.Error, LogCategory.Export, $"Can't get defaults for AudioClip {clip.Name}");
                    return;
                }

                int sampleRate = (int)frequency;
                result = subsound.getLength(out uint length, TIMEUNIT.PCMBYTES);
                if (result != RESULT.OK)
                {
                    Logger.Instance.Log(LogType.Error, LogCategory.Export, $"Can't get length for AudioClip {clip.Name}");
                    return;
                }

                result = subsound.@lock(0, length, out IntPtr ptr1, out IntPtr ptr2, out uint len1, out uint len2);
                if (result != RESULT.OK)
                {
                    Logger.Instance.Log(LogType.Error, LogCategory.Export, $"Can't lock for AudioClip {clip.Name}");
                    return;
                }

                using (BinaryWriter writer = new BinaryWriter(fileStream))
                {
                    writer.Write(Encoding.UTF8.GetBytes("RIFF"));
                    writer.Write(len1 + 36);
                    writer.Write(Encoding.UTF8.GetBytes("WAVEfmt "));
                    writer.Write(16);
                    writer.Write((short)1);
                    writer.Write((short)numChannels);
                    writer.Write(sampleRate);
                    writer.Write(sampleRate * numChannels * bitsPerSample / 8);
                    writer.Write((short)(numChannels * bitsPerSample / 8));
                    writer.Write((short)bitsPerSample);
                    writer.Write(Encoding.UTF8.GetBytes("data"));
                    writer.Write(len1);

                    for (int i = 0; i < len1; i++)
                    {
                        byte value = Marshal.ReadByte(ptr1, i);
                        writer.Write(value);
                    }
                }

                result = subsound.unlock(ptr1, ptr2, len1, len2);
                if (result != RESULT.OK)
                {
                    Logger.Instance.Log(LogType.Error, LogCategory.Export, $"Can't unlock for AudioClip {clip.Name}");
                }
            }
            finally
            {
                if (subsound != null)
                {
                    subsound.release();
                }
                if (sound != null)
                {
                    sound.release();
                }
                if (system != null)
                {
                    system.release();
                }
            }
        }