Version 1.1
This collection of units contains useful classes for handling ACM compressed data.
Index
Enum EDSPCMChannels
Enum EDSPCMBitsPerSample
Enum EDSPCMStaticFrequency
Type TDSPCMDynamicFrequency
Class TDSWaveFormatProperty
Class TDSWaveFormatPCM
Class TDSWaveFormatPCMStatic
Class TDSWaveFormatPCMDynamic
Class TDSWaveFormatACMSet SDSACMFormatFilter
Set SDSACMSupport
Class TDSACMFormatChoose
Class TDSACMFormatDetails
Class TDSACMFormatTagDetails
Armin Sander, Digital SimpleX GmbH
- Many internal changes to TDSWaveFomat for better compatibility with ACM CODECs and the Win32 Wave model.
- Changed model for more secure asynchronous operations in TDSWaveStreamFactory.
- Added SDSACMSupport, TDSACMFormatDetails and TDSACMFormatTagDetails for driver supplied description strings.
- Some minor bug fixes (mostly driver compatibility fixes).
- TDSTStream now allows writes to the format property of TDSStream. Useful for processing raw data originating from a TStream (although it's currently not supported by the TDSWaveStreamFactory).
- Added some methods to TDSWaveFormat.
- Changed conversion login in TDSWaveStreamFactory. Should now do exactly what it is supposed to do:
- Removed a dead-locking bug (mainly occured if the BitsPerSample of source and suggested target-format were not equal ... thanks to John Mertus).
- If the given target-format is complete, the target conversion is now done directly (not anymore with only suggesting a driver based on the active TDSWaveFormat properties ... thanks to Hervé Couplet).
- Added the ability to process pre-formatted wave input and output streams to the TDSWaveStreamFactory.
This is the main unit for opening conversion streams.
To be extensible this is nothing else than a wrapper for the four most important methods of this library. All properties are optional and affect the method-calls.
Create
The constructor.
Reset
Resets all optional properties to their defaults. Useful for reusing a current instantiated factory for opening another stream.
OpenFileRead(const _fn : string) : TDSStream
Opens a file for reading. _fn is the filename. The result is a TDSStream with the ability to read from.
Returns nil if an error occured.OpenFileWrite(const _fn : string; _sourceformat : TDSFormat) : TDSStream
Opens a file for writing. _fn is the filename of the newly created file. _sourceformat is the data-format description you want to write in to the created TDSStream.
Returns nil if an error occured.OpenStreamRead(_xstream : TDSStream) : TDSStream
The same as OpenFileRead, but instead reading from a RIFF-WAVE file you delegate all reads to the given _xstream. _xstream has to contain RIFF-WAVE format data, or should have attached a TDSWaveStreamFormat to enable the processing of raw data.
Returns nil if an error occured.OpenStreamWrite(_xstream : TDSStream; _sourceformat : TDSFormat) : TDSStream
Same as OpenFileWrite but with a given stream as output stream.
Returns nil if an error occured.
TargetFormat : TDSWaveFormat (r/w)
Optional target format. If using OpenXXXRead without an TargetFormat, the stream resulted has the original format of the source (the file or the stream). If the TargetFormat property has been set, the factory creates a stream which matches the TargetFormat. Sometimes multiple combined streams are generated internally to match the wanted format.
The same happens with a call to OpenXXXWrite. If the TargetFormat has been set, the factory matches the output format of the file or stream to the TargetFormat.
default: unset
Realtime : Boolean (r/w)
Set this to true if you accept ACM conversions with lower quality and higher performance.
Useful for realtime streaming and playing.
default: false
Async : Boolean (r/w)
Use a thread-barrier with an integrated stream-FIFO to optimize reads and writes to the resulting stream. The buffer-size is defined by BufferMS.
Warning: If you use OpenStreamXXX calls the calls to the external streams are directly invoked from another thread.
default: false
BufferMS : Cardinal (r/w)
Reperesents the FIFO buffersize if using Async in milliseconds.
Enhanced intelligence warning: setting this value automatically sets Async to true.
default: 3000
Some helper methods to query file-formats without generating streams (of course internally they are mapped to the factories methods, but for your convenience).
QueryFileFormat(const _fn : string) : TDSWaveStreamFormat
Queries the format of the RIFF-WAVE file.
Returns nil if an error occurred.
QueryStreamFormat(_xstream : TDSStream) : TDSWaveStreamFormat
Queries the format of the RIFF-WAVE stream.
Queries the format only if the given TDSStream has no attached format description (TDSStream.Format).
Returns nil if an error occurred.
Base class for all formats used.
Warning: Although this is a TPersistent you won't get happy using persistence managing calls on this class. This is only to support Assign calls.
For readable/writeable properties see unit UDSWaveFormatProperties.
Covers the WAVEFORMATEX Win32 structure. But beware, the TDSWaveFormat could handle also a partly initialized state. For giving conversion hints instead of a complete format description.
Assign(_source : TPersistent)
You can assign here another TDSWaveFormat or a TDSWaveStreamFormat class.
IsComplete : Boolean
Results true if this is a complete wave-format. All necessary properties are available.MSToAvgBytes(_ms : Cardinal) : Cardinal
Computes the number of average bytes from the given milliseconds for the current wave-format.
Active properties will invalidate passive properties.
Format : Cardinal (r/w)
This is the current wave format tag as listed in mmreg.h include.Channels : Cardinal (r/w)
Number of channels.Frequency : Cardinal (r/w)
The frequency in Hz.BitsPerSample : Cardinal (r/w)
Bits per sample.
Passive Properties
Passive properties are read-only, because they can be computed automatically or queried from the ACM driver directly.
AvgBytesPerSec : Cardinal (r)
Average bytes per seconds. Represents only a precise value if the format is WAVE_FORMAT_PCM.BlockAlign : Cardinal (r)
Hmm, don't know why I document this here? If you see a sense in describing BlockAlign for users, please mail to armin@dsx.de.
FormatValid : Boolean (r)
Returns true if the Format property is valid.ChannelsValid : Boolean (r)
Returns true if the Channels property is valid.FrequencyValid : Boolean (r)
Returns true if the Frequency property is valid.BitsPerSampleValid : Boolean (r/w)
Returns true if the BitsPerSample property is valid.
Create : TDSWaveFormat
Creates a TDSWaveFormat instance with all properties set to unset.CreateDefault : TDSWaveFormat
Creates a default TDSWaveFormat class.
Currently default values are
WAVE_FORMAT_PCM,
22050hz,
1 channel,
16 bits per sample.
Please: don't rely on it.CreateByFrequencyChannels(_freq, _channels : Cardinal) : TDSWaveFormat
Creates a WAVE_FORMAT_PCM with 16 bit.CreateByFrequencyBitsChannels(_freq, _bits, _channels : Cardinal) : TDSWaveFormat
Creates a WAVE_FORMAT_PCM.
Covers the newly introduced WAVEFACT Win32 structure.
Create
Assign(_source : TPersistent)
Assign compatible are TDSWaveFact and TDSWaveStreamFormat.IsValid : Boolean
Sometimes (especially while realtime-recording), SampleLength can't be computed before closing the stream. In this case IsValid returns false.
SampleLength : Cardinal (r/w)
The length of the sample in bytes.
This class combines the TDSWaveFormat and TDSWaveFact class to one single format.
Create
Assign(_source : TPersistent)
Compatible to TDSWaveStreamFormat and TDSWaveFormat.
CreateByFormat(_format : TDSWaveFormat) : TDSWaveStreamFormat
Warning: resulting TDSWaveStreamFormat has an invalid Fact.
CreateByFormatFact(_format : TDSWaveFormat; _fact : TDSWaveFact) : TDSWaveStreamFormat
Format : TDSWaveFormat (r/w)
Fact : TDSWaveFact (r/w)
HasFact : Boolean (r)
Returns true if Fact is valid.
And now the published part (or visible one). The following classes are valueable if you want to create components offering the possibility to choose TDSWaveFormat settings.
possible channel-settings for WAVE_FORMAT_PCM
possible bit-settings for WAVE_FORMAT_PCM
possible frequencies for so called static (system recommended) WAVE_FORMAT_PCM formats.
dynamic frequency range to support DirectSound features.
Base class for all wave format properties.
Create
Format : TDSWaveFormat (r)
Returns the appropriate TDSWaveFormat instance.
Base class for all properties to choose a PCM format.
Channels : EDSPCMChannels (r/w)
BitsPerSample : EDSPCMBitsPerSample (r/w)
For static PCM formats (reduced frequency options).
Frequency : EDSPCMStaticFrequency (r/w)
For dynamic PCM formats (frequency rage 100..100000).
Frequency : TDSPCMDynamicFrequency (r/w)
Complete ACM choose possibilities. Represented with a format string only and a (...) in the object inspector popping up the system integrated wave-format choose requester.
Useful to restrict selection options. See TDSACMFormatChoose.
Set SDSACMSupport = (aftsAsync, aftsCodec, aftsConverter, aftsFilter, aftsHardware)
Support flags for the retrieved CODEC inforamtion. See TDSACMFormatDetails and TDSACMFormatTagDetails.
Helper class to choose an ACM format by using the system supplied requester. All properties are optional. But setting OwnerWindow is recommended.
Create
Choose : TDSWaveFormat
Pops up the system ACM format choose requester. Result is nil if no format has been selected.
OwnerWindow : HWND (w)
The owner-window of the requester. Use this property to avoid user-input to your application while the choose requester is open.
PreselectedFormat : TDSWaveFormat (w)
You can set this format to give the choose requester a hint what format should be preselected. If the format is currently not supported (the driver is not installed), the system matches to the next appropriate driver.
Title : string (w)
The title of the choose-requester. System-default is "Sound Selection".
Filter : SDSACMFormatFilter (w)
Set this to filter the possible formats.
FilterFormat : TDSWaveFormat (w)
In case of a acmffConvert or acmffSuggest filter you have to set the FilterFormat to restrict the number of selectable formats.
Only valid if Choose results <> nil.
FormatTag : string (r)
Name of the returned format.
FormatAttributes : string (r)
Attributes of the returned format.
Class TDSACMFormatDetails = class(TObject)
Information class for querying information about a given TDSWaveFormat.
Properties
Tag : DWORD (r)
The tag of the given format.Support : SDSACMSupport (r)
Support flags.Description : string (r)
The string description of the given format.
Class Methods
CreateByFormat(_format : TDSWaveFormat) : TDSACMFormatDetails
Creates the information structure by a given TDSWaveFormat.
Class TDSACMFormatTagDetails = class(TDSACMFormatDetails)
Information class for querying information about a given format tag.
Properties
MaxSize : DWORD (r)
The maximum size of a Win32 TWaveFormatEx structure used by this format.
Class Methods
CreateByTag(_tag : DWORD) : TDSACMFormatTagDetails;
Creates the information structure by a given format tag (like WAVE_FORMAT_PCM).
The base class for all streams. This class has no TStream is its base-class. Although I have initially designed it to base on TStream I have decided to move away for several reasons. As you can see (from the number of *.dcu) our library contains more than a simple ACM library. An own stream-base class was more straightforward than using TStream.
a) a simpler syntax for reading, writing and seeking.
b) a format-description for streams.
c) easier creation of combined, child, thread-safe and FIFO streams.
d) more fun.
Create
Read(const _area : RDSArea) : LongInt
Read to an RDSArea. Results the number of bytes read or -1 if an error occurred.
Write(const _area : RDSArea) : LongInt
Writes from an RDSArea. Results the number of bytes written or -1 if an error occurred.
Seek(const _seek : RDSSeek) : Boolean
Moves the current stream-pointer as described by RDSSeek. Returns false if an error occurred.
Size : LongInt (r)
The size of the stream in bytes.
Position : LongInt (r)
The current stream cursor position.
Format : TDSFormat (r/w)
The format of the stream.
New for 1.1: Some stream types allow writing to this property.
Stream : TStream (r)
An optional TStream representation of this TDSStream.
Warning: avoid usage.
Copy(_src : TDSStream; _dst : TDSStream) : Boolean
Copies all available data from the _src TDSStream to the _dst TDSStream. Returns true if successful.
TDSTStream is a simple class to map TStream object to TDSStream objects.
New for 1.1: the format property of TDSStream can be used to give the stream a format (a wave format!) to allow subsequent raw-processing.
Create(_stream : TStream)
An RDSArea is a range defined by a position or pointer and a length. Another description for RDSArea could be a one-dimensional vector. It's mainly used to describe ranges in memory or inside files.
length : Cardinal
pos : Cardinal or pt : PChar (union)
RDSArea_By : RDSArea
Constructs an RDSArea with 0/0.
RDSArea_ByPosLength(_pos : Cardinal; _length : Cardinal) : RDSArea
Constructs an RDSArea with pos = _pos and length = _length.
RDSArea_ByPosPos(_pos1 : Cardinal; _pos2 : Cardinal) : RDSArea
Returns an RDSArea with pos := _pos1 and length := _pos2-_pos1.
RDSArea_GetEndPos(const _self : RDSArea) : Cardinal
Returns pos + length.
RDSArea_HasBody(const _self : RDSArea) : Boolean
An RDSArea has a body if length > 0. In this case this function returns true.
RDSArea_RequireBody(const _self : RDSArea)
Raises a standard exception if _self has no body.
RDSArea_Intersection(const _self : RDSArea; const _right : RDSArea) : RDSArea
Returns the intersection of _self and _right.
RDSArea_Contains(const _self : RDSArea; const _right : RDSArea) : Boolean
Returns true if _right is contained in _self.
RDSArea_Intersects(const _self : RDSArea; const _right : RDSArea) : Boolean
Returns true if _self intersects with _right.
RDSArea_SeekBegin(var _self : RDSArea; _delta : LongInt)
Moves the beginning of the RDSArea by _delta.
RDSArea_SeekEnd(var _self : RDSArea; _delta : LongInt)
Moves the end of the RDSArea by _delta.
RDSSeek is the abstraction for seeking commands combining the two needed parameters into one record.
Used for TDSStream seek calls.
EDSSeekOrigin = (soBegin, soEnd, soCurrent)
delta : LongInt
origin : EDSSeekOrigin
RDSSeek_Begin(_delta : LongInt) : RDSSeek
Returns an RDSSeek from beginning.
RDSSeek_End(_delta : LongInt) : RDSSeek
Returns an RDSSeek from end.
RDSSeek_Current(_delta : LongInt) : RDSSeek
Returns an RDSSeek from current.
Memory handling gizmos.
Originally defined in UDSArea.RDSArea
RDSArea_ByPtLength(_pt : PChar; _length : Cardinal) : RDSArea
Returns an RDSArea with a Pt _pt and length _length.
RDSArea_ByPtPt(_pt1 : PChar; _pt2 : PChar) : RDSArea
Returns an RDSArea with Pt _pt1 and Length (_pt2-_pt1).
RDSArea_Allocate(_length : Cardinal) : RDSArea
Allocates an RDSArea using GetMem. If the allocation fails, the resulting RDSArea is empty (nil/0).
RDSArea_Free(var _self : RDSArea)
Frees the given previously allocated RDSArea.
RDSArea_Resize(var _self : RDSArea; _size : Cardinal)
Resizes the RDSArea. Warning: Not only the length of _self will be changed here, also the Pt gets modified.
RDSArea_GetPt(const _self : RDSArea) : PChar;
Retrieves the Pt of the RDSArea _self.
Warning: Don't use this Method, use _self.pt instead. May be this method will be removed in the next library update.RDSArea_GetEndPt(const _self : RDSArea) : PChar;
Computes the EndPt of the RDSArea _self (pt + length).
RDSArea_Zero(const _self : RDSArea);
Fills the complete RDSArea _self with zeros.RDSArea_Fill(const _self : RDSArea; _fill : byte);
Fills the complete RDSArea _self with the byte _fill.
TDSFileStream is the complementary class to TFileStream but based on TDSStream.
OpenRead(const _fn : string) : TDSFileStream
Returns a read-stream to a file.OpenWrite(const _fn : string) : TDSFileStream
Returns a write-stream to a file.
TDSMemoryStream is the complementary class to TMemoryStream but based on TDSStream. For documentation look at the TMemoryStream VCL help file.
Create
LoadFromFile(const _fn: string)
SaveToFile(const _fn: string)
LoadFromStream(_stream: TDSStream)
SaveToStream(_stream: TDSStream)
SetSize(_size : LongInt)
Clear
Memory : Pointer (r)
Area : RDSArea (r)