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
- FixedFlowMap.cs
- ConfigurationLocationCollection.cs
- EntityContainerEntitySet.cs
- XsltOutput.cs
- ObjectDataSource.cs
- RelatedCurrencyManager.cs
- WebConfigurationManager.cs
- MappingSource.cs
- AssemblyResolver.cs
- SmiXetterAccessMap.cs
- EmptyEnumerator.cs
- RectAnimationBase.cs
- AxHost.cs
- DirectoryGroupQuery.cs
- Symbol.cs
- StateMachineWorkflowDesigner.cs
- PreviousTrackingServiceAttribute.cs
- M3DUtil.cs
- OneOfConst.cs
- HttpListenerException.cs
- HtmlEncodedRawTextWriter.cs
- ProtocolsConfigurationHandler.cs
- DataRowChangeEvent.cs
- ArcSegment.cs
- DocumentOrderComparer.cs
- FragmentNavigationEventArgs.cs
- UnsettableComboBox.cs
- Transform.cs
- Events.cs
- XmlStrings.cs
- CodeIndexerExpression.cs
- UpdateTranslator.cs
- IndexedEnumerable.cs
- PropertyPushdownHelper.cs
- RankException.cs
- TransactionInterop.cs
- CodeDelegateInvokeExpression.cs
- SafeHandles.cs
- EventTrigger.cs
- AssemblyResourceLoader.cs
- IUnknownConstantAttribute.cs
- ToolStripProfessionalLowResolutionRenderer.cs
- BulletDecorator.cs
- ObjectDataSourceFilteringEventArgs.cs
- ButtonChrome.cs
- DataGridPreparingCellForEditEventArgs.cs
- ZoneButton.cs
- EntityContainerEmitter.cs
- TriState.cs
- DirectoryObjectSecurity.cs
- TypedElement.cs
- UserPersonalizationStateInfo.cs
- Tuple.cs
- AddInIpcChannel.cs
- ConstNode.cs
- TextElementEditingBehaviorAttribute.cs
- ThemeableAttribute.cs
- EntitySetBaseCollection.cs
- UriTemplateTableMatchCandidate.cs
- ReflectionServiceProvider.cs
- RevocationPoint.cs
- RepeaterItemEventArgs.cs
- CrossSiteScriptingValidation.cs
- UriSection.cs
- MetadataArtifactLoaderResource.cs
- UniqueIdentifierService.cs
- RequestQueue.cs
- ValueChangedEventManager.cs
- RawStylusInputReport.cs
- ListItemsPage.cs
- x509store.cs
- serverconfig.cs
- MetadataHelper.cs
- ClientScriptManagerWrapper.cs
- WorkflowPersistenceService.cs
- Message.cs
- InternalSafeNativeMethods.cs
- DataSourceProvider.cs
- QueryAccessibilityHelpEvent.cs
- ToolboxComponentsCreatedEventArgs.cs
- PropertyStore.cs
- OleDbEnumerator.cs
- BoundingRectTracker.cs
- CompilerLocalReference.cs
- SqlDelegatedTransaction.cs
- QilPatternFactory.cs
- WindowHideOrCloseTracker.cs
- QueuePathDialog.cs
- SessionIDManager.cs
- TakeOrSkipQueryOperator.cs
- DefaultValueAttribute.cs
- XmlBinaryReader.cs
- SQLMoneyStorage.cs
- KeyManager.cs
- EdmType.cs
- ToolStripSeparatorRenderEventArgs.cs
- GenericAuthenticationEventArgs.cs
- CacheAxisQuery.cs
- SocketAddress.cs
- PrimitiveRenderer.cs