Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Speech / Src / Internal / Synthesis / AudioBase.cs / 1 / AudioBase.cs
//------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This class defines the header used to identify a waveform-audio
// buffer.
//
// History:
// 2/1/2005 [....] Created from the Sapi Managed code
//-----------------------------------------------------------------
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace System.Speech.Internal.Synthesis
{
///
/// Encapsulates Waveform Audio Interface playback functions and provides a simple
/// interface for playing audio.
///
internal abstract class AudioBase
{
//*******************************************************************
//
// Constructors
//
//*******************************************************************
#region Constructors
///
/// Create an instance of AudioBase.
///
internal AudioBase ()
{
}
#endregion
//********************************************************************
//
// Internal Methods
//
//*******************************************************************
#region Internal Methods
#region abstract Members
///
/// Play a wave file.
///
///
internal abstract void Begin (byte [] wfx);
///
/// Play a wave file.
///
internal abstract void End ();
///
/// Play a wave file.
///
///
///
internal virtual void Play (IntPtr pBuff, int cb)
{
byte [] buffer = new byte [cb];
Marshal.Copy (pBuff, buffer, 0, cb);
Play (buffer);
}
///
/// Play a wave file.
///
///
internal virtual void Play (byte [] buffer)
{
GCHandle gc = GCHandle.Alloc (buffer);
Play (gc.AddrOfPinnedObject (), buffer.Length);
gc.Free ();
}
///
/// Pause the playback of a sound.
///
/// MMSYSERR.NOERROR if successful
internal abstract void Pause ();
///
/// Resume the playback of a paused sound.
///
/// MMSYSERR.NOERROR if successful
internal abstract void Resume ();
///
/// Throw an event synchronized with the audio stream
///
///
internal abstract void InjectEvent (TTSEvent ttsEvent);
///
/// File operation are synchonous no wait
///
internal abstract void WaitUntilDone ();
///
/// Wait for all the queued buffers to be played
///
internal abstract void Abort ();
#endregion
#region helpers
internal void PlayWaveFile (AudioData audio)
{
// allocate some memory for the largest header
try
{
// Fake a header for ALaw and ULaw
if (!string.IsNullOrEmpty (audio._mimeType))
{
WAVEFORMATEX wfx = new WAVEFORMATEX ();
wfx.nChannels = 1;
wfx.nSamplesPerSec = 8000;
wfx.nAvgBytesPerSec = 8000;
wfx.nBlockAlign = 1;
wfx.wBitsPerSample = 8;
wfx.cbSize = 0;
switch (audio._mimeType)
{
case "audio/basic":
wfx.wFormatTag = (short) AudioFormat.EncodingFormat.ULaw;
break;
case "audio/x-alaw-basic":
wfx.wFormatTag = (short) AudioFormat.EncodingFormat.ALaw;
break;
default:
throw new FormatException (SR.Get (SRID.UnknownMimeFormat));
}
Begin (wfx.ToBytes ());
try
{
byte [] data = new byte [(int) audio._stream.Length];
audio._stream.Read (data, 0, data.Length);
Play (data);
}
finally
{
WaitUntilDone ();
End ();
}
}
else
{
BinaryReader br = new BinaryReader (audio._stream);
try
{
byte [] wfx =GetWaveFormat (br);
if (wfx == null)
{
throw new FormatException (SR.Get (SRID.NotValidAudioFile, audio._uri.ToString ()));
}
Begin (wfx);
try
{
while (true)
{
DATAHDR dataHdr = new DATAHDR ();
// check for the end of file (+8 for the 2 DWORD)
if (audio._stream.Position + 8 >= audio._stream.Length)
{
break;
}
dataHdr._id = br.ReadUInt32 ();
dataHdr._len = br.ReadInt32 ();
// Is this the WAVE data?
if (dataHdr._id == DATA_MARKER)
{
byte [] ab = Helpers.ReadStreamToByteArray (audio._stream, dataHdr._len);
Play (ab);
}
else
{
// Skip this RIFF fragment.
audio._stream.Seek (dataHdr._len, SeekOrigin.Current);
}
}
}
finally
{
WaitUntilDone ();
End ();
}
}
finally
{
((IDisposable) br).Dispose ();
}
}
}
finally
{
audio.Dispose ();
}
}
internal static byte [] GetWaveFormat (BinaryReader br)
{
// Read the riff Header
RIFFHDR riff = new RIFFHDR ();
riff._id = br.ReadUInt32 ();
riff._len = br.ReadInt32 ();
riff._type = br.ReadUInt32 ();
if (riff._id != RIFF_MARKER && riff._type != WAVE_MARKER)
{
return null; ;
}
BLOCKHDR block = new BLOCKHDR ();
block._id = br.ReadUInt32 ();
block._len = br.ReadInt32 ();
if (block._id != FMT_MARKER)
{
return null; ;
}
// If the format is of type WAVEFORMAT then fake a cbByte with a length of zero
byte [] wfx;
wfx = br.ReadBytes (block._len);
// Hardcode the value of the size for the structure element
// as the C# compiler pads the structure to the closest 4 or 8 bytes
if (block._len == 16)
{
byte [] wfxTemp = new byte [18];
Array.Copy (wfx, wfxTemp, 16);
wfx = wfxTemp;
}
return wfx;
}
///
///
///
///
///
///
///
/// Position in the stream for the header
internal static void WriteWaveHeader (Stream stream, WAVEFORMATEX waveEx, long position, int cData)
{
RIFFHDR riff = new RIFFHDR (0);
BLOCKHDR block = new BLOCKHDR (0);
DATAHDR dataHdr = new DATAHDR (0);
int cRiff = Marshal.SizeOf (riff);
int cBlock = Marshal.SizeOf (block);
int cWaveEx = waveEx.Length;// Marshal.SizeOf (waveEx); // The CLR automatically pad the waveEx structure to dword boundary. Force 16.
int cDataHdr = Marshal.SizeOf (dataHdr);
int total = cRiff + cBlock + cWaveEx + cDataHdr;
using (MemoryStream memStream = new MemoryStream ())
{
BinaryWriter bw = new BinaryWriter (memStream);
try
{
// Write the RIFF section
riff._len = total + cData - 8/* - cRiff*/; // for the "WAVE" 4 characters
bw.Write (riff._id);
bw.Write (riff._len);
bw.Write (riff._type);
// Write the wave header section
block._len = cWaveEx;
bw.Write (block._id);
bw.Write (block._len);
// Write the FormatEx structure
bw.Write (waveEx.ToBytes ());
//bw.Write (waveEx.cbSize);
// Write the data section
dataHdr._len = cData;
bw.Write (dataHdr._id);
bw.Write (dataHdr._len);
stream.Seek (position, SeekOrigin.Begin);
stream.Write (memStream.GetBuffer (), 0, (int) memStream.Length);
}
finally
{
((IDisposable) bw).Dispose ();
}
}
}
#endregion
#endregion
//********************************************************************
//
// Internal Property
//
//********************************************************************
#region Internal Property
internal abstract TimeSpan Duration { get; }
internal virtual long Position { get { return 0; } }
internal virtual bool IsAborted
{
set
{
_aborted = false;
}
get
{
return _aborted;
}
}
internal virtual byte [] WaveFormat { get { return null; } }
#endregion
//*******************************************************************
//
// Protected Property
//
//********************************************************************
#region Protected Property
protected bool _aborted;
#endregion
//*******************************************************************
//
// Private Types
//
//*******************************************************************
#region Private Types
private const UInt32 RIFF_MARKER = 0x46464952;
private const UInt32 WAVE_MARKER = 0x45564157;
private const UInt32 FMT_MARKER = 0x20746d66;
private const UInt32 DATA_MARKER = 0x61746164;
[StructLayout (LayoutKind.Sequential)]
private struct RIFFHDR
{
internal UInt32 _id;
internal Int32 _len; /* file length less header */
internal UInt32 _type; /* should be "WAVE" */
internal RIFFHDR (int length)
{
_id = RIFF_MARKER;
_type = WAVE_MARKER;
_len = length;
}
}
[StructLayout (LayoutKind.Sequential)]
private struct BLOCKHDR
{
internal UInt32 _id; /* should be "fmt " or "data" */
internal Int32 _len; /* block size less header */
internal BLOCKHDR (int length)
{
_id = FMT_MARKER;
_len = length;
}
};
[StructLayout (LayoutKind.Sequential)]
private struct DATAHDR
{
internal UInt32 _id; /* should be "fmt " or "data" */
internal Int32 _len; /* block size less header */
internal DATAHDR (int length)
{
_id = DATA_MARKER;
_len = length;
}
}
#endregion
}
//*******************************************************************
//
// Internal Types
//
//********************************************************************
#region Internal Methods
[System.Runtime.InteropServices.TypeLibTypeAttribute (16)]
internal struct WAVEFORMATEX
{
#pragma warning disable 649
internal Int16 wFormatTag;
internal Int16 nChannels;
internal int nSamplesPerSec;
internal int nAvgBytesPerSec;
internal Int16 nBlockAlign;
internal Int16 wBitsPerSample;
internal Int16 cbSize;
#pragma warning restore 649
static internal WAVEFORMATEX ToWaveHeader (byte [] waveHeader)
{
GCHandle gc = GCHandle.Alloc (waveHeader, GCHandleType.Pinned);
IntPtr ptr = gc.AddrOfPinnedObject ();
WAVEFORMATEX wfx = new WAVEFORMATEX ();
wfx.wFormatTag = Marshal.ReadInt16 (ptr);
wfx.nChannels = Marshal.ReadInt16 (ptr, 2);
wfx.nSamplesPerSec = Marshal.ReadInt32 (ptr, 4);
wfx.nAvgBytesPerSec = Marshal.ReadInt32 (ptr, 8);
wfx.nBlockAlign = Marshal.ReadInt16 (ptr, 12);
wfx.wBitsPerSample = Marshal.ReadInt16 (ptr, 14);
wfx.cbSize = Marshal.ReadInt16 (ptr, 16);
if (wfx.cbSize != 0)
{
throw new InvalidOperationException ();
}
gc.Free ();
return wfx;
}
static internal void AvgBytesPerSec (byte [] waveHeader, out int avgBytesPerSec, out int nBlockAlign)
{
// Hardcode the value of the size for the structure element
// as the C# compiler pads the structure to the closest 4 or 8 bytes
GCHandle gc = GCHandle.Alloc (waveHeader, GCHandleType.Pinned);
IntPtr ptr = gc.AddrOfPinnedObject ();
avgBytesPerSec = Marshal.ReadInt32 (ptr, 8);
nBlockAlign = Marshal.ReadInt16 (ptr, 12);
gc.Free ();
}
internal byte [] ToBytes ()
{
System.Diagnostics.Debug.Assert (cbSize == 0);
GCHandle gc = GCHandle.Alloc (this, GCHandleType.Pinned);
byte [] ab = ToBytes (gc.AddrOfPinnedObject ());
gc.Free ();
return ab;
}
static internal byte [] ToBytes (IntPtr waveHeader)
{
// Hardcode the value of the size for the structure element
// as the C# compiler pads the structure to the closest 4 or 8 bytes
int cbSize = Marshal.ReadInt16 (waveHeader, 16);
byte [] ab = new byte [18 + cbSize];
Marshal.Copy (waveHeader, ab, 0, 18 + cbSize);
return ab;
}
static internal WAVEFORMATEX Default
{
get
{
WAVEFORMATEX wfx = new WAVEFORMATEX ();
wfx.wFormatTag = 1;
wfx.nChannels = 1;
wfx.nSamplesPerSec = 22050;
wfx.nAvgBytesPerSec = 44100;
wfx.nBlockAlign = 2;
wfx.wBitsPerSample = 16;
wfx.cbSize = 0;
return wfx;
}
}
internal int Length
{
get
{
return 18 + cbSize;
}
}
}
#endregion
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ByteConverter.cs
- DateTimeConverter.cs
- ExportOptions.cs
- PropertyPathConverter.cs
- BuildProvider.cs
- ThicknessAnimationUsingKeyFrames.cs
- DownloadProgressEventArgs.cs
- Int32Animation.cs
- Vector3DAnimationUsingKeyFrames.cs
- FieldNameLookup.cs
- GroupLabel.cs
- SecurityTokenRequirement.cs
- StoreItemCollection.Loader.cs
- RC2CryptoServiceProvider.cs
- NetMsmqBindingCollectionElement.cs
- RootCodeDomSerializer.cs
- InstanceLockQueryResult.cs
- ControlValuePropertyAttribute.cs
- HtmlAnchor.cs
- NameSpaceExtractor.cs
- DataControlCommands.cs
- PnrpPermission.cs
- FixedSOMTableCell.cs
- ParamArrayAttribute.cs
- FtpWebResponse.cs
- ConnectionPoint.cs
- StyleBamlRecordReader.cs
- RootDesignerSerializerAttribute.cs
- DuplicateWaitObjectException.cs
- UpdatePanelControlTrigger.cs
- PropertyPushdownHelper.cs
- TrackBar.cs
- DbParameterCollection.cs
- DriveNotFoundException.cs
- QuaternionIndependentAnimationStorage.cs
- AsnEncodedData.cs
- ChannelManagerHelpers.cs
- SectionUpdates.cs
- OdbcConnectionFactory.cs
- ViewCellSlot.cs
- CharEnumerator.cs
- ScriptDescriptor.cs
- DateTimeHelper.cs
- StylusLogic.cs
- SchemaNames.cs
- templategroup.cs
- CookielessData.cs
- DataListGeneralPage.cs
- WorkflowCommandExtensionItem.cs
- XmlEncodedRawTextWriter.cs
- DataContractSerializerServiceBehavior.cs
- WebScriptEnablingElement.cs
- ButtonBase.cs
- InlineCategoriesDocument.cs
- WebPartsSection.cs
- HttpHandlersSection.cs
- ObjectHandle.cs
- Int32Rect.cs
- UnsafePeerToPeerMethods.cs
- ControlIdConverter.cs
- PolicyStatement.cs
- TdsParserSafeHandles.cs
- PromptEventArgs.cs
- mediapermission.cs
- indexingfiltermarshaler.cs
- SqlColumnizer.cs
- RuleSetBrowserDialog.cs
- SortQuery.cs
- DesignerSerializerAttribute.cs
- ApplicationId.cs
- AndAlso.cs
- DataTableNewRowEvent.cs
- FrameworkContentElement.cs
- LZCodec.cs
- DataRow.cs
- XmlSchemaException.cs
- CodeNamespace.cs
- OleDbConnectionFactory.cs
- FatalException.cs
- LogExtent.cs
- SqlNotificationRequest.cs
- CodeBinaryOperatorExpression.cs
- IndexedEnumerable.cs
- TemplatePropertyEntry.cs
- DataKeyCollection.cs
- DependsOnAttribute.cs
- HostProtectionPermission.cs
- SourceElementsCollection.cs
- QueryParameter.cs
- FamilyTypefaceCollection.cs
- Soap12ProtocolImporter.cs
- UnsupportedPolicyOptionsException.cs
- UnicodeEncoding.cs
- EntityContainerAssociationSetEnd.cs
- HtmlTable.cs
- SignatureResourcePool.cs
- WsrmFault.cs
- MultiSelectRootGridEntry.cs
- ColorKeyFrameCollection.cs
- ParenthesizePropertyNameAttribute.cs