public ReadInt16 ( EndianType endianType ) : |
||
endianType | EndianType | |
return |
/// <summary> /// Adds silence to wav files alter volume /// </summary> /// <param name="silenceInsertLength">Milliseconds to insert at start of wav</param> /// <param name="volume">0=silent, 1=100%</param> /// <param name="maxLength">If the wav is longer than this then crop (includes silence), if 0 then don't crop</param> /// <param name="srcFilenames">Filenames to pad</param> public static void SetLengthSilenceAndVolume(float silenceInsertLength, float maxLength, float volume, string fileName) { FileStream inS; FileStream outS; WavSingleChunkHeader h; uint silenceLen; string tmpName; //uint origChunkLen; int copied; byte[] buff = new byte[10000]; for (int i = 0; i < buff.Length; i++) buff[i] = 0; tmpName = string.Format("{0}_{1}", fileName, Guid.NewGuid().ToString("N")); using (inS = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { using (outS = new FileStream(tmpName, FileMode.CreateNew, FileAccess.ReadWrite)) { h = ParseWavSingleChunkHeader(inS); //origChunkLen = h.ChunkLength; silenceLen = (uint)((float)h.AvgBytesPerSec * (silenceInsertLength / 1000F)); silenceLen -= silenceLen % h.BlockAlign; uint newLenBytes = maxLength != 0 ? (uint)((float)h.AvgBytesPerSec * (maxLength / 1000F)) : h.ChunkLength + silenceLen; newLenBytes -= newLenBytes % h.BlockAlign; h.ChunkLength = (uint)((uint)inS.Length - h.DataOffset) + silenceLen; if (h.ChunkLength > newLenBytes) h.ChunkLength = newLenBytes; h.ChunkLength -= h.ChunkLength % h.BlockAlign; h.FileLength = (h.ChunkLength + (uint)h.DataOffset) - 8; WriteSingleChunkHeader(h, outS); copied = 0; int len = 0; while (copied < silenceLen) { len = buff.Length; if (copied + buff.Length > silenceLen) len = (int)silenceLen - copied; outS.Write(buff, 0, len); copied += len; } //origChunkLen = h.ChunkLength; //we need to copy this much //copy audio and set volume BinaryEndianWriter bw = new BinaryEndianWriter(outS); BinaryEndianReader br = new BinaryEndianReader(inS); int b32; while (copied != h.ChunkLength) //length is block aligned so don't worry about channel count { b32 = (int)br.ReadInt16(EndianType.Little); b32 = (int)((float)b32 * volume); b32 = Math.Max((int)short.MinValue, Math.Min((int)short.MaxValue, b32)); bw.Write((short)b32, EndianType.Little); copied += 2; } //copied = (int)origChunkLen; //we've copied this much (silence included) //while (copied < h.ChunkLength) //pad to the length we said it was in the header //{ // inS.Read(buff, 0, buff.Length); // if (copied + buff.Length < h.ChunkLength) // outS.Write(buff, 0, buff.Length); // else // outS.Write(buff, 0, (int)h.ChunkLength % - copied); // copied += buff.Length; //} outS.Flush(); } } if (File.Exists(fileName)) { if (File.Exists(tmpName)) FileHelper.Move(tmpName, fileName); } }
/// <summary> /// Test for silent wavs /// </summary> /// <param name="filename">input raw wav</param> /// <param name="tolerence">0=0% to 1=1%</param> /// <returns></returns> public static bool IsWavSilent(string filename, float tolerence) { long tested = 0; long silent = 0; int pos; using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) { WavSingleChunkHeader h = WavProcessor.ParseWavSingleChunkHeader(fs); BinaryEndianReader br = new BinaryEndianReader(fs); for (int i = h.DataOffset; i < ((int)h.ChunkLength - 1024); i += (1024 * 1024)) //check at each meg { int block = 0; pos = i; fs.Seek((long)pos, SeekOrigin.Begin); while (block != 1024) //length is block aligned so don't worry about channel count { if (br.ReadInt16(EndianType.Little) == 0) silent += 2; tested += 2; block++; } } } if (((double)silent / (double)tested) >= (double)tolerence) return true; else return false; }