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(); } } }