예제 #1
0
		internal unsafe void SaveAsWaveFile(string filePath)
		{
			const int chunkSize = 4096;
			FileStream file = null;
			IntPtr data = IntPtr.Zero;

			try
			{
				// Create the file
				file = new FileStream(filePath, FileMode.Create, FileAccess.Write);

				// Alocate memory for the PCM data buffer
				data = Marshal.AllocHGlobal(chunkSize);

				// Create a holding buffer that the PCM data will be copied into
				byte[] buffer = new byte[chunkSize];

				uint totalSize = 0;
				uint bytesRead = 0;

				// Get the length of the sound in PCM bytes
				this.LengthUnit = TimeUnits.PcmByte;
				uint pcmLength = this.FmodLength;

				// Create the WAV structures
				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] { 'f', 'm', 't', ' ' };
				fmtChunk.Chunk.Size = Marshal.SizeOf(fmtChunk) - Marshal.SizeOf(riffChunk);
				fmtChunk.FormatTag = 1;
				fmtChunk.NumberOfChannels = (ushort)this.NumberOfChannels;
				fmtChunk.SamplesPerSecond = (uint)this.DefaultSettings.Frequency;
				fmtChunk.AverageBytesPerSecond = (uint)(this.DefaultSettings.Frequency * this.NumberOfChannels * this.NumberOfBitsPerSample / 8);
				fmtChunk.BlockSize = (ushort)(1 * this.NumberOfChannels * this.NumberOfBitsPerSample / 8);
				fmtChunk.NumberOfBitsPerSample = (ushort)this.NumberOfBitsPerSample;

				dataChunk.Chunk = new RiffChunk();
				dataChunk.Chunk.Id = new char[4] { 'd', 'a', 't', 'a' };
				dataChunk.Chunk.Size = (int)pcmLength;

				wavHeader.Chunk = new RiffChunk();
				wavHeader.Chunk.Id = new char[4] { 'R', 'I', 'F', 'F' };
				wavHeader.Chunk.Size = (int)(Marshal.SizeOf(fmtChunk) + Marshal.SizeOf(riffChunk) + pcmLength);
				wavHeader.RiffType = new char[4] { 'W', 'A', 'V', '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));

				file.Write(wavHeaderBytes, 0, Marshal.SizeOf(wavHeader));
				file.Write(fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk));
				file.Write(dataChunkBytes, 0, Marshal.SizeOf(dataChunk));

				do
				{
					// Read PCM data from the sound
					bytesRead = Read(data, chunkSize);

					// Copy the PCM data into the buffer
					Marshal.Copy(data, buffer, 0, chunkSize);

					// Write the PCM data to the FileStream
					file.Write(buffer, 0, (int)bytesRead);

					// Increment totalRead
					totalSize += bytesRead;
				}
				while (currentResult == Result.Ok && bytesRead == chunkSize);

				//file.Close();
			}
			catch (Exception ex)
			{
				throw new ApplicationException("There was an error saving this sound to " + filePath + " : " + currentResult.ToString() + ":" + ex.Message, ex);
			}
			finally
			{
				// Always free the data pointer
				if (data != IntPtr.Zero) Marshal.FreeHGlobal(data);

				// Always close the file
				if (file != null) file.Close();
			}
		}
예제 #2
0
        internal unsafe void SaveAsWaveFile(string filePath)
        {
            const int  chunkSize = 4096;
            FileStream file      = null;
            IntPtr     data      = IntPtr.Zero;

            try
            {
                // Create the file
                file = new FileStream(filePath, FileMode.Create, FileAccess.Write);

                // Alocate memory for the PCM data buffer
                data = Marshal.AllocHGlobal(chunkSize);

                // Create a holding buffer that the PCM data will be copied into
                byte[] buffer = new byte[chunkSize];

                uint totalSize = 0;
                uint bytesRead = 0;

                // Get the length of the sound in PCM bytes
                this.LengthUnit = TimeUnits.PcmByte;
                uint pcmLength = this.FmodLength;

                // Create the WAV structures
                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] {
                    'f', 'm', 't', ' '
                };
                fmtChunk.Chunk.Size            = Marshal.SizeOf(fmtChunk) - Marshal.SizeOf(riffChunk);
                fmtChunk.FormatTag             = 1;
                fmtChunk.NumberOfChannels      = (ushort)this.NumberOfChannels;
                fmtChunk.SamplesPerSecond      = (uint)this.DefaultSettings.Frequency;
                fmtChunk.AverageBytesPerSecond = (uint)(this.DefaultSettings.Frequency * this.NumberOfChannels * this.NumberOfBitsPerSample / 8);
                fmtChunk.BlockSize             = (ushort)(1 * this.NumberOfChannels * this.NumberOfBitsPerSample / 8);
                fmtChunk.NumberOfBitsPerSample = (ushort)this.NumberOfBitsPerSample;

                dataChunk.Chunk    = new RiffChunk();
                dataChunk.Chunk.Id = new char[4] {
                    'd', 'a', 't', 'a'
                };
                dataChunk.Chunk.Size = (int)pcmLength;

                wavHeader.Chunk    = new RiffChunk();
                wavHeader.Chunk.Id = new char[4] {
                    'R', 'I', 'F', 'F'
                };
                wavHeader.Chunk.Size = (int)(Marshal.SizeOf(fmtChunk) + Marshal.SizeOf(riffChunk) + pcmLength);
                wavHeader.RiffType   = new char[4] {
                    'W', 'A', 'V', '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));

                file.Write(wavHeaderBytes, 0, Marshal.SizeOf(wavHeader));
                file.Write(fmtChunkBytes, 0, Marshal.SizeOf(fmtChunk));
                file.Write(dataChunkBytes, 0, Marshal.SizeOf(dataChunk));

                do
                {
                    // Read PCM data from the sound
                    bytesRead = Read(data, chunkSize);

                    // Copy the PCM data into the buffer
                    Marshal.Copy(data, buffer, 0, chunkSize);

                    // Write the PCM data to the FileStream
                    file.Write(buffer, 0, (int)bytesRead);

                    // Increment totalRead
                    totalSize += bytesRead;
                }while (currentResult == Result.Ok && bytesRead == chunkSize);

                //file.Close();
            }
            catch (Exception ex)
            {
                throw new ApplicationException("There was an error saving this sound to " + filePath + " : " + currentResult.ToString() + ":" + ex.Message, ex);
            }
            finally
            {
                // Always free the data pointer
                if (data != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(data);
                }

                // Always close the file
                if (file != null)
                {
                    file.Close();
                }
            }
        }