📄 unavcide.pas
字号:
(*
----------------------------------------------
unaVcIDE.pas - VC 2.5 Pro VCL components
Voice Communicator components version 2.5 Pro
----------------------------------------------
This source code cannot be used without
proper permission granted to you as a private
person or an entity by the Lake of Soft, Ltd
Visit http://lakeofsoft.com/ for details.
Copyright (c) 2001, 2007 Lake of Soft, Ltd
All rights reserved
----------------------------------------------
created by:
Lake, 01 Jun 2002
modified by:
Lake, Jun-Dec 2002
Lake, Jan-Dec 2003
Lake, Jan-May 2004
Lake, May-Oct 2005
Lake, Mar 2007
----------------------------------------------
*)
{$I unaDef.inc}
{xx $DEFINE PACKET_DEBUG }
{xx $DEFINE PACKET_TCP_DELAY_EMULATE }
{xx $DEFINE UNAVCIDE_NO_SCRIPT_COMPONENT } // define to link without scriptor component
unit
unaVCIDE;
{DP:UNIT
Contains the following VC 2.5 Pro components and classes:
<IMG SRC="pix/vc25palette.gif" usemap="#vc25ide" ismap border="0" />
<map name="vc25ide">
<area shape="rect" coords="52,24,80,52" href="#class_TunavclWaveInDevice" alt="TunavclWaveInDevice" />
<area shape="rect" coords="81,24,109,52" href="#class_TunavclWaveOutDevice" alt="TunavclWaveOutDevice" />
<area shape="rect" coords="109,24,137,52" href="#class_TunavclWaveCodecDevice" alt="TunavclWaveCodecDevice" />
<area shape="rect" coords="137,24,165,52" href="#class_TunavclWaveRiff" alt="TunavclWaveRiff" />
<area shape="rect" coords="166,24,194,52" href="#class_TunavclWaveMixer" alt="TunavclWaveMixer" />
<area shape="rect" coords="194,24,222,52" href="#class_TunavclWaveResampler" alt="TunavclWaveResampler" />
<area shape="rect" coords="222,24,250,52" href="#class_TunavclIPOutStream" alt="TunavclIPOutStream" />
<area shape="rect" coords="250,24,278,52" href="#class_TunavclIPInStream" alt="TunavclIPInStream" />
<area shape="rect" coords="279,24,307,52" href="#class_TunavclIPBroadcastServer" alt="TunavclIPBroadcastServer" />
<area shape="rect" coords="307,24,335,52" href="#class_TunavclIPBroadcastClient" alt="TunavclIPBroadcastClient" />
<area shape="rect" coords="335,24,363,52" href="#class_TunavclScriptor" alt="TunavclScriptor" />
<area shape="default" href="#unit_unavcIDE" />
</map>
}
interface
uses
Windows, unaTypes, Math, SysUtils, MMSystem,
unaClasses, unaMsAcmApi, unaMsAcmClasses, unaWave, WinSock, unaSockets,
Classes;
// --------------------------------
// -- basic abstract component --
// --------------------------------
const
c_proxyDataArraySize = 40;
type
// -- ahead declarations --
unavclInOutPipe = class;
unavclInOutPipeClass = class of unavclInOutPipe;
{DP:METHOD
Data availability notification event.
}
unavclPipeDataEvent = procedure(sender: unavclInOutPipe; data: pointer; len: unsigned) of object;
{DP:METHOD
Before Format change notification event.
}
unavclPipeBeforeFormatChangeEvent = procedure(sender: unavclInOutPipe; provider: unavclInOutPipe; newFormat: pointer; len: unsigned; out allowFormatChange: bool) of object;
{DP:METHOD
After Format change notification event.
}
unavclPipeAfterFormatChangeEvent = procedure(sender: unavclInOutPipe; provider: unavclInOutPipe; newFormat: pointer; len: unsigned) of object;
//
// -- unavclInOutPipe --
//
{DP:CLASS
Base abstract class for all VCL components in VC set.
}
unavclInOutPipe = class(tComponent)
private
f_shouldActivate: bool;
f_isFormatProvider: bool;
f_autoActivate: bool;
f_enableDataProxy: bool;
//
f_activateState: int; // 0 - none
// +1 - setting active := true
// -1 - setting active := false
//
f_enableDP: bool;
//
f_dumpOutput: string;
f_dumpInput: string;
f_dumpOutputOK: bool;
f_dumpInputOK: bool;
//
f_inBytes: int64;
f_outBytes: int64;
f_options: unsigned;
//
f_dataAvail: unavclPipeDataEvent;
f_dataDSP: unavclPipeDataEvent;
//
f_afterFormatChange: unavclPipeAfterFormatChangeEvent;
f_beforeFormatChange: unavclPipeBeforeFormatChangeEvent;
//
f_formatCRC: unsigned;
//
f_consumers: unaObjectList;
f_providers: unaObjectList;
f_gate: unaInProcessGate;
f_dataProxyThread: unaThread;
//
procedure triggerDataAvailEvent(data: pointer; len: unsigned);
procedure triggerDataDSPEvent(data: pointer; len: unsigned);
//
function getActive(): bool;
procedure setActive(value: bool);
function doSetActive(value: bool; timeout: unsigned = 3000): bool;
//
function getConsumerOneAndOnly(): unavclInOutPipe;
function getProviderOneAndOnly(): unavclInOutPipe;
procedure setConsumerOneAndOnly(value: unavclInOutPipe);
function applyFormatOnConsumers(data: pointer; len: unsigned; restoreActiveState: bool; provider: unavclInOutPipe): bool;
//
procedure notifyConsumers(); // simply notify all consumers there is no more provider (self)
procedure notifyProviders(value: unavclInOutPipe);
function checkIfFormatProvider(restoreActiveState: bool): bool;
function checkIfAutoActivate(value: bool; timeout: unsigned = 10000): bool;
//
function _enter(timeout: unsigned {$IFDEF PACKET_DEBUG}; const entryPoint: string{$ENDIF}): bool;
procedure _leave({$IFDEF PACKET_DEBUG}const entryPoint: string{$ENDIF});
procedure setEnableDP(value: bool);
protected
// abstract functions
{DP:METHOD
Writes data into the pipe.
}
function doWrite(data: pointer; len: unsigned; provider: unavclInOutPipe = nil): int; virtual; abstract;
{DP:METHOD
Reads data from the pipe.
}
function doRead(data: pointer; len: unsigned): unsigned; virtual; abstract;
{DP:METHOD
Returns available data size in the pipe.
}
function getAvailableDataLen(index: int): unsigned; virtual; abstract;
{DP:METHOD
Opens the pipe.
}
function doOpen(): bool; virtual;
{DP:METHOD
Closes the pipe.
}
procedure doClose(); virtual;
{DP:METHOD
Returns true if component was activated.
}
function isActive(): bool; virtual; abstract;
{DP:METHOD
Restricts the execution of the pipe to one thread.
}
function doEnter(timeOut: unsigned = 1000): bool; virtual; abstract;
{DP:METHOD
Removes the restrictions on the execution of the pipe.
}
procedure doLeave(); virtual; abstract;
{DP:METHOD
Processes new data available from the pipe.
}
function onNewData(data: pointer; len: unsigned; provider: unavclInOutPipe = nil): bool; virtual;
{DP:METHOD
Applies new format of the stream to the pipe.
}
function applyFormat(data: pointer; len: unsigned; provider: unavclInOutPipe = nil; restoreActiveState: bool = false): bool; virtual;
{DP:METHOD
Fills the format of the pipe stream.
}
function getFormatExchangeData(out data: pointer): unsigned; virtual;
{DP:METHOD
}
function doGetPosition(): int64; virtual;
{DP:METHOD
}
procedure Notification(component: tComponent; operation: tOperation); override;
{DP:METHOD
Assigns new provider for the pipe. Only mixer can support more that one providers.
}
function doAddProvider(provider: unavclInOutPipe): bool; virtual;
{DP:METHOD
Removes one of pipe's providers.
}
procedure doRemoveProvider(provider: unavclInOutPipe); virtual;
{DP:METHOD
Adds new consumer for the pipe. Only one consumer is currently supported.
}
function doAddConsumer(consumer: unavclInOutPipe; forceNewFormat: bool = true): bool; virtual;
{DP:METHOD
Removes consumer from the pipe.
}
procedure doRemoveConsumer(consumer: unavclInOutPipe); virtual;
//
procedure doSetEnableDP(value: bool); virtual;
{DP:METHOD
Usually creates an internal device of the pipe, and activates the component if needed.
}
procedure Loaded(); override;
public
{DP:METHOD
Creates a pipe.
}
procedure AfterConstruction(); override;
procedure BeforeDestruction(); override;
{DP:METHOD
Enters the pipe one-thread execution mode.
}
function enter(timeOut: unsigned = 1000): bool;
{DP:METHOD
Leaves the pipe one-thread execution mode.
}
procedure leave();
{DP:METHOD
Writes data into the pipe.
}
function write(data: pointer; len: unsigned; provider: unavclInOutPipe = nil): int; overload;
{DP:METHOD
Writes data into the pipe.
}
function write(const data: string; provider: unavclInOutPipe = nil): unsigned; overload;
{DP:METHOD
If you did not specify the consumer for component, you must call read() method periodically to access the stream data.
Best place to do that is onDataAvailable() event handler.
}
function read(data: pointer; len: unsigned): unsigned; overload;
{DP:METHOD
Reads data as a string.
}
function read(): string; overload;
{DP:METHOD
Opens the pipe.
}
function open(): bool;
{DP:METHOD
Closes the pipe.
}
procedure close(timeout: int = 0);
//
{DP:METHOD
Assigns new provider for the pipe. Only mixer can support more that one providers.
}
function addProvider(provider: unavclInOutPipe): bool;
{DP:METHOD
Removes one of pipe's providers.
}
procedure removeProvider(provider: unavclInOutPipe);
{DP:METHOD
Adds new consumer for the pipe. Only one consumer is currently supported.
}
function addConsumer(consumer: unavclInOutPipe; forceNewFormat: bool = true): bool;
{DP:METHOD
Removes consumer from the pipe.
}
procedure removeConsumer(consumer: unavclInOutPipe);
{DP:METHOD
Returns consumer of a pipe.
}
function getConsumer(index: unsigned = 0): unavclInOutPipe;
{DP:METHOD
Returns provider of a pipe.
}
function getProvider(index: unsigned = 0): unavclInOutPipe;
{DP:METHOD
Returns number of consumers.
}
function getConsumerCount(): unsigned;
{DP:METHOD
Returns number of providers.
}
function getProviderCount(): unsigned;
{DP:METHOD
Returns index of specified consumer.
}
function getConsumerIndex(value: unavclInOutPipe): int;
{DP:METHOD
Returns index of specified provider.
}
function getProviderIndex(value: unavclInOutPipe): int;
{DP:METHOD
Returns current position for stream.
}
function getPosition(): int64;
{DP:METHOD
Forces component to assign a format to consumers. Call this method before activation.
}
procedure clearFormatCRC();
//
// -- PROPERTIES --
//
{DP:METHOD
Returns data written into but not yet processed by the pipe.
}
property availableDataLenIn: unsigned index 0 read getAvailableDataLen;
{DP:METHOD
Returns data size available to read from the pipe.
}
property availableDataLenOut: unsigned index 1 read getAvailableDataLen;
{DP:METHOD
Number of bytes received by the pipe.
}
property inBytes: int64 read f_inBytes;
{DP:METHOD
Number of bytes produced by the pipe.
}
property outBytes: int64 read f_outBytes;
{DP:METHOD
Specifies whether the component would perform any data processing.
}
property enableDataProcessing: bool read f_enableDP write setEnableDP default True;
{DP:METHOD
Current position in stream.
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -