Пример #1
0
	public static byte[] EncodeToADPCM(AudioClip source, IMAADPCM.ADPCMState[] states = null)
	{
		Debug.Log ("channels = " + source.channels);
		float[] data = new float[source.samples*source.channels];
		source.GetData(data, 0);
		IMAADPCM.ADPCMState state = new IMAADPCM.ADPCMState();
		state.valprev = 0;
		
		int count = source.samples;
		byte[] bytes = new byte[count/2];
		for (int i = 0; i < count/2; i++) 
		{
			int m1 = i*2;
			int m2 = i*2+1;
			
			//samples en entrée
			short i1 = (short)(data[i*2+0]*32768f);
			short i2 = (short)(data[i*2+1]*32768f);
			
			if (m1%1017 == 0 && states != null)
			{
				Debug.Log ("modulo1");
				int stateindex = m1/1017;
				states[stateindex].valprev = state.valprev;
				states[stateindex].index = state.index;
			}
			byte b1 = IMAADPCM.encodeADPCM(i1, ref state);
			
			if (m2%1017 == 0 && states != null)
			{
				Debug.Log ("modulo2");
				int stateindex = m2/1017;
				states[stateindex].valprev = state.valprev;
				states[stateindex].index = state.index;
			}
			byte b2 = IMAADPCM.encodeADPCM(i2, ref state);
			
			//Debug.Log (""+b1+" " + b2);
			//bytes[i] = (byte)(b1*16+b2);
			
			bytes[i] = (byte)(b1*16+b2);
		}
		return bytes;
	}
Пример #2
0
        public static MemoryStream encodeCompressedFromWAV(string source)
        {
            WAVFile      wav = new WAVFile();
            MemoryStream ms  = new MemoryStream();

            wav.Open(source, WAVFile.WAVFileMode.READ);

            IMAADPCM.ADPCMState state = new IMAADPCM.ADPCMState();
            byte enc1, enc2;

            for (long i = 0; i < wav.NumSamples / 2; i++)
            {
                enc1 = IMAADPCM.encodeADPCM(wav.GetNextSampleAs16Bit(), ref state);
                enc2 = IMAADPCM.encodeADPCM(wav.GetNextSampleAs16Bit(), ref state);
                ms.Write(BitConverter.GetBytes(Convert.ToInt32(Utils.binaryString(enc2, 4) + Utils.binaryString(enc1, 4), 2)), 0, 1);
            }

            wav.Close();
            return(ms);
        }
Пример #3
0
        public static void decodeCompressedToWAV(MemoryStream data, WAVFile target)
        {
            //WAVFile wav = new WAVFile();
            //wav.Create(@"E:\TEMP\SPARKIV\~AudioModding\STARTING_TUNE_LEFT_DECODED.wav", false, 44100, 16, true);

            //FileStream fs = new FileStream(@"E:\TEMP\SPARKIV\~AudioModding\STARTING_TUNE_LEFT.bin", FileMode.Open, FileAccess.Read);
            byte[] buffer = new byte[1];

            IMAADPCM.ADPCMState state = new IMAADPCM.ADPCMState();
            short val;

            for (long i = 0; i < data.Length; i++)
            {
                data.Read(buffer, 0, 1);
                val = IMAADPCM.decodeADPCM((byte)(buffer[0] & 0xf), ref state);
                target.AddSample_16bit(val);
                val = IMAADPCM.decodeADPCM((byte)((buffer[0] >> 4) & 0xf), ref state);
                target.AddSample_16bit(val);
            }

            data.Close();
            target.Close();
        }
Пример #4
0
        public static bool replaceSample(int sampleIndex, string path)
        {
            long offset = IVAUDSingle.WIoffset[sampleIndex] + IVAUDSingle.headerSize;

            byte[] dataBefore = new byte[offset - IVAUDSingle.headerSize];
            byte[] dataAfter  = new byte[IVAUD.file.Length - (offset + IVAUDSingle.WInumSamplesInBytes_computed[sampleIndex])];

            //Get data between header and replaced sample
            IVAUD.file.Seek(IVAUDSingle.headerSize, SeekOrigin.Begin);
            IVAUD.file.Read(dataBefore, 0, dataBefore.Length);

            //Get data between replaced sample and eof
            IVAUD.file.Seek(offset + IVAUDSingle.WInumSamplesInBytes_computed[sampleIndex], SeekOrigin.Begin);
            IVAUD.file.Read(dataAfter, 0, dataAfter.Length);

            //Close file
            IVAUD.close();

            //Open WAV file and encode it
            WAVFile wav = new WAVFile();

            wav.Open(path, WAVFile.WAVFileMode.READ);

            MemoryStream ms = new MemoryStream();

            IMAADPCM.ADPCMState state = new IMAADPCM.ADPCMState();
            //byte enc1, enc2;

            byte[] bytes     = new byte[2];
            int    loopValue = ((wav.DataSizeBytes - 8) / wav.BytesPerSample);

            /*Debug.WriteLine((((wav.DataSizeBytes - 8) / wav.BytesPerSample)) / 2);
             * Debug.WriteLine(wav.NumSamples / 2);
             * Debug.WriteLine((((wav.DataSizeBytes - 8) / wav.BytesPerSample)));
             * Debug.WriteLine(wav.NumSamples);*/

            //for (long i = 0; i < wav.NumSamples / 2; i++) {
            for (long i = 0; i < loopValue / 2; i++)
            {
                bytes[0] = IMAADPCM.encodeADPCM(wav.GetNextSampleAs16Bit(), ref state);
                bytes[1] = IMAADPCM.encodeADPCM(wav.GetNextSampleAs16Bit(), ref state);
                ms.Write(BitConverter.GetBytes(Convert.ToInt32(Utils.binaryString(bytes[1], 4) + Utils.binaryString(bytes[0], 4), 2)), 0, 1);
            }

            long originalOffset = offset + IVAUDSingle.WInumSamplesInBytes_computed[sampleIndex];

            //Change header values
            IVAUDSingle.WInumSamplesInBytes[sampleIndex]          = (int)ms.Length;
            IVAUDSingle.WInumSamplesInBytes_computed[sampleIndex] = Utils.getPaddedSize(IVAUDSingle.WInumSamplesInBytes[sampleIndex]);
            IVAUDSingle.WInumSamples16Bit[sampleIndex]            = (int)(ms.Length * 2);
            IVAUDSingle.WIsamplerate[sampleIndex] = (ushort)wav.SampleRateHz;
            if (IVAUDSingle.WIHsize[sampleIndex] > 32)
            {
                IVAUDSingle.WInumSamples16Bit2[sampleIndex] = (uint)(ms.Length * 2);
            }

            //Change later offsets
            long newOffset    = offset + IVAUDSingle.WInumSamplesInBytes_computed[sampleIndex];
            long offsetChange = newOffset - originalOffset;

            for (int i = 0; i < IVAUDSingle.WIHoffset.Count; i++)
            {
                if ((IVAUDSingle.WIoffset[i] + IVAUDSingle.headerSize) > offset)
                {
                    IVAUDSingle.WIoffset[i] += offsetChange;
                }
            }

            wav.Close();

            //Get WAV data
            byte[] dataWAV = new byte[ms.Length];
            ms.Seek(0, SeekOrigin.Begin);
            ms.Read(dataWAV, 0, (int)ms.Length);
            ms.Close();

            //Write header
            FileStream fs = new FileStream(Environment.GetEnvironmentVariable("TEMP") + "\\IVATB\\Current" + Utils.sessionID + ".tmp", FileMode.Open, FileAccess.ReadWrite);

            fs.Seek(0, SeekOrigin.Begin);
            if (!IVAUDSingle.write(fs))
            {
                return(false);
            }

            //Write before-data
            fs.Seek(IVAUDSingle.headerSize, SeekOrigin.Begin);
            fs.Write(dataBefore, 0, dataBefore.Length);

            //Write sample
            fs.Seek(offset, SeekOrigin.Begin);
            fs.Write(dataWAV, 0, dataWAV.Length);

            //Write after-data
            fs.Seek(offset + IVAUDSingle.WInumSamplesInBytes_computed[sampleIndex], SeekOrigin.Begin);
            fs.Write(dataAfter, 0, dataAfter.Length);

            //Fix file length if needed
            if (offsetChange < 0)
            {
                fs.SetLength(fs.Length + offsetChange);
            }

            fs.Close();

            //Replace the file
            //IVAUD.close();
            //File.Copy(Environment.GetEnvironmentVariable("TEMP") + "\\IVATB\\Replace" + Utils.sessionID + ".tmp", Environment.GetEnvironmentVariable("TEMP") + "\\IVATB\\Current" + Utils.sessionID + ".tmp", true);

            //Reload the file
            IVAUD.load(Environment.GetEnvironmentVariable("TEMP") + "\\IVATB\\Current" + Utils.sessionID + ".tmp");

            return(true);
        }
Пример #5
0
	public static byte[] GetADPCMWAVData(AudioClip clip, int maxsamples)
	{
		Debug.Log ("maxsamples="+maxsamples);
		int headersize = 60;
		float[] fdata = new float[clip.samples*clip.channels];
		int rawdatasize = (clip.samples*clip.channels)/2;
		if (rawdatasize>maxsamples/2)
			rawdatasize = maxsamples/2;
		clip.GetData(fdata, 0);

		int 	SampleRate 			= 22050;
		int 	ByteRate 			= 11100;

		int blockalign = 1024; //taille d'un header ADPCM complet
		int blockdata = blockalign-4;//252;
		int blocks = rawdatasize/blockdata;
		int datasize = blocks * blockalign;
		//IMAADPCM.ADPCMState[] states = new IMAADPCM.ADPCMState[blocks+1];
		//for (int i=0;i<blocks;++i)
		//{
		//	states[i] = new IMAADPCM.ADPCMState();
		//}
		//byte[] data = EncodeToADPCM(record, states);
		
		
		
		
		uint totalsize = (uint)(datasize+headersize);
		Debug.Log ("total size = " + totalsize);
		byte[] total = new byte[totalsize];
		
		byte[] b = null;
		
		
		b = System.Text.Encoding.UTF8.GetBytes("RIFF");
		b.CopyTo(total, 0);
		
		b = System.BitConverter.GetBytes(total.Length-8);
		b.CopyTo(total, 4);
		
		b = System.Text.Encoding.UTF8.GetBytes("WAVE");
		b.CopyTo(total, 8);
		
		//fmt CHUNK =======================
		b = System.Text.Encoding.UTF8.GetBytes("fmt ");
		b.CopyTo(total, 12);
		
		//4
		b = System.BitConverter.GetBytes(20); //taille du block fmt
		b.CopyTo(total, 16);
		
		//2
		b = System.BitConverter.GetBytes((ushort)17); //FORMAT 0x11=INA ADPCM (17) OK !!!
		//b = System.BitConverter.GetBytes((ushort)57); 
		//b = System.BitConverter.GetBytes((ushort)259); //FORMAT 0x11=INA ADPCM (17)
		b.CopyTo(total, 20);
		
		b = System.BitConverter.GetBytes((ushort)1); //CHANNELS OK !!!
		b.CopyTo(total, 22);
		
		b = System.BitConverter.GetBytes((uint)SampleRate); //SR
		b.CopyTo(total, 24);
		
		//byte rate = SR/2 + overhead
		//b = System.BitConverter.GetBytes((uint)(22050*1/2)); //byte rate //SR*channels*2
		b = System.BitConverter.GetBytes((uint)(ByteRate)); //byte rate //SR*channels*2
		b.CopyTo(total, 28);
		
		//block align
		b = System.BitConverter.GetBytes((ushort)blockalign); //2 : 16 bits mono 512 dans le fichier Audacity
		b.CopyTo(total, 32);
		
		b = System.BitConverter.GetBytes((ushort)4); //bits per samples, 4
		b.CopyTo(total, 34);
		
		//taille de la zone extended
		b = System.BitConverter.GetBytes((ushort)2); 
		b.CopyTo(total, 36);
		
		int samplesperblock = (blockalign-4)*2+1;
		b = System.BitConverter.GetBytes((ushort)samplesperblock);  //nombre de samples par bloc : (512-4)*2+1
		b.CopyTo(total, 38);
		
		
		
		//FACT CHUNK
		b = System.Text.Encoding.UTF8.GetBytes("fact");
		b.CopyTo(total, 40);
		
		b = System.BitConverter.GetBytes(4); //taille du block fact : 4 octets
		b.CopyTo(total, 44);
		
		b = System.BitConverter.GetBytes((uint)datasize*2);  //nombre de samples au total
		b.CopyTo(total, 48);
		
		
		//DATA CHUNK
		b = System.Text.Encoding.UTF8.GetBytes("data");
		b.CopyTo(total, 52);
		
		b = System.BitConverter.GetBytes((uint)totalsize);
		b.CopyTo(total, 56);
		
		
		//on commence à header size
		
		
		//compression IMA ADPCM
		
		
		//Debug.Log("Samples per blocks = " + samplesperblock);
		
		IMAADPCM.ADPCMState state = new IMAADPCM.ADPCMState();
		state.valprev = 0;
		state.index = 0;
		int count = (blocks-1) * samplesperblock;
		int dest = 0;
		bool first = true;
		
		
		for (int s=0;s<count;++s) //pour tous les samples en entrée
		{
			short input = (short)(fdata[s]*32768f);
			int m = s%samplesperblock;
			byte adpcm = IMAADPCM.encodeADPCM(input, ref state);
			
			if (m == 0)
			{
				//premier sample du bloc
				//il faut écrire un header mais ne pas émettre normalement le sample
				//s+=1;
				//byte adpcm = IMAADPCM.encodeADPCM(input, ref state);
				//Debug.Log ("write adpcm header at dest " + dest + " first="+first + " vals " + state.valprev + " " + state.index);
				b = System.BitConverter.GetBytes(state.valprev);
				total[headersize+dest+0] = b[0];
				total[headersize+dest+1] = b[1];
				total[headersize+dest+2] = state.index;
				total[headersize+dest+3] = 0;//adpcm; //hack pour avoir quand même le nible dans le header NON ! semble poser un problème sur la box
				
				dest += 4;
				first = true;
				//byte adpcm = IMAADPCM.encodeADPCM(input, ref state);
			}
			else
			{
				//byte adpcm = IMAADPCM.encodeADPCM(input, ref state);
				//cas normal, on écrit l'échantillon
				//byte adpcm = IMAADPCM.encodeADPCM(input, ref state);
				if (first)
				{
					total[headersize+dest] = (byte)(adpcm);
					first = false;
				}
				else
				{
					total[headersize+dest] += (byte)(adpcm*16);
					dest ++;
					first = true;
				}
			}
		}
		
		return total;
	}
Пример #6
0
	//=============================================
	//=============================================
	public static AudioClip SetADPCMData(byte[] bytes)
	{
		
		//lire le header 
		//reconstituer le buffer ADPCM
		//décoder
		int headersize = 60; //hardcoded for ADPCM app encoded
		if (bytes[0] == 'R' && bytes[1] == 'I' && bytes[2] == 'F' && bytes[3] == 'F')
		{
			Debug.Log ("ok, this is a RIFF file");
			
			//48
			ushort format = System.BitConverter.ToUInt16(bytes, 20); //FORMAT
			if (format != 17)
			{
				Debug.Log ("ERROR, bad format : " + format + " - should be IMA ADPCM");
				return null;
			}
			uint totalsamples = System.BitConverter.ToUInt32(bytes, 48);
			ushort blockalign = System.BitConverter.ToUInt16(bytes, 32); //alignement de bloc en octets
			uint SampleRate = System.BitConverter.ToUInt32(bytes, 24);
			Debug.Log ("total samples=" + totalsamples);
			//totalsamples = (uint)(bytes.Length-60); //test
			Debug.Log ("block align=" + blockalign);
			
			int datasize = bytes.Length-headersize;
			int blocks = datasize/blockalign;
			int estimated_samples = blocks*((blockalign-4)*2+1);
			Debug.Log ("estimated samples=" + estimated_samples);
			if (totalsamples >= estimated_samples)
			{
				Debug.Log ("bad totalsamples!");
				totalsamples = (uint)estimated_samples;
			}
			//return null;
			AudioClip dest = AudioClip.Create("adpcm_downloaded", (int)totalsamples, 1, (int)SampleRate, false, false);
			float[] data = new float[totalsamples];
			for (int k=0;k<totalsamples;++k)
				data[k] = 0f;
			IMAADPCM.ADPCMState state = new IMAADPCM.ADPCMState(); 
			state.valprev = 0;
			state.index = 0;
			int j = 0; //destination index
			int i = 0; //source index
			while (i<totalsamples/2)
			{
				if (i%blockalign == 0)
				{
					//Debug.Log ("ADPCM BLOCK (i=" + i + ") = " + bytes[headersize+i+0] + " " + bytes[headersize+i+1] + " " + bytes[headersize+i+2] + " " + bytes[headersize+i+3]);
					//on est sur le premier byte du header
					//Debug.Log ("Current ADPCM state = " + state.valprev + " " + state.index);
					//cas particulier : 4 octets header, on met à jour le state et on écrit un échantillon
					//bytes[headersize+i+1] = 0;
					byte[] b = new byte[2];
					b[0] = bytes[headersize+i+0];
					b[1] = bytes[headersize+i+1];
					short sample = System.BitConverter.ToInt16(b, 0); //sample de référence
					//Debug.Log ("sample=" + sample);
					byte index = bytes[headersize+i+2]; //index de référence
					//le 4e octet ne contient rien de significatif
					//data[j] = ((float)state.valprev)/32767f;
					//short i1 = IMAADPCM.decodeADPCM(bytes[headersize+i+3], ref state); //hack
					//data[j] = (float)(i1)/32768f;
					//if (i>0)
					//	IMAADPCM.encodeADPCM(sample, ref state);
					//if (i>0)
					//{
					//ADPCM state update
					state.valprev = sample;
					state.index = index;
					data[j] = (float)(sample)/32768f;
					//}
					//IMAADPCM.encodeADPCM(sample, ref state); //post encode 
					//IMAADPCM.encodeADPCM(sample, ref state); //post encode 
					
					//byte b2 = (byte)(state.valprev&15);
					//short i1 = IMAADPCM.decodeADPCM(b2, ref state);
					//Debug.Log ("predicted=" + i1 + " sample=" + sample);
					//byte adpcm = IMAADPCM.encodeADPCM(sample, ref state);
					//state.valprev = System.BitConverter.ToInt16(bytes, headersize+i);
					//
					//sample = i1;
					
					//data[j] = ((float)state.valprev)/32768f;
					//data[j] = (float)((double)sample)/32768f;
					//data[j] = (float)(sample)/32768f;
					//data[j] = 0;
					/*if (j>0)
					{
						Debug.Log ("previous="+data[j-1] + " current=" + data[j]);
					}*/
					//j++;
					
					//state.valprev = System.BitConverter.ToInt16(b, 0);
					//state.index = bytes[headersize+i+2];
					//Debug.Log ("Corrected ADPCM state = " + state.valprev + " " + state.index);
					//i+=3;
					//if (j>10)
					j++;
					i+=4; //on avance de 4 pour passer le header
				}
				else
				{
					//cas normal
					byte b = bytes[headersize+i];
					byte b1 = (byte)((b/16)&15); //nibble 1
					byte b2 = (byte)(b&15); //nibble 2
					short i1 = IMAADPCM.decodeADPCM(b2, ref state);
					short i2 = IMAADPCM.decodeADPCM(b1, ref state);
					data[j] = ((float)i1)/32768f;
					j++;
					data[j] = ((float)i2)/32768f;
					j++;
					i++; //next input byte
				}
			}
			
			//patch 
			
			/*for (int k=0;k<totalsamples;++k)
			{
				if (k>0 && k%(blockalign*2) == 0)
				{
					Debug.Log ("before patch " + data[k-1] + " " + data[k] + " " + data[k+1]);
					//data[k] = (data[k-1]+data[k+1])/2f;
					//Debug.Log ("after patch " + data[k-1] + " " + data[k] + " " + data[k+1]);
				}
			}*/
			
			/*
			FileStream fs = new FileStream("adpcm.raw", FileMode.Create);
			for (int u=0;u<data.Length;++u)
			{
				byte[] b = System.BitConverter.GetBytes(data[u]); 
				fs.Write(b, 0, 4);
			}
			*/
			//
			//fs.Close();
			//rampin and out
			
			/*for (int u=0;u<2000;++u)
			{
				float k = (float)u/2000f;
				data[u] *= k;
				data[totalsamples-1-u] *= k;
			}
			*/
			dest.SetData(data, 0);
			return dest;
		}
		else
		{
			Debug.Log ("ERROR, this is not a RIFF file");
		}
		
		return null;
	}
Пример #7
0
        static void Main(string[] args)
        {
            //Debug test
            //args = (@"E:\Mijn documenten\Visual Studio 2010\ADPCMEncoder\~24000HZTEST.wav|test").Split(Convert.ToChar("|"));
            //args = (@"E:\Mijn documenten\Visual Studio 2010\ADPCMEncoder\TestFiles\LoadingSNOW.wav|test").Split(Convert.ToChar("|"));

            //Print header
            Console.WriteLine("=================");
            Console.WriteLine("IMA ADPCM Encoder");
            Console.WriteLine(" by Flitskikker");
            Console.WriteLine("=================");
            Console.WriteLine("");

            //Check args
            if (args.Length == 0)
            {
                //No args
                Console.WriteLine("ERROR: No command line arguments passed. Press any key to exit...");
                Console.ReadLine();
                Environment.Exit(1);
            }

            //Check file
            if (!File.Exists(args[0]))
            {
                //File not found
                Console.WriteLine("ERROR: File \"" + args[0] + "\" not found. Press any key to exit...");
                Console.ReadLine();
                Environment.Exit(2);
            }

            //Print file
            Console.WriteLine("File: " + args[0]);
            Console.WriteLine("");

            //Load file
            WAVFile wav = new WAVFile();

            wav.Open(args[0], WAVFile.WAVFileMode.READ);

            //Show WAV info
            Console.WriteLine("WAV Info:");
            Console.WriteLine("\tBits per sample:\t" + wav.BitsPerSample.ToString() + " bits");
            Console.WriteLine("\tBytes per sample:\t" + wav.BytesPerSample.ToString());
            Console.WriteLine("\tBytes per second:\t" + wav.BytesPerSec.ToString());
            Console.WriteLine("\tData size:\t\t" + wav.DataSizeBytes.ToString() + " bytes");
            Console.WriteLine("\tDuration:\t\t" + Math.Round(Convert.ToDecimal((double)wav.NumSamples / (double)wav.SampleRateHz), 2).ToString() + " seconds (" + Utils.getDurationString(wav.NumSamples, wav.SampleRateHz) + ")");
            Console.WriteLine("\tEncoding type:\t\t" + wav.EncodingType.ToString());
            Console.WriteLine("\tFile size:\t\t" + wav.FileSizeBytes.ToString() + " bytes");
            Console.WriteLine("\t# of channels:\t\t" + wav.NumChannels.ToString());
            Console.WriteLine("\t# of samples:\t\t" + wav.NumSamples.ToString());
            Console.WriteLine("\tRIFF type:\t\t" + wav.RIFFTypeString);
            Console.WriteLine("\tSample Rate:\t\t" + wav.SampleRateHz.ToString() + " Hz");
            Console.WriteLine("\tWAV header:\t\t" + wav.WAVHeaderString);
            Console.WriteLine("");

            //Check bits
            if (wav.BitsPerSample != 16)
            {
                //Not 16 bits
                Console.WriteLine("ERROR: WAV should have 16 bits per sample. Press any key to exit...");
                Console.ReadLine();
                Environment.Exit(1);
            }

            //Check bytes per sample
            if (wav.BytesPerSample / wav.NumChannels != 2)
            {
                //Not 2 bytes
                Console.WriteLine("ERROR: WAV should have (wav.NumChannels * 2) bytes per sample. Press any key to exit...");
                Console.ReadLine();
                Environment.Exit(1);
            }

            //Print message
            Console.WriteLine("Ready to go! Press any key when ready...");

            //Wait for input
            Console.ReadLine();

            if (wav.NumChannels > 1)
            {
                //Split channels
                Console.WriteLine("");
                Console.WriteLine("Saving separate channels...");
                Console.WriteLine("");

                List <WAVFile> wavs = new List <WAVFile>();

                for (int c = 0; c < wav.NumChannels; c++)
                {
                    wavs.Add(new WAVFile());
                    wavs[c].Create(Path.GetDirectoryName(args[0]) + "\\" + Path.GetFileNameWithoutExtension(args[0]) + "_" + (c + 1).ToString() + ".wav", false, wav.SampleRateHz, wav.BitsPerSample, true);
                }

                int numSamplesCorrected = ((wav.DataSizeBytes - 8) / wav.BytesPerSample);

                //for (long i = 0; i < wav.NumSamples / wav.NumChannels; i++) {
                for (long i = 0; i < numSamplesCorrected; i++)
                {
                    for (int c = 0; c < wav.NumChannels; c++)
                    {
                        wavs[c].AddSample_16bit(wav.GetNextSampleAs16Bit());
                    }
                }

                for (int c = 0; c < wav.NumChannels; c++)
                {
                    wavs[c].Close();
                }
            }

            //Encode
            Console.WriteLine("");
            Console.WriteLine("Encoding file(s)...");
            Console.WriteLine("");

            IMAADPCM.ADPCMState state = new IMAADPCM.ADPCMState();
            WAVFile             cwav  = new WAVFile();
            int nc = wav.NumChannels;

            for (int c = 0; c < wav.NumChannels; c++)
            {
                Console.WriteLine("Encoding file: " + Path.GetDirectoryName(args[0]) + "\\" + Path.GetFileNameWithoutExtension(args[0]) + "_" + (c + 1).ToString() + ".bin");

                MemoryStream ms = new MemoryStream();
                cwav = new WAVFile();

                // Open splitted WAV
                if (wav.NumChannels > 1)
                {
                    cwav.Open(Path.GetDirectoryName(args[0]) + "\\" + Path.GetFileNameWithoutExtension(args[0]) + "_" + (c + 1).ToString() + ".wav", WAVFile.WAVFileMode.READ_WRITE);
                }
                else
                {
                    cwav = wav;
                    //wav.Close();
                    //cwav.Open(args[0], WAVFile.WAVFileMode.READ_WRITE);
                }

                byte[] bytes     = new byte[2];
                int    loopValue = ((cwav.DataSizeBytes - 8) / cwav.BytesPerSample);

                //Actual encode
                for (long i = 0; i < loopValue / 2; i++)
                {
                    bytes[0] = IMAADPCM.encodeADPCM(cwav.GetNextSampleAs16Bit(), ref state);
                    bytes[1] = IMAADPCM.encodeADPCM(cwav.GetNextSampleAs16Bit(), ref state);
                    ms.Write(BitConverter.GetBytes(Convert.ToInt32(Utils.binaryString(bytes[1], 4) + Utils.binaryString(bytes[0], 4), 2)), 0, 1);
                }

                //Get WAV data
                byte[] dataWAV = new byte[ms.Length];
                ms.Seek(0, SeekOrigin.Begin);
                ms.Read(dataWAV, 0, (int)ms.Length);
                ms.Close();

                //Create file
                FileStream fs = new FileStream(Path.GetDirectoryName(args[0]) + "\\" + Path.GetFileNameWithoutExtension(args[0]) + "_" + (c + 1).ToString() + ".bin", FileMode.Create, FileAccess.ReadWrite);

                //Write sample
                fs.Seek(0, SeekOrigin.Begin);
                fs.Write(dataWAV, 0, dataWAV.Length);

                //Close
                cwav.Close();
                ms.Close();
                fs.Close();

                if (nc == 1)
                {
                    break;
                }
            }

            //Close WAV file
            wav.Close();

            //Print message
            Console.WriteLine("");
            Console.WriteLine("Done! Press any key to exit...");

            //Wait for input
            Console.ReadLine();

            //Exit
            Environment.Exit(0);
        }