/// <summary> /// Load a RIFF WAVE. /// </summary> /// <param name="b">The file.</param> public void Load(byte[] b) { //Reader. MemoryStream src = new MemoryStream(b); BinaryDataReader br = new BinaryDataReader(src); magic = new string(br.ReadChars(4)); chunkSize = br.ReadUInt32(); format = new string(br.ReadChars(4)); //The chunks. fmt = new FmtChunk(); data = new DataChunk(); fmt.Load(ref br); data.Load(ref br, fmt); while (br.Position <= (b.Length - 4)) { string magic = new string(br.ReadChars(4)); if (magic == "smpl") { br.Position -= 4; smpl = new SmplChunk(); smpl.Load(ref br); } } }
/// <summary> /// Make a new data chunk. /// </summary> /// <param name="samples">The samples to contain. Is a double array, first index is channel number.</param> /// <param name="fmt">Fmt chunk.</param> public DataChunk(object samples, FmtChunk fmt) { channels = new List <DataSamples>(); if (fmt.bitsPerSample == 8) { byte[][] pcm8 = (samples as byte[][]); for (int i = 0; i < fmt.numChannels; i++) { channels.Add(new DataSamples() { pcm8 = pcm8[i].ToList() }); } } else { Int16[][] pcm16 = (samples as Int16[][]); for (int i = 0; i < fmt.numChannels; i++) { channels.Add(new DataSamples() { pcm16 = pcm16[i].ToList() }); } } }
/// <summary> /// Write the data chunk. /// </summary> /// <param name="bw">The writer.</param> /// <param name="fmt">Fmt chunk.</param> public void Write(ref BinaryDataWriter bw, FmtChunk fmt) { //Call write. base.Write(ref bw); //Write each sample. if (fmt.bitsPerSample == FmtChunk.BitsPerSample.PCM8) { for (int i = 0; i < channels[0].pcm8.Count(); i++) { //Write each channel. for (int j = 0; j < fmt.numChannels; j++) { bw.Write(channels[j].pcm8[i]); } } } else if (fmt.bitsPerSample == FmtChunk.BitsPerSample.PCM16) { for (int i = 0; i < channels[0].pcm16.Count(); i++) { //Write each channel. for (int j = 0; j < fmt.numChannels; j++) { bw.Write(channels[j].pcm16[i]); } } } }
/// <summary> /// Load a data chunk. /// </summary> /// <param name="br">The reader.</param> /// <param name="fmt">Fmt chunk.</param> public void Load(ref BinaryDataReader br, FmtChunk fmt) { //Call load. base.Load(ref br); //Create channels. channels = new List <DataSamples>(); for (int i = 0; i < fmt.numChannels; i++) { channels.Add(new DataSamples() { pcm8 = new List <byte>(), pcm16 = new List <Int16>() }); } //Read each sample frame. for (int i = 0; i < size / fmt.blockAlign; i++) { //Read each channel. for (int j = 0; j < fmt.numChannels; j++) { if (fmt.bitsPerSample == FmtChunk.BitsPerSample.PCM8) { channels[j].pcm8.Add(br.ReadByte()); } else if (fmt.bitsPerSample == FmtChunk.BitsPerSample.PCM16) { channels[j].pcm16.Add(br.ReadInt16()); } } } }
/// <summary>Initializes a new instance of the <see cref="RWWaveFile"/> class.</summary> /// <param name="rid">The Chunk id</param> /// <param name="rfs">The Chunk size</param> /// <param name="rfmt">The Chunk format (WAVE)</param> /// <param name="fid">The subChunk id</param> /// <param name="fsz">The subChunk Size.</param> /// <param name="ftg">The audio format</param> /// <param name="fc">The number of channels</param> /// <param name="fsr">The sample rate</param> /// <param name="fbs">The byte rate</param> /// <param name="fba">The block align</param> /// <param name="fbps">The bits per sample</param> /// <param name="did">The subChunk id 2 (DATA)</param> /// <param name="dsz">The data size (bytes)</param> public RWWaveFile(Byte[] rid, uint rfs, Byte[] rfmt, Byte[] fid, uint fsz, ushort ftg, ushort fc, uint fsr, uint fbs, ushort fba, ushort fbps, Byte[] did, uint dsz) { RiffChunk1 = new RiffChunk(); FmtChunk1 = new FmtChunk(); DataChunk1 = new DataChunk(); // RIFF chunk RiffChunk1.RiffID = rid; RiffChunk1.FileSize = rfs; RiffChunk1.RiffFormat = rfmt; // fmt chuck FmtChunk1.FmtID = fid; FmtChunk1.FmtSize = fsz; FmtChunk1.FmtTag = ftg; FmtChunk1.Channels = fc; FmtChunk1.SamplesPerSec = fsr; FmtChunk1.AverageBytesPerSec = fbs; FmtChunk1.BlockAlign = fba; FmtChunk1.BitsPerSample = fbps; // data chunk DataChunk1.DataID = did; DataChunk1.DataSize = dsz; }
public static AudioClip ToAudioClip(byte[] audioData, string fileName) { using (MemoryStream fs = new MemoryStream(audioData)) { using (BinaryReader reader = new BinaryReader(fs)) { GetChunk(fs, reader); // RIFF chunk FmtChunk formatChunk = (FmtChunk)GetChunk(fs, reader); while (fs.Position < fs.Length) { Chunk chunk = GetChunk(fs, reader); if (chunk.Ident == ChunkType.Data) { DataChunk dc = (DataChunk)chunk; float[] data = dc.GetAudioData(formatChunk); AudioClip clip = AudioClip.Create(fileName, data.Length, 1, formatChunk.Frequency, false); clip.SetData(data, 0); return(clip); } } } } return(null); }
/*public float[] GetAudioData(FmtChunk format) * { * int samplesPerChannel = ByteCount / (format.BytesPerSample * format.Channels); * if (format.Channels > 1) * { * Debug.LogError("Audio file has more than 1 channel, this is not supported."); * return null; * } * * if (format.BitsPerSample != 8) * { * Debug.LogError("Audio file has more than 8 bits per channel, this is not supported."); * return null; * } * * float[] data = new float[samplesPerChannel]; * int mask = (int)Math.Floor(Math.Pow(2, format.BitsPerSample)) - 1; * int offset = 0; * for (int index = 0; index < samplesPerChannel; ++index) * { * data[index] = (_samples[offset] & mask) / 255f; * offset += format.BytesPerSample; ++index; * } * * return data; * }*/ public float[] GetAudioData(FmtChunk format) { if (format.Channels > 1) { Debug.LogError("More than 1 audio channel not implemented."); return(null); } if (format.BitsPerSample != 8) { Debug.LogError("Only 8-bit audio is implemented."); return(null); } int samplesPerChannel = ByteCount / format.BytesPerSample; float[] data = new float[samplesPerChannel]; int mask = (int)Math.Floor(Math.Pow(2, format.BitsPerSample)) - 1; int offset = 0; for (int index = 0; index < samplesPerChannel; ++index) { data[index] = (_samples[offset] & mask) / 255f; offset += format.BytesPerSample; } return(data); }
public WaveFile(Stream stream) { FileStream = stream; Riff = new RiffChunk(); Format = new FmtChunk(); Data = new DataChunk(); }
/// <summary>Initializes a new instance of the <see cref="RWWaveFile"/> class.</summary> /// <param name="newFilePath">The path to the file</param> public RWWaveFile(string newFilePath) { filepath = newFilePath; fileInfo = new FileInfo(newFilePath); fileStream = fileInfo.OpenRead(); RiffChunk1 = new RiffChunk(fileStream); FmtChunk1 = new FmtChunk(fileStream); DataChunk1 = new DataChunk(fileStream, FmtChunk1); }
/// <summary> /// Update the data chunk. /// </summary> /// <param name="fmt">Fmt chunk.</param> public void Update(FmtChunk fmt) { //Call update. if (fmt.bitsPerSample == FmtChunk.BitsPerSample.PCM8) { base.Update("data", (UInt32)(fmt.blockAlign * channels[0].pcm8.Count())); } else if (fmt.bitsPerSample == FmtChunk.BitsPerSample.PCM16) { base.Update("data", (UInt32)(fmt.blockAlign * channels[0].pcm16.Count())); } }
private void WriteWavHeader(int length) { FMOD.SOUND_TYPE type = FMOD.SOUND_TYPE.UNKNOWN; FMOD.SOUND_FORMAT format = FMOD.SOUND_FORMAT.NONE; int channels = 0, bits = 0, temp1 = 0; float rate = 0.0f; float temp = 0.0f; if (sound == null) { return; } sound.getFormat(ref type, ref format, ref channels, ref bits); sound.getDefaults(ref rate, ref temp, ref temp, ref temp1); fs.Seek(0, SeekOrigin.Begin); FmtChunk fmtChunk = new FmtChunk(); DataChunk dataChunk = new DataChunk(); WavHeader wavHeader = new WavHeader(); RiffChunk riffChunk = new RiffChunk(); fmtChunk.chunk = new RiffChunk(); fmtChunk.chunk.id = new char[4]; fmtChunk.chunk.id[0] = 'f'; fmtChunk.chunk.id[1] = 'm'; fmtChunk.chunk.id[2] = 't'; fmtChunk.chunk.id[3] = ' '; fmtChunk.chunk.size = Marshal.SizeOf(fmtChunk) - Marshal.SizeOf(riffChunk); fmtChunk.wFormatTag = 1; fmtChunk.nChannels = (ushort)channels; fmtChunk.nSamplesPerSec = (uint)rate; fmtChunk.nAvgBytesPerSec = (uint)(rate * channels * bits / 8); fmtChunk.nBlockAlign = (ushort)(1 * channels * bits / 8); fmtChunk.wBitsPerSample = (ushort)bits; dataChunk.chunk = new RiffChunk(); dataChunk.chunk.id = new char[4]; dataChunk.chunk.id[0] = 'd'; dataChunk.chunk.id[1] = 'a'; dataChunk.chunk.id[2] = 't'; dataChunk.chunk.id[3] = 'a'; dataChunk.chunk.size = (int)length; wavHeader.chunk = new RiffChunk(); wavHeader.chunk.id = new char[4]; wavHeader.chunk.id[0] = 'R'; wavHeader.chunk.id[1] = 'I'; wavHeader.chunk.id[2] = 'F'; wavHeader.chunk.id[3] = 'F'; wavHeader.chunk.size = (int)(Marshal.SizeOf(fmtChunk) + Marshal.SizeOf(riffChunk) + length); wavHeader.rifftype = new char[4]; wavHeader.rifftype[0] = 'W'; wavHeader.rifftype[1] = 'A'; wavHeader.rifftype[2] = 'V'; wavHeader.rifftype[3] = 'E'; /* Write out the WAV header. */ IntPtr wavHeaderPtr = Marshal.AllocHGlobal(Marshal.SizeOf(wavHeader)); IntPtr fmtChunkPtr = Marshal.AllocHGlobal(Marshal.SizeOf(fmtChunk)); IntPtr dataChunkPtr = Marshal.AllocHGlobal(Marshal.SizeOf(dataChunk)); byte []wavHeaderBytes = new byte[Marshal.SizeOf(wavHeader)]; byte []fmtChunkBytes = new byte[Marshal.SizeOf(fmtChunk)]; byte []dataChunkBytes = new byte[Marshal.SizeOf(dataChunk)]; Marshal.StructureToPtr(wavHeader, wavHeaderPtr, false); Marshal.Copy(wavHeaderPtr, wavHeaderBytes, 0, Marshal.SizeOf(wavHeader)); Marshal.StructureToPtr(fmtChunk, fmtChunkPtr, false); Marshal.Copy(fmtChunkPtr, fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk)); Marshal.StructureToPtr(dataChunk, dataChunkPtr, false); Marshal.Copy(dataChunkPtr, dataChunkBytes, 0, Marshal.SizeOf(dataChunk)); fs.Write(wavHeaderBytes, 0, Marshal.SizeOf(wavHeader)); fs.Write(fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk)); fs.Write(dataChunkBytes, 0, Marshal.SizeOf(dataChunk)); }
public static void WriteWavHeader(FileStream stream, FMOD.Sound sound, int length, Object usingFmod) { FMOD.SOUND_TYPE type = FMOD.SOUND_TYPE.UNKNOWN; FMOD.SOUND_FORMAT format = FMOD.SOUND_FORMAT.NONE; int channels = 0, bits = 0, temp1 = 0; float rate = 0.0f; float temp = 0.0f; if (sound == null) { return; } lock (usingFmod) { sound.getFormat(ref type, ref format, ref channels, ref bits); sound.getDefaults(ref rate, ref temp, ref temp, ref temp1); } log.Info("WaveWriter.WriteWavHeader: sound format: dataLength " + length + ", type " + type + ", format " + format + ", channels " + channels + ", bits " + bits + ", rate " + rate); stream.Seek(0, SeekOrigin.Begin); FmtChunk fmtChunk = new FmtChunk(); DataChunk dataChunk = new DataChunk(); WavHeader wavHeader = new WavHeader(); RiffChunk riffChunk = new RiffChunk(); fmtChunk.chunk = new RiffChunk(); fmtChunk.chunk.id = new char[4]; fmtChunk.chunk.id[0] = 'f'; fmtChunk.chunk.id[1] = 'm'; fmtChunk.chunk.id[2] = 't'; fmtChunk.chunk.id[3] = ' '; fmtChunk.chunk.size = Marshal.SizeOf(fmtChunk) - Marshal.SizeOf(riffChunk); fmtChunk.wFormatTag = 1; fmtChunk.nChannels = (ushort)channels; fmtChunk.nSamplesPerSec = (uint)rate; fmtChunk.nAvgBytesPerSec = (uint)(rate * channels * bits / 8); fmtChunk.nBlockAlign = (ushort)(1 * channels * bits / 8); fmtChunk.wBitsPerSample = (ushort)bits; dataChunk.chunk = new RiffChunk(); dataChunk.chunk.id = new char[4]; dataChunk.chunk.id[0] = 'd'; dataChunk.chunk.id[1] = 'a'; dataChunk.chunk.id[2] = 't'; dataChunk.chunk.id[3] = 'a'; dataChunk.chunk.size = (int)length; wavHeader.chunk = new RiffChunk(); wavHeader.chunk.id = new char[4]; wavHeader.chunk.id[0] = 'R'; wavHeader.chunk.id[1] = 'I'; wavHeader.chunk.id[2] = 'F'; wavHeader.chunk.id[3] = 'F'; wavHeader.chunk.size = (int)(Marshal.SizeOf(fmtChunk) + Marshal.SizeOf(riffChunk) + length); wavHeader.rifftype = new char[4]; wavHeader.rifftype[0] = 'W'; wavHeader.rifftype[1] = 'A'; wavHeader.rifftype[2] = 'V'; wavHeader.rifftype[3] = 'E'; /* * Write out the WAV header. */ IntPtr wavHeaderPtr = Marshal.AllocHGlobal(Marshal.SizeOf(wavHeader)); IntPtr fmtChunkPtr = Marshal.AllocHGlobal(Marshal.SizeOf(fmtChunk)); IntPtr dataChunkPtr = Marshal.AllocHGlobal(Marshal.SizeOf(dataChunk)); byte [] wavHeaderBytes = new byte[Marshal.SizeOf(wavHeader)]; byte [] fmtChunkBytes = new byte[Marshal.SizeOf(fmtChunk)]; byte [] dataChunkBytes = new byte[Marshal.SizeOf(dataChunk)]; Marshal.StructureToPtr(wavHeader, wavHeaderPtr, false); Marshal.Copy(wavHeaderPtr, wavHeaderBytes, 0, Marshal.SizeOf(wavHeader)); Marshal.StructureToPtr(fmtChunk, fmtChunkPtr, false); Marshal.Copy(fmtChunkPtr, fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk)); Marshal.StructureToPtr(dataChunk, dataChunkPtr, false); Marshal.Copy(dataChunkPtr, dataChunkBytes, 0, Marshal.SizeOf(dataChunk)); stream.Write(wavHeaderBytes, 0, Marshal.SizeOf(wavHeader)); stream.Write(fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk)); stream.Write(dataChunkBytes, 0, Marshal.SizeOf(dataChunk)); }
/// <summary> /// Get sample data in the wave file /// </summary> /// <returns>A double array[channel][sample] in range -1.0 to 1.0</returns> public double[][] GetSampleData() { FmtChunk fmtChunk = (FmtChunk)Riff.Chunks["fmt "]; DataChunk dataChunk = (DataChunk)Riff.Chunks["data"]; double[][] values = new double[fmtChunk.NumChennals][]; int channelLength = dataChunk.Data.Length / fmtChunk.BlockAlign; for (int i = 0; i < fmtChunk.NumChennals; i++) { values[i] = new double[channelLength]; } short audioFormat = fmtChunk.AudioFormat; if (audioFormat == -2) { if (fmtChunk.ExtraParams != null) { audioFormat = GetFormatCode(fmtChunk.ExtraParams.SubFormatGuid); } else { throw new FormatNotSupportedException(); } } switch (audioFormat) { case 0x0001: switch (fmtChunk.BitsPerSample) { case 16: using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(dataChunk.Data))) { for (int pos = 0; pos < channelLength; pos++) { for (int chan = 0; chan < fmtChunk.NumChennals; chan++) { short value = binaryReader.ReadInt16(); values[chan][pos] = (double)value / short.MaxValue; } } } break; case 24: using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(dataChunk.Data))) { for (int pos = 0; pos < channelLength; pos++) { for (int chan = 0; chan < fmtChunk.NumChennals; chan++) { byte[] buffer = new byte[3]; binaryReader.Read(buffer, 0, buffer.Length); int value = buffer[0] | buffer[1] << 8 | (sbyte)buffer[2] << 16; values[chan][pos] = (double)value / 8388607; } } } break; case 32: using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(dataChunk.Data))) { for (int pos = 0; pos < channelLength; pos++) { for (int chan = 0; chan < fmtChunk.NumChennals; chan++) { int value = binaryReader.ReadInt32(); values[chan][pos] = (double)value / int.MaxValue; } } } break; case 64: using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(dataChunk.Data))) { for (int pos = 0; pos < channelLength; pos++) { for (int chan = 0; chan < fmtChunk.NumChennals; chan++) { long value = binaryReader.ReadInt64(); values[chan][pos] = (double)value / long.MaxValue; } } } break; default: throw new FormatNotSupportedException(); } break; case 0x0003: switch (fmtChunk.BitsPerSample) { case 32: using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(dataChunk.Data))) { for (int pos = 0; pos < channelLength; pos++) { for (int chan = 0; chan < fmtChunk.NumChennals; chan++) { float value = binaryReader.ReadSingle(); values[chan][pos] = value; } } } break; case 64: using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(dataChunk.Data))) { for (int pos = 0; pos < channelLength; pos++) { for (int chan = 0; chan < fmtChunk.NumChennals; chan++) { double value = binaryReader.ReadDouble(); values[chan][pos] = value; } } } break; default: throw new FormatNotSupportedException(); } break; default: throw new FormatNotSupportedException(); } return(values); }
private void SaveToWav() { FileStream fs = null; int channels = 0, bits = 0; float rate = 0; IntPtr ptr1 = new IntPtr(), ptr2 = new IntPtr(); uint lenbytes = 0, len1 = 0, len2 = 0; FMOD.SOUND_TYPE type = FMOD.SOUND_TYPE.WAV; FMOD.SOUND_FORMAT format = FMOD.SOUND_FORMAT.NONE; int temp1 = 0; float temp3 = 0; if (sound == null) { return; } sound.getFormat(ref type, ref format, ref channels, ref bits); sound.getDefaults(ref rate, ref temp3, ref temp3, ref temp1); sound.getLength(ref lenbytes, FMOD.TIMEUNIT.PCMBYTES); FmtChunk fmtChunk = new FmtChunk(); DataChunk dataChunk = new DataChunk(); WavHeader wavHeader = new WavHeader(); RiffChunk riffChunk = new RiffChunk(); fmtChunk.chunk = new RiffChunk(); fmtChunk.chunk.id = new char[4]; fmtChunk.chunk.id[0] = 'f'; fmtChunk.chunk.id[1] = 'm'; fmtChunk.chunk.id[2] = 't'; fmtChunk.chunk.id[3] = ' '; fmtChunk.chunk.size = Marshal.SizeOf(fmtChunk) - Marshal.SizeOf(riffChunk); fmtChunk.wFormatTag = 1; fmtChunk.nChannels = (ushort)channels; fmtChunk.nSamplesPerSec = (uint)rate; fmtChunk.nAvgBytesPerSec = (uint)(rate * channels * bits / 8); fmtChunk.nBlockAlign = (ushort)(1 * channels * bits / 8); fmtChunk.wBitsPerSample = (ushort)bits; dataChunk.chunk = new RiffChunk(); dataChunk.chunk.id = new char[4]; dataChunk.chunk.id[0] = 'd'; dataChunk.chunk.id[1] = 'a'; dataChunk.chunk.id[2] = 't'; dataChunk.chunk.id[3] = 'a'; dataChunk.chunk.size = (int)lenbytes; wavHeader.chunk = new RiffChunk(); wavHeader.chunk.id = new char[4]; wavHeader.chunk.id[0] = 'R'; wavHeader.chunk.id[1] = 'I'; wavHeader.chunk.id[2] = 'F'; wavHeader.chunk.id[3] = 'F'; wavHeader.chunk.size = (int)(Marshal.SizeOf(fmtChunk) + Marshal.SizeOf(riffChunk) + lenbytes); wavHeader.rifftype = new char[4]; wavHeader.rifftype[0] = 'W'; wavHeader.rifftype[1] = 'A'; wavHeader.rifftype[2] = 'V'; wavHeader.rifftype[3] = 'E'; fs = new FileStream("record.wav", FileMode.Create, FileAccess.Write); /* * Write out the WAV header. */ IntPtr wavHeaderPtr = Marshal.AllocHGlobal(Marshal.SizeOf(wavHeader)); IntPtr fmtChunkPtr = Marshal.AllocHGlobal(Marshal.SizeOf(fmtChunk)); IntPtr dataChunkPtr = Marshal.AllocHGlobal(Marshal.SizeOf(dataChunk)); byte [] wavHeaderBytes = new byte[Marshal.SizeOf(wavHeader)]; byte [] fmtChunkBytes = new byte[Marshal.SizeOf(fmtChunk)]; byte [] dataChunkBytes = new byte[Marshal.SizeOf(dataChunk)]; Marshal.StructureToPtr(wavHeader, wavHeaderPtr, false); Marshal.Copy(wavHeaderPtr, wavHeaderBytes, 0, Marshal.SizeOf(wavHeader)); Marshal.StructureToPtr(fmtChunk, fmtChunkPtr, false); Marshal.Copy(fmtChunkPtr, fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk)); Marshal.StructureToPtr(dataChunk, dataChunkPtr, false); Marshal.Copy(dataChunkPtr, dataChunkBytes, 0, Marshal.SizeOf(dataChunk)); fs.Write(wavHeaderBytes, 0, Marshal.SizeOf(wavHeader)); fs.Write(fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk)); fs.Write(dataChunkBytes, 0, Marshal.SizeOf(dataChunk)); /* * Lock the sound to get access to the raw data. */ sound.@lock(0, lenbytes, ref ptr1, ref ptr2, ref len1, ref len2); /* * Write it to disk. */ byte [] rawdata = new byte[len1]; Marshal.Copy(ptr1, rawdata, 0, (int)len1); fs.Write(rawdata, 0, (int)len1); /* * Unlock the sound to allow FMOD to use it again. */ sound.unlock(ptr1, ptr2, len1, len2); fs.Close(); MessageBox.Show("Written to record.wav"); }
private void SaveToWav() { FileStream fs = null; int channels = 0, bits = 0; float rate = 0; IntPtr ptr1 = new IntPtr(), ptr2 = new IntPtr(); uint lenbytes = 0, len1 = 0, len2 = 0; FMOD.SOUND_TYPE type = FMOD.SOUND_TYPE.WAV; FMOD.SOUND_FORMAT format = FMOD.SOUND_FORMAT.NONE; int temp1 = 0; float temp3 = 0; if (sound == null) { return; } sound.getFormat (ref type, ref format, ref channels, ref bits); sound.getDefaults(ref rate, ref temp3, ref temp3, ref temp1); sound.getLength (ref lenbytes, FMOD.TIMEUNIT.PCMBYTES); FmtChunk fmtChunk = new FmtChunk(); DataChunk dataChunk = new DataChunk(); WavHeader wavHeader = new WavHeader(); RiffChunk riffChunk = new RiffChunk(); fmtChunk.chunk = new RiffChunk(); fmtChunk.chunk.id = new char[4]; fmtChunk.chunk.id[0] = 'f'; fmtChunk.chunk.id[1] = 'm'; fmtChunk.chunk.id[2] = 't'; fmtChunk.chunk.id[3] = ' '; fmtChunk.chunk.size = Marshal.SizeOf(fmtChunk) - Marshal.SizeOf(riffChunk); fmtChunk.wFormatTag = 1; fmtChunk.nChannels = (ushort)channels; fmtChunk.nSamplesPerSec = (uint)rate; fmtChunk.nAvgBytesPerSec = (uint)(rate * channels * bits / 8); fmtChunk.nBlockAlign = (ushort)(1 * channels * bits / 8); fmtChunk.wBitsPerSample = (ushort)bits; dataChunk.chunk = new RiffChunk(); dataChunk.chunk.id = new char[4]; dataChunk.chunk.id[0] = 'd'; dataChunk.chunk.id[1] = 'a'; dataChunk.chunk.id[2] = 't'; dataChunk.chunk.id[3] = 'a'; dataChunk.chunk.size = (int)lenbytes; wavHeader.chunk = new RiffChunk(); wavHeader.chunk.id = new char[4]; wavHeader.chunk.id[0] = 'R'; wavHeader.chunk.id[1] = 'I'; wavHeader.chunk.id[2] = 'F'; wavHeader.chunk.id[3] = 'F'; wavHeader.chunk.size = (int)(Marshal.SizeOf(fmtChunk) + Marshal.SizeOf(riffChunk) + lenbytes); wavHeader.rifftype = new char[4]; wavHeader.rifftype[0] = 'W'; wavHeader.rifftype[1] = 'A'; wavHeader.rifftype[2] = 'V'; wavHeader.rifftype[3] = 'E'; fs = new FileStream("record.wav", FileMode.Create, FileAccess.Write); /* Write out the WAV header. */ IntPtr wavHeaderPtr = Marshal.AllocHGlobal(Marshal.SizeOf(wavHeader)); IntPtr fmtChunkPtr = Marshal.AllocHGlobal(Marshal.SizeOf(fmtChunk)); IntPtr dataChunkPtr = Marshal.AllocHGlobal(Marshal.SizeOf(dataChunk)); byte []wavHeaderBytes = new byte[Marshal.SizeOf(wavHeader)]; byte []fmtChunkBytes = new byte[Marshal.SizeOf(fmtChunk)]; byte []dataChunkBytes = new byte[Marshal.SizeOf(dataChunk)]; Marshal.StructureToPtr(wavHeader, wavHeaderPtr, false); Marshal.Copy(wavHeaderPtr, wavHeaderBytes, 0, Marshal.SizeOf(wavHeader)); Marshal.StructureToPtr(fmtChunk, fmtChunkPtr, false); Marshal.Copy(fmtChunkPtr, fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk)); Marshal.StructureToPtr(dataChunk, dataChunkPtr, false); Marshal.Copy(dataChunkPtr, dataChunkBytes, 0, Marshal.SizeOf(dataChunk)); fs.Write(wavHeaderBytes, 0, Marshal.SizeOf(wavHeader)); fs.Write(fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk)); fs.Write(dataChunkBytes, 0, Marshal.SizeOf(dataChunk)); /* Lock the sound to get access to the raw data. */ sound.@lock(0, lenbytes, ref ptr1, ref ptr2, ref len1, ref len2); /* Write it to disk. */ byte []rawdata = new byte[len1]; Marshal.Copy(ptr1, rawdata, 0, (int)len1); fs.Write(rawdata, 0, (int)len1); /* Unlock the sound to allow FMOD to use it again. */ sound.unlock(ptr1, ptr2, len1, len2); fs.Close(); MessageBox.Show("Written to record.wav"); }