// // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. IT CAN BE DISTRIBUTED FREE OF CHARGE AS LONG AS THIS HEADER // REMAINS UNCHANGED. // // Email: yetiicb@hotmail.com // // Copyright (C) 2002-2003 Idael Cardoso. // using System; using System.IO; using WaveLib; namespace Yeti.MMedia { /// /// Save RAW PCM data to a stream in WAVE format /// public class WaveWriter : AudioWriter { private const uint WaveHeaderSize = 38; private const uint WaveFormatSize = 18; private uint m_AudioDataSize = 0; private uint m_WrittenBytes = 0; private bool closed = false; public WaveWriter(Stream Output, WaveFormat Format, uint AudioDataSize) : base(Output, Format) { m_AudioDataSize = AudioDataSize; WriteWaveHeader(); } public WaveWriter(Stream Output, WaveFormat Format) :base(Output, Format) { if ( !OutStream.CanSeek ) { throw new ArgumentException("The stream must supports seeking if AudioDataSize is not supported", "Output"); } OutStream.Seek(WaveHeaderSize+8, SeekOrigin.Current); } private byte[] Int2ByteArr(uint val) { byte[] res = new byte[4]; for(int i=0; i<4; i++) { res[i] = (byte)(val >> (i*8)); } return res; } private byte[] Int2ByteArr(short val) { byte[] res = new byte[2]; for(int i=0; i<2; i++) { res[i] = (byte)(val >> (i*8)); } return res; } protected void WriteWaveHeader() { Write(new byte[]{(byte)'R', (byte)'I', (byte)'F', (byte)'F'}); Write(Int2ByteArr(m_AudioDataSize + WaveHeaderSize)); Write(new byte[]{(byte)'W', (byte)'A', (byte)'V', (byte)'E'}); Write(new byte[]{(byte)'f', (byte)'m', (byte)'t', (byte)' '}); Write(Int2ByteArr(WaveFormatSize)); Write(Int2ByteArr(m_InputDataFormat.wFormatTag)); Write(Int2ByteArr(m_InputDataFormat.nChannels)); Write(Int2ByteArr((uint)m_InputDataFormat.nSamplesPerSec)); Write(Int2ByteArr((uint)m_InputDataFormat.nAvgBytesPerSec)); Write(Int2ByteArr(m_InputDataFormat.nBlockAlign)); Write(Int2ByteArr(m_InputDataFormat.wBitsPerSample)); Write(Int2ByteArr(m_InputDataFormat.cbSize)); Write(new byte[]{(byte)'d', (byte)'a', (byte)'t', (byte)'a'}); Write(Int2ByteArr(m_AudioDataSize)); m_WrittenBytes -= (WaveHeaderSize+8); } public override void Close() { if (!closed) { if ( m_AudioDataSize == 0 ) { Seek(-(int)m_WrittenBytes - (int)WaveHeaderSize - 8, SeekOrigin.Current); m_AudioDataSize = m_WrittenBytes; WriteWaveHeader(); } } closed = true; base.Close (); } public override void Write(byte[] buffer, int index, int count) { base.Write (buffer, index, count); m_WrittenBytes += (uint)count; } public override void Write(byte[] buffer) { base.Write (buffer); m_WrittenBytes += (uint)buffer.Length; } protected override int GetOptimalBufferSize() { return m_InputDataFormat.nAvgBytesPerSec /10; } public static IEditAudioWriterConfig GetConfigControl(AudioWriterConfig config) { IEditAudioWriterConfig cfg = new EditWaveWriter(); cfg.Config = config; return cfg; } } }