// Copyright (c) 2012 Calvin Rien // http://the.darktable.com // // This software is provided 'as-is', without any express or implied warranty. In // no event will the authors be held liable for any damages arising from the use // of this software. // // Permission is granted to anyone to use this software for any purpose, // including commercial applications, and to alter it and redistribute it freely, // subject to the following restrictions: // // 1. The origin of this software must not be misrepresented; you must not claim // that you wrote the original software. If you use this software in a product, // an acknowledgment in the product documentation would be appreciated but is not // required. // // 2. Altered source versions must be plainly marked as such, and must not be // misrepresented as being the original software. // // 3. This notice may not be removed or altered from any source distribution. // // ============================================================================= // // derived from Gregorio Zanon's script // http://forum.unity3d.com/threads/119295-Writing-AudioListener.GetOutputData-to-wav-problem?p=806734&viewfull=1#post806734 using System; using System.IO; using UnityEngine; using System.Collections.Generic; public static class SavWav { const int HEADER_SIZE = 44; public static bool Save(string filename, AudioClip clip) { if (!filename.ToLower().EndsWith(".wav")) { filename += ".wav"; } var filepath = Path.Combine(Application.persistentDataPath, filename); Debug.Log(filepath); // Make sure directory exists if user is saving to sub dir. Directory.CreateDirectory(Path.GetDirectoryName(filepath)); using (var fileStream = CreateEmpty(filepath)) { ConvertAndWrite(fileStream, clip); WriteHeader(fileStream, clip); } return true; // TODO: return false if there's a failure saving the file } public static AudioClip TrimSilence(AudioClip clip, float min) { var samples = new float[clip.samples]; clip.GetData(samples, 0); return TrimSilence(new List(samples), min, clip.channels, clip.frequency); } public static AudioClip TrimSilence(List samples, float min, int channels, int hz) { return TrimSilence(samples, min, channels, hz, false, false); } public static AudioClip TrimSilence(List samples, float min, int channels, int hz, bool _3D, bool stream) { int i; for (i=0; i min) { break; } } samples.RemoveRange(0, i); for (i=samples.Count - 1; i>0; i--) { if (Mathf.Abs(samples[i]) > min) { break; } } samples.RemoveRange(i, samples.Count - i); var clip = AudioClip.Create("TempClip", samples.Count, channels, hz, _3D, stream); clip.SetData(samples.ToArray(), 0); return clip; } static FileStream CreateEmpty(string filepath) { var fileStream = new FileStream(filepath, FileMode.Create); byte emptyByte = new byte(); for(int i = 0; i < HEADER_SIZE; i++) //preparing the header { fileStream.WriteByte(emptyByte); } return fileStream; } static void ConvertAndWrite(FileStream fileStream, AudioClip clip) { var samples = new float[clip.samples]; clip.GetData(samples, 0); Int16[] intData = new Int16[samples.Length]; //converting in 2 float[] steps to Int16[], //then Int16[] to Byte[] Byte[] bytesData = new Byte[samples.Length * 2]; //bytesData array is twice the size of //dataSource array because a float converted in Int16 is 2 bytes. int rescaleFactor = 32767; //to convert float to Int16 for (int i = 0; i