我想添加来自2个wav文件的信号并将每个字节转换为short,除以2以避免溢出,然后添加2个短值,然后在写入输出文件之前重新转换回字节。
有问题的wav文件是人类语音文件 - 不是纯正弦波。
我确保将来自同一频道的字节加在一起。 因此,来自一个文件的第0个位置的字节与来自第二个文件的偶数位置的字节混合,奇数定位的元素被添加到来自其他文件的奇数元素。
我的困难在于,当我使用一个静音(0声音)的wav时,过程完美无缺,输出声音完全可以听见但是当两个wav文件都有一些声音时,结果变成了一个响亮的声音。
问题:
我想在c#中完全执行此操作,并且不想使用NAudio / Nyquist /或其他库
有人可以帮忙吗?
int idx=0;
int OverlapPCT=20;
byte[] arrfile = {};
byte[] arrfileNext = {};
byte[] arrfileOut = {};
string TmpOutFile = Application.StartupPath + "\\" + "tmp.wav";
if (File.Exists (TmpOutFile)){File.Delete (TmpOutFile); }
FileStream fo = new FileStream (@TmpOutFile, FileMode.Append, FileAccess.Write);
BinaryWriter bw = new BinaryWriter (fo);
//header part of output file written here -
// set the position within the filestreams
// from where header ends and data is to be read
fs.Position = 44;
fsNext.Position = 44;
// read first stream into the arrfile, second into arrfileNext
fs.Read (arrfile, 0, fs.Length-44);
fsNext.Read (arrfileNext, 0, fsNext.Length-44);
// ---------------------------------
ThisArrOvlpWithPrev = 0;
ThisArrOvlpWithNext = arrfile.Length (OverlapPCT/100);
ThisArrNoOvlp = arrfile.Length - (ThisArrOvlpWithPrev+ThisArrOvlpWithNext);
Array.Clear (arrfileOut, 0, arrfileOut.Length);
// make sure arrfileOut is same size as overlap with previous
Array.Resize<byte> (ref arrfileOut, ThisArrOvlpWithPrev);
byte[] AmpAdjMergedByteArr= { };
short[] shArr = { };
short[] shArrNext = { };
// get both overlapping areas
// for first file, it begins at overlap with prev + part without overlap
// size of the overlap is overlap with next
Buffer.BlockCopy (arrfile, ThisArrOvlpWithPrev+ThisArrNoOvlp, shArr,0,ThisArrOvlpWithNext);
Buffer.BlockCopy (arrfileNext, 0, shArrNext, 0, ThisArrOvlpWithNext);
Array.Resize<byte> (ref AmpAdjMergedByteArr, ThisArrOvlpWithNext);
for (idx=0; idx<ThisArrOvlpWithNext; idx++)
{
AmpAdjMergedByteArr[idx] = (byte) (shArr[idx] /2 + shArrNext[idx]/2);
}
// now set the size of output file and write this to output
Buffer.BlockCopy (AmpAdjMergedByteArr, 0, arrfileOut, 0, AmpAdjMergedByteArr.Length);
bw.Write (arrfileOut);