/// <summary> /// Create a WAV structure using PCM audio format /// </summary> /// <param name="numChannels">Number of channels</param> /// <param name="sampleRate">Sample rate</param> /// <param name="bitsPerSample">Bits per sample</param> /// <param name="data">Audio data</param> /// <returns>New wav structure</returns> public static sWAV Create_WAV(ushort numChannels, uint sampleRate, ushort bitsPerSample, byte[] data) { sWAV wav = new sWAV(); wav.chunkID = new char[] { 'R', 'I', 'F', 'F' }; wav.format = new char[] { 'W', 'A', 'V', 'E' }; wav.wave.fmt.chunkID = new char[] { 'f', 'm', 't', '\x20' }; wav.wave.fmt.chunkSize = 16; wav.wave.fmt.audioFormat = WaveFormat.WAVE_FORMAT_PCM; wav.wave.fmt.numChannels = numChannels; wav.wave.fmt.sampleRate = sampleRate; wav.wave.fmt.bitsPerSample = bitsPerSample; wav.wave.fmt.byteRate = wav.wave.fmt.sampleRate * wav.wave.fmt.bitsPerSample * wav.wave.fmt.numChannels / 8; wav.wave.fmt.blockAlign = (ushort)(wav.wave.fmt.numChannels * wav.wave.fmt.bitsPerSample / (ushort)(8)); wav.wave.data.chunkID = new char[] { 'd', 'a', 't', 'a' }; wav.wave.data.chunkSize = (uint)data.Length; wav.wave.data.data = new byte[data.Length]; wav.wave.data.data = data; wav.chunkSize = (uint)(0x24 + data.Length); return(wav); }
/// <summary> /// Read a wave file and return its structure. /// </summary> /// <param name="filein">File to read</param> /// <returns>Structure of the wave file</returns> public static sWAV Read(string filein) { sWAV wav = new sWAV(); BinaryReader br = new BinaryReader(File.OpenRead(filein)); // RIFF header wav.chunkID = br.ReadChars(4); wav.chunkSize = br.ReadUInt32(); wav.format = br.ReadChars(4); if (new String(wav.chunkID) != "RIFF" || new String(wav.format) != "WAVE") { throw new NotSupportedException(); } // fmt sub-chunk wav.wave.fmt.chunkID = br.ReadChars(4); wav.wave.fmt.chunkSize = br.ReadUInt32(); wav.wave.fmt.audioFormat = (WaveFormat)br.ReadUInt16(); wav.wave.fmt.numChannels = br.ReadUInt16(); wav.wave.fmt.sampleRate = br.ReadUInt32(); wav.wave.fmt.byteRate = br.ReadUInt32(); wav.wave.fmt.blockAlign = br.ReadUInt16(); wav.wave.fmt.bitsPerSample = br.ReadUInt16(); br.BaseStream.Position = 0x14 + wav.wave.fmt.chunkSize; String dataID = new String(br.ReadChars(4)); while (dataID != "data") { br.BaseStream.Position += br.ReadUInt32() + 0x04; dataID = new String(br.ReadChars(4)); } // data sub-chunk br.BaseStream.Position -= 4; wav.wave.data.chunkID = br.ReadChars(4); wav.wave.data.chunkSize = br.ReadUInt32(); wav.wave.data.data = br.ReadBytes((int)wav.wave.data.chunkSize - 0x08); br.Close(); // Convert the data to PCM16 if (wav.wave.fmt.audioFormat != WaveFormat.WAVE_FORMAT_PCM) { throw new NotSupportedException(); } if (wav.wave.fmt.audioFormat == WaveFormat.WAVE_FORMAT_PCM && wav.wave.fmt.bitsPerSample == 0x08) // PCM8 { wav.wave.fmt.bitsPerSample = 0x10; wav.wave.fmt.blockAlign = (ushort)(wav.wave.fmt.numChannels * wav.wave.fmt.bitsPerSample / (ushort)(8)); wav.wave.fmt.byteRate = wav.wave.fmt.sampleRate * wav.wave.fmt.bitsPerSample * wav.wave.fmt.numChannels / 8; wav.wave.data.data = PCM.PCM8UnsignedToPCM16(wav.wave.data.data); } return(wav); }
public static sWAV ConvertToWAV(sSWAV swav, bool loop) { sWAV wav = new sWAV(); if (swav.data.info.nWaveType == 0) // 8 Bits per sample, PCM-8 { swav.data.data = PCM.PCM8SignedToPCM16(swav.data.data); if (loop) { Byte[] data = new Byte[(int)swav.data.info.nNonLoopLen]; Array.Copy(swav.data.data, swav.data.info.nLoopOffset, data, 0, data.Length); swav.data.data = data; } wav = WAV.Create_WAV(1, swav.data.info.nSampleRate, 16, swav.data.data); } else if (swav.data.info.nWaveType == 1) // 16 Bits per sample, PCM-16 { if (loop) // NO TESTED { Byte[] data = new Byte[(int)swav.data.info.nNonLoopLen]; Array.Copy(swav.data.data, swav.data.info.nLoopOffset, data, 0, data.Length); swav.data.data = data; } wav = WAV.Create_WAV(1, swav.data.info.nSampleRate, 16, swav.data.data); } else if (swav.data.info.nWaveType >= 2) // 4 Bits per sample, IMA-ADPCM { swav.data.data = Compression_ADPCM.Decompress( swav.data.data, BitConverter.ToUInt16(swav.data.data, 0), BitConverter.ToUInt16(swav.data.data, 2)); if (loop) { Byte[] data = new Byte[swav.data.data.Length - ((int)swav.data.info.nLoopOffset * 2)]; Array.Copy(swav.data.data, swav.data.info.nLoopOffset * 2, data, 0, data.Length); swav.data.data = data; } wav = WAV.Create_WAV(1, swav.data.info.nSampleRate, 16, swav.data.data); } return(wav); }
public static sSWAV ConvertToSWAV(sWAV wav, int waveType, int volume = 150) { sSWAV swav = new sSWAV(); swav.header.type = "SWAV".ToCharArray(); swav.header.magic = 0x0100FEFF; swav.header.nSize = 0x10; swav.header.nBlock = 0x01; swav.data.type = "DATA".ToCharArray(); swav.data.info.nWaveType = (byte)waveType; swav.data.info.bLoop = 1; swav.data.info.nSampleRate = (ushort)wav.wave.fmt.sampleRate; swav.data.info.nTime = (ushort)(1.6756991e+7 / wav.wave.fmt.sampleRate); swav.data.info.nLoopOffset = 0x01; if (wav.wave.fmt.numChannels > 1) { wav.wave.data.data = WAV.ConvertToMono(wav.wave.data.data, wav.wave.fmt.numChannels, wav.wave.fmt.bitsPerSample); } //wav.wave.data.data = ChangeVolume(wav.wave.data.data, volume, wav.wave.fmt.bitsPerSample); if (waveType == 0) { swav.data.data = PCM.PCM16ToPCM8(wav.wave.data.data); } else if (waveType == 2) { List <byte> temp = new List <byte>(); temp.AddRange(new Byte[] { 0x00, 0x00, 0x00, 0x00 }); temp.AddRange(Compression_ADPCM.Compress(wav.wave.data.data)); swav.data.data = temp.ToArray(); } else { swav.data.data = wav.wave.data.data; } swav.data.nSize = (uint)swav.data.data.Length + 0x0A; swav.data.info.nNonLoopLen = (uint)swav.data.data.Length; swav.header.nFileSize = swav.data.nSize + swav.header.nSize; return(swav); }
/// <summary> /// Write a WAV structure to a WAV file /// </summary> /// <param name="wav">WAV structu to write</param> /// <param name="fileout">File where the structure will be written</param> public static void Write(sWAV wav, string fileout) { FileStream fs = null; BinaryWriter bw = null; try { fs = new FileStream(fileout, System.IO.FileMode.Create); bw = new BinaryWriter(fs); bw.Write(Encoding.ASCII.GetBytes(wav.chunkID)); bw.Write(wav.chunkSize); bw.Write(Encoding.ASCII.GetBytes(wav.format)); bw.Write(Encoding.ASCII.GetBytes(wav.wave.fmt.chunkID)); bw.Write(wav.wave.fmt.chunkSize); bw.Write(Convert.ToUInt16(wav.wave.fmt.audioFormat)); bw.Write(wav.wave.fmt.numChannels); bw.Write(wav.wave.fmt.sampleRate); bw.Write(wav.wave.fmt.byteRate); bw.Write(wav.wave.fmt.blockAlign); bw.Write(wav.wave.fmt.bitsPerSample); bw.Write(Encoding.ASCII.GetBytes(wav.wave.data.chunkID)); bw.Write(wav.wave.data.chunkSize); bw.Write(wav.wave.data.data); bw.Flush(); } catch (Exception ex) { Console.WriteLine(ex.Message.ToString()); } finally { if (fs != null) { fs.Close(); } if (bw != null) { bw.Close(); } } }
/// <summary> /// Convert a WAV structure to a STRM structure /// </summary> /// <param name="wav">WAV structure to convert</param> /// <returns>STRM structure converted</returns> public static sSTRM ConvertToSTRM(sWAV wav, int waveType, int blockSize = 0x200) { if (blockSize <= 0) { blockSize = 0x200; } if (waveType == 2) { blockSize -= 4; // compression info blockSize *= 4; // 4-bit } else if (waveType == 0) { blockSize *= 2; // 8-bit } sSTRM strm = new sSTRM(); strm.cabecera.id = "STRM".ToArray(); strm.cabecera.constant = 0x0100FEFF; strm.cabecera.headerSize = 0x10; strm.cabecera.nBlocks = 0x02; strm.head.id = "HEAD".ToArray(); strm.head.size = 0x50; strm.head.waveType = (byte)waveType; strm.head.loop = 1; strm.head.channels = wav.wave.fmt.numChannels; strm.head.sampleRate = (ushort)wav.wave.fmt.sampleRate; strm.head.time = (ushort)(1.0 / strm.head.sampleRate * 1.6756991e+7 / 32); strm.head.loopOffset = 0x00; strm.head.dataOffset = 0x68; strm.head.reserved = new Byte[32]; strm.data.id = "DATA".ToArray(); if (wav.wave.fmt.numChannels == 2) { strm.data.leftChannel = DivideChannels(wav.wave.data.data, true); strm.data.rightChannel = DivideChannels(wav.wave.data.data, false); byte[][] leftBlock = CreateBlocks(strm.data.leftChannel, blockSize, waveType); byte[][] rigthBlock = CreateBlocks(strm.data.rightChannel, blockSize, waveType); strm.data.data = MergeBlocks(leftBlock, rigthBlock); strm.head.blockLen = (uint)leftBlock[0].Length; strm.head.lastBlocklen = (uint)leftBlock[leftBlock.Length - 1].Length; strm.head.nBlocks = (uint)leftBlock.Length; } else { byte[][] blocks = CreateBlocks(wav.wave.data.data, blockSize, waveType); List <byte> data = new List <byte>(); for (int i = 0; i < blocks.Length; i++) { data.AddRange(blocks[i]); } strm.data.data = data.ToArray(); strm.head.blockLen = (uint)blocks[0].Length; strm.head.lastBlocklen = (uint)blocks[blocks.Length - 1].Length; strm.head.nBlocks = (uint)blocks.Length; } if (waveType == 2) { strm.head.blockSample = (strm.head.blockLen - 4) * 2; strm.head.lastBlockSample = (strm.head.lastBlocklen - 4) * 2; } else if (waveType == 1) { strm.head.blockSample = strm.head.blockLen / 2; strm.head.lastBlockSample = strm.head.lastBlocklen / 2; } else if (waveType == 0) { strm.head.blockSample = strm.head.blockLen; strm.head.lastBlockSample = strm.head.lastBlocklen; } strm.head.nSamples = (strm.head.nBlocks - 1) * strm.head.blockSample + strm.head.lastBlockSample; strm.data.size = (uint)strm.data.data.Length + 0x08; strm.cabecera.fileSize = strm.data.size + strm.head.size + strm.cabecera.headerSize; return(strm); }
/// <summary> /// Convert a STRM structure to a WAV structure /// </summary> /// <param name="strm">STRM structure to convert</param> /// <param name="loop">If true, the new WAV data will start in the loop offset</param> /// <returns>WAV structure converted</returns> public static sWAV ConvertToWAV(sSTRM strm, bool loop) { sWAV wav = new sWAV(); // Get the audio data if (strm.head.channels == 2) { // Get both channels and convert it to PCM-16 strm.data.leftChannel = DivideChannels(strm.data.data, strm.head.nBlocks, strm.head.blockLen, strm.head.lastBlocklen, true, strm.head.waveType); strm.data.rightChannel = DivideChannels(strm.data.data, strm.head.nBlocks, strm.head.blockLen, strm.head.lastBlocklen, false, strm.head.waveType); Array.Clear(strm.data.data, 0, strm.data.data.Length); if (loop && strm.head.waveType == 0) // 8 bits per sample { strm.data.data = MergeChannels(strm.data.leftChannel, strm.data.rightChannel, (int)strm.head.loopOffset); } else if (loop && strm.head.waveType == 2) // 4 bits per sample { strm.data.data = MergeChannels(strm.data.leftChannel, strm.data.rightChannel, (int)strm.head.loopOffset * 2); } else if (loop && strm.head.waveType == 1) // 16 bits per sample (NO TESTED) { strm.data.data = MergeChannels(strm.data.leftChannel, strm.data.rightChannel, (int)strm.head.loopOffset); } else // No loop { strm.data.data = MergeChannels(strm.data.leftChannel, strm.data.rightChannel); } } else if (strm.head.channels == 1) { // Get the channel and convert it to PCM-16 strm.data.data = MonoChannel(strm.data.data, strm.head.nBlocks, strm.head.blockLen, strm.head.lastBlocklen, strm.head.waveType); if (strm.head.waveType == 0 && loop) // 8 bits per sample { Byte[] data = new Byte[strm.data.data.Length - (int)strm.head.loopOffset]; Array.Copy(strm.data.data, strm.head.loopOffset, data, 0, data.Length); strm.data.data = data; } else if (loop && strm.head.waveType == 2) // 4 bits per sample { Byte[] data = new Byte[strm.data.data.Length - ((int)strm.head.loopOffset * 2)]; Array.Copy(strm.data.data, strm.head.loopOffset * 2, data, 0, data.Length); strm.data.data = data; } else if (loop && strm.head.waveType == 1) // 16-bits per sample (NO TESTED) { Byte[] data = new Byte[strm.data.data.Length - (int)strm.head.loopOffset]; Array.Copy(strm.data.data, strm.head.loopOffset, data, 0, data.Length); strm.data.data = data; } } // Create the WAV structure from the STRM data wav = WAV.Create_WAV(strm.head.channels, strm.head.sampleRate, 16, strm.data.data); return(wav); }
/// <summary> /// Convert a STRM structure to a WAV structure /// </summary> /// <param name="strm">STRM structure to convert</param> /// <param name="loop">If true, the new WAV data will start in the loop offset</param> /// <returns>WAV structure converted</returns> public static sWAV ConvertToWAV(sSTRM strm, bool loop) { sWAV wav = new sWAV(); // Get the audio data if (strm.head.channels == 2) { // Get both channels and convert it to PCM-16 strm.data.leftChannel = DivideChannels(strm.data.data, strm.head.nBlocks, strm.head.blockLen, strm.head.lastBlocklen, true, strm.head.waveType); strm.data.rightChannel = DivideChannels(strm.data.data, strm.head.nBlocks, strm.head.blockLen, strm.head.lastBlocklen, false, strm.head.waveType); Array.Clear(strm.data.data, 0, strm.data.data.Length); if (loop && strm.head.waveType == 0) // 8 bits per sample strm.data.data = MergeChannels(strm.data.leftChannel, strm.data.rightChannel, (int)strm.head.loopOffset); else if (loop && strm.head.waveType == 2) // 4 bits per sample strm.data.data = MergeChannels(strm.data.leftChannel, strm.data.rightChannel, (int)strm.head.loopOffset * 2); else if (loop && strm.head.waveType == 1) // 16 bits per sample (NO TESTED) strm.data.data = MergeChannels(strm.data.leftChannel, strm.data.rightChannel, (int)strm.head.loopOffset); else // No loop strm.data.data = MergeChannels(strm.data.leftChannel, strm.data.rightChannel); } else if (strm.head.channels == 1) { // Get the channel and convert it to PCM-16 strm.data.data = MonoChannel(strm.data.data, strm.head.nBlocks, strm.head.blockLen, strm.head.lastBlocklen, strm.head.waveType); if (strm.head.waveType == 0 && loop) // 8 bits per sample { Byte[] data = new Byte[strm.data.data.Length - (int)strm.head.loopOffset]; Array.Copy(strm.data.data, strm.head.loopOffset, data, 0, data.Length); strm.data.data = data; } else if (loop && strm.head.waveType == 2) // 4 bits per sample { Byte[] data = new Byte[strm.data.data.Length - ((int)strm.head.loopOffset * 2)]; Array.Copy(strm.data.data, strm.head.loopOffset * 2, data, 0, data.Length); strm.data.data = data; } else if (loop && strm.head.waveType == 1) // 16-bits per sample (NO TESTED) { Byte[] data = new Byte[strm.data.data.Length - (int)strm.head.loopOffset]; Array.Copy(strm.data.data, strm.head.loopOffset, data, 0, data.Length); strm.data.data = data; } } // Create the WAV structure from the STRM data wav = WAV.Create_WAV(strm.head.channels, strm.head.sampleRate, 16, strm.data.data); return wav; }
/// <summary> /// Convert a WAV structure to a STRM structure /// </summary> /// <param name="wav">WAV structure to convert</param> /// <returns>STRM structure converted</returns> public static sSTRM ConvertToSTRM(sWAV wav, int waveType, int blockSize = 0x200) { if (blockSize <= 0) blockSize = 0x200; if (waveType == 2) { blockSize -= 4; // compression info blockSize *= 4; // 4-bit } else if (waveType == 0) blockSize *= 2; // 8-bit sSTRM strm = new sSTRM(); strm.cabecera.id = "STRM".ToArray(); strm.cabecera.constant = 0x0100FEFF; strm.cabecera.headerSize = 0x10; strm.cabecera.nBlocks = 0x02; strm.head.id = "HEAD".ToArray(); strm.head.size = 0x50; strm.head.waveType = (byte)waveType; strm.head.loop = 1; strm.head.channels = wav.wave.fmt.numChannels; strm.head.sampleRate = (ushort)wav.wave.fmt.sampleRate; strm.head.time = (ushort)(1.0 / strm.head.sampleRate * 1.6756991e+7 / 32); strm.head.loopOffset = 0x00; strm.head.dataOffset = 0x68; strm.head.reserved = new Byte[32]; strm.data.id = "DATA".ToArray(); if (wav.wave.fmt.numChannels == 2) { strm.data.leftChannel = DivideChannels(wav.wave.data.data, true); strm.data.rightChannel = DivideChannels(wav.wave.data.data, false); byte[][] leftBlock = CreateBlocks(strm.data.leftChannel, blockSize, waveType); byte[][] rigthBlock = CreateBlocks(strm.data.rightChannel, blockSize, waveType); strm.data.data = MergeBlocks(leftBlock, rigthBlock); strm.head.blockLen = (uint)leftBlock[0].Length; strm.head.lastBlocklen = (uint)leftBlock[leftBlock.Length - 1].Length; strm.head.nBlocks = (uint)leftBlock.Length; } else { byte[][] blocks = CreateBlocks(wav.wave.data.data, blockSize, waveType); List<byte> data = new List<byte>(); for (int i = 0; i < blocks.Length; i++) data.AddRange(blocks[i]); strm.data.data = data.ToArray(); strm.head.blockLen = (uint)blocks[0].Length; strm.head.lastBlocklen = (uint)blocks[blocks.Length - 1].Length; strm.head.nBlocks = (uint)blocks.Length; } if (waveType == 2) { strm.head.blockSample = (strm.head.blockLen - 4) * 2; strm.head.lastBlockSample = (strm.head.lastBlocklen - 4) * 2; } else if (waveType == 1) { strm.head.blockSample = strm.head.blockLen / 2; strm.head.lastBlockSample = strm.head.lastBlocklen / 2; } else if (waveType == 0) { strm.head.blockSample = strm.head.blockLen; strm.head.lastBlockSample = strm.head.lastBlocklen; } strm.head.nSamples = (strm.head.nBlocks - 1) * strm.head.blockSample + strm.head.lastBlockSample; strm.data.size = (uint)strm.data.data.Length + 0x08; strm.cabecera.fileSize = strm.data.size + strm.head.size + strm.cabecera.headerSize; return strm; }
/// <summary> /// Write a WAV structure to a WAV file /// </summary> /// <param name="wav">WAV structu to write</param> /// <param name="fileout">File where the structure will be written</param> public static void Write(sWAV wav, string fileout) { FileStream fs = null; BinaryWriter bw = null; try { fs = new FileStream(fileout, System.IO.FileMode.Create); bw = new BinaryWriter(fs); bw.Write(Encoding.ASCII.GetBytes(wav.chunkID)); bw.Write(wav.chunkSize); bw.Write(Encoding.ASCII.GetBytes(wav.format)); bw.Write(Encoding.ASCII.GetBytes(wav.wave.fmt.chunkID)); bw.Write(wav.wave.fmt.chunkSize); bw.Write(Convert.ToUInt16(wav.wave.fmt.audioFormat)); bw.Write(wav.wave.fmt.numChannels); bw.Write(wav.wave.fmt.sampleRate); bw.Write(wav.wave.fmt.byteRate); bw.Write(wav.wave.fmt.blockAlign); bw.Write(wav.wave.fmt.bitsPerSample); bw.Write(Encoding.ASCII.GetBytes(wav.wave.data.chunkID)); bw.Write(wav.wave.data.chunkSize); bw.Write(wav.wave.data.data); bw.Flush(); } catch (Exception ex) { Console.WriteLine(ex.Message.ToString()); } finally { if (fs != null) fs.Close(); if (bw != null) bw.Close(); } }
private void btnImport_Click(object sender, EventArgs e) { Sound selectedFile = SearchFile(); String fileout = pluginHost.Get_TempFolder() + Path.DirectorySeparatorChar + Path.GetRandomFileName(); OpenFileDialog o = new OpenFileDialog(); o.CheckFileExists = true; o.AddExtension = true; o.DefaultExt = "wav"; o.Filter = "WAVE audio format (*.wav)|*.wav"; if (o.ShowDialog() != DialogResult.OK) { return; } String filein = o.FileName; sWAV wav = new sWAV(); try { wav = WAV.Read(filein); } catch (Exception ex) { MessageBox.Show(ex.Message); return; } NewAudioOptions dialog = new NewAudioOptions(pluginHost, (selectedFile.type == FormatSound.SWAV ? true : false)); switch (selectedFile.type) { case FormatSound.STRM: sSTRM oldStrm = STRM.Read(SaveFile()); dialog.Compression = oldStrm.head.waveType; dialog.BlockSize = (int)oldStrm.head.blockLen; dialog.Loop = (oldStrm.head.loop != 0 ? true : false); dialog.LoopOffset = (int)oldStrm.head.loopOffset; dialog.SampleRate = (int)wav.wave.fmt.sampleRate; if (dialog.ShowDialog() != DialogResult.OK) { return; } sSTRM strm = STRM.ConvertToSTRM(wav, dialog.Compression); strm.head.loop = (byte)(dialog.Loop ? 0x01 : 0x00); strm.head.loopOffset = (uint)dialog.LoopOffset; STRM.Write(strm, fileout); break; case FormatSound.SWAV: sSWAV oldSwav = SWAV.Read(SaveFile()); dialog.Compression = oldSwav.data.info.nWaveType; dialog.Loop = (oldSwav.data.info.bLoop != 0 ? true : false); dialog.LoopLength = (int)oldSwav.data.info.nNonLoopLen; dialog.LoopOffset = (int)oldSwav.data.info.nLoopOffset; dialog.SampleRate = (int)wav.wave.fmt.sampleRate; if (dialog.ShowDialog() != DialogResult.OK) { return; } sSWAV swav = SWAV.ConvertToSWAV(wav, dialog.Compression, dialog.Volume); swav.data.info.bLoop = (byte)(dialog.Loop ? 0x01 : 0x00); swav.data.info.nLoopOffset = (ushort)dialog.LoopOffset; swav.data.info.nNonLoopLen = (uint)dialog.LoopLength; SWAV.Write(swav, fileout); break; case FormatSound.SSEQ: case FormatSound.SSAR: case FormatSound.SBNK: case FormatSound.SWAR: default: break; } if (!File.Exists(fileout)) { return; } ChangeFile((int)selectedFile.id, fileout); }
/// <summary> /// Read a wave file and return its structure. /// </summary> /// <param name="filein">File to read</param> /// <returns>Structure of the wave file</returns> public static sWAV Read(string filein) { sWAV wav = new sWAV(); BinaryReader br = new BinaryReader(File.OpenRead(filein)); // RIFF header wav.chunkID = br.ReadChars(4); wav.chunkSize = br.ReadUInt32(); wav.format = br.ReadChars(4); if (new String(wav.chunkID) != "RIFF" || new String(wav.format) != "WAVE") throw new NotSupportedException(); // fmt sub-chunk wav.wave.fmt.chunkID = br.ReadChars(4); wav.wave.fmt.chunkSize = br.ReadUInt32(); wav.wave.fmt.audioFormat = (WaveFormat)br.ReadUInt16(); wav.wave.fmt.numChannels = br.ReadUInt16(); wav.wave.fmt.sampleRate = br.ReadUInt32(); wav.wave.fmt.byteRate = br.ReadUInt32(); wav.wave.fmt.blockAlign = br.ReadUInt16(); wav.wave.fmt.bitsPerSample = br.ReadUInt16(); br.BaseStream.Position = 0x14 + wav.wave.fmt.chunkSize; String dataID = new String(br.ReadChars(4)); while (dataID != "data") { br.BaseStream.Position += br.ReadUInt32() + 0x04; dataID = new String(br.ReadChars(4)); } // data sub-chunk br.BaseStream.Position -= 4; wav.wave.data.chunkID = br.ReadChars(4); wav.wave.data.chunkSize = br.ReadUInt32(); wav.wave.data.data = br.ReadBytes((int)wav.wave.data.chunkSize - 0x08); br.Close(); // Convert the data to PCM16 if (wav.wave.fmt.audioFormat != WaveFormat.WAVE_FORMAT_PCM) throw new NotSupportedException(); if (wav.wave.fmt.audioFormat == WaveFormat.WAVE_FORMAT_PCM && wav.wave.fmt.bitsPerSample == 0x08) // PCM8 { wav.wave.fmt.bitsPerSample = 0x10; wav.wave.fmt.blockAlign = (ushort)(wav.wave.fmt.numChannels * wav.wave.fmt.bitsPerSample / (ushort)(8)); wav.wave.fmt.byteRate = wav.wave.fmt.sampleRate * wav.wave.fmt.bitsPerSample * wav.wave.fmt.numChannels / 8; wav.wave.data.data = PCM.PCM8UnsignedToPCM16(wav.wave.data.data); } return wav; }
/// <summary> /// Create a WAV structure using PCM audio format /// </summary> /// <param name="numChannels">Number of channels</param> /// <param name="sampleRate">Sample rate</param> /// <param name="bitsPerSample">Bits per sample</param> /// <param name="data">Audio data</param> /// <returns>New wav structure</returns> public static sWAV Create_WAV(ushort numChannels, uint sampleRate, ushort bitsPerSample, byte[] data) { sWAV wav = new sWAV(); wav.chunkID = new char[] { 'R', 'I', 'F', 'F' }; wav.format = new char[] { 'W', 'A', 'V', 'E' }; wav.wave.fmt.chunkID = new char[] { 'f', 'm', 't', '\x20' }; wav.wave.fmt.chunkSize = 16; wav.wave.fmt.audioFormat = WaveFormat.WAVE_FORMAT_PCM; wav.wave.fmt.numChannels = numChannels; wav.wave.fmt.sampleRate = sampleRate; wav.wave.fmt.bitsPerSample = bitsPerSample; wav.wave.fmt.byteRate = wav.wave.fmt.sampleRate * wav.wave.fmt.bitsPerSample * wav.wave.fmt.numChannels / 8; wav.wave.fmt.blockAlign = (ushort)(wav.wave.fmt.numChannels * wav.wave.fmt.bitsPerSample / (ushort)(8)); wav.wave.data.chunkID = new char[] { 'd', 'a', 't', 'a' }; wav.wave.data.chunkSize = (uint)data.Length; wav.wave.data.data = new byte[data.Length]; wav.wave.data.data = data; wav.chunkSize = (uint)(0x24 + data.Length); return wav; }
public static sWAV ConvertToWAV(sSWAV swav, bool loop) { sWAV wav = new sWAV(); if (swav.data.info.nWaveType == 0) // 8 Bits per sample, PCM-8 { swav.data.data = PCM.PCM8SignedToPCM16(swav.data.data); if (loop) { Byte[] data = new Byte[(int)swav.data.info.nNonLoopLen]; Array.Copy(swav.data.data, swav.data.info.nLoopOffset, data, 0, data.Length); swav.data.data = data; } wav = WAV.Create_WAV(1, swav.data.info.nSampleRate, 16, swav.data.data); } else if (swav.data.info.nWaveType == 1) // 16 Bits per sample, PCM-16 { if (loop) // NO TESTED { Byte[] data = new Byte[(int)swav.data.info.nNonLoopLen]; Array.Copy(swav.data.data, swav.data.info.nLoopOffset, data, 0, data.Length); swav.data.data = data; } wav = WAV.Create_WAV(1, swav.data.info.nSampleRate, 16, swav.data.data); } else if (swav.data.info.nWaveType >= 2) // 4 Bits per sample, IMA-ADPCM { swav.data.data = Compression_ADPCM.Decompress( swav.data.data, BitConverter.ToUInt16(swav.data.data, 0), BitConverter.ToUInt16(swav.data.data, 2)); if (loop) { Byte[] data = new Byte[swav.data.data.Length - ((int)swav.data.info.nLoopOffset * 2)]; Array.Copy(swav.data.data, swav.data.info.nLoopOffset * 2, data, 0, data.Length); swav.data.data = data; } wav = WAV.Create_WAV(1, swav.data.info.nSampleRate, 16, swav.data.data); } return wav; }
public static sSWAV ConvertToSWAV(sWAV wav, int waveType, int volume = 150) { sSWAV swav = new sSWAV(); swav.header.type = "SWAV".ToCharArray(); swav.header.magic = 0x0100FEFF; swav.header.nSize = 0x10; swav.header.nBlock = 0x01; swav.data.type = "DATA".ToCharArray(); swav.data.info.nWaveType = (byte)waveType; swav.data.info.bLoop = 1; swav.data.info.nSampleRate = (ushort)wav.wave.fmt.sampleRate; swav.data.info.nTime = (ushort)(1.6756991e+7 / wav.wave.fmt.sampleRate); swav.data.info.nLoopOffset = 0x01; if (wav.wave.fmt.numChannels > 1) wav.wave.data.data = WAV.ConvertToMono(wav.wave.data.data, wav.wave.fmt.numChannels, wav.wave.fmt.bitsPerSample); //wav.wave.data.data = ChangeVolume(wav.wave.data.data, volume, wav.wave.fmt.bitsPerSample); if (waveType == 0) swav.data.data = PCM.PCM16ToPCM8(wav.wave.data.data); else if (waveType == 2) { List<byte> temp = new List<byte>(); temp.AddRange(new Byte[] { 0x00, 0x00, 0x00, 0x00 }); temp.AddRange(Compression_ADPCM.Compress(wav.wave.data.data)); swav.data.data = temp.ToArray(); } else swav.data.data = wav.wave.data.data; swav.data.nSize = (uint)swav.data.data.Length + 0x0A; swav.data.info.nNonLoopLen = (uint)swav.data.data.Length; swav.header.nFileSize = swav.data.nSize + swav.header.nSize; return swav; }
private void btnImport_Click(object sender, EventArgs e) { Sound selectedFile = SearchFile(); String fileout = pluginHost.Get_TempFolder() + Path.DirectorySeparatorChar + Path.GetRandomFileName(); OpenFileDialog o = new OpenFileDialog(); o.CheckFileExists = true; o.AddExtension = true; o.DefaultExt = "wav"; o.Filter = "WAVE audio format (*.wav)|*.wav"; if (o.ShowDialog() != DialogResult.OK) return; String filein = o.FileName; sWAV wav = new sWAV(); try { wav = WAV.Read(filein); } catch (Exception ex) { MessageBox.Show(ex.Message); return; } NewAudioOptions dialog = new NewAudioOptions(pluginHost, (selectedFile.type == FormatSound.SWAV ? true : false)); switch (selectedFile.type) { case FormatSound.STRM: sSTRM oldStrm = STRM.Read(SaveFile()); dialog.Compression = oldStrm.head.waveType; dialog.BlockSize = (int)oldStrm.head.blockLen; dialog.Loop = (oldStrm.head.loop != 0 ? true : false); dialog.LoopOffset = (int)oldStrm.head.loopOffset; dialog.SampleRate = (int)wav.wave.fmt.sampleRate; if (dialog.ShowDialog() != DialogResult.OK) return; sSTRM strm = STRM.ConvertToSTRM(wav, dialog.Compression); strm.head.loop = (byte)(dialog.Loop ? 0x01 : 0x00); strm.head.loopOffset = (uint)dialog.LoopOffset; STRM.Write(strm, fileout); break; case FormatSound.SWAV: sSWAV oldSwav = SWAV.Read(SaveFile()); dialog.Compression = oldSwav.data.info.nWaveType; dialog.Loop = (oldSwav.data.info.bLoop != 0 ? true : false); dialog.LoopLength = (int)oldSwav.data.info.nNonLoopLen; dialog.LoopOffset = (int)oldSwav.data.info.nLoopOffset; dialog.SampleRate = (int)wav.wave.fmt.sampleRate; if (dialog.ShowDialog() != DialogResult.OK) return; sSWAV swav = SWAV.ConvertToSWAV(wav, dialog.Compression, dialog.Volume); swav.data.info.bLoop = (byte)(dialog.Loop ? 0x01 : 0x00); swav.data.info.nLoopOffset = (ushort)dialog.LoopOffset; swav.data.info.nNonLoopLen = (uint)dialog.LoopLength; SWAV.Write(swav, fileout); break; case FormatSound.SSEQ: case FormatSound.SSAR: case FormatSound.SBNK: case FormatSound.SWAR: default: break; } if (!File.Exists(fileout)) return; ChangeFile((int)selectedFile.id, fileout); }