⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmdscptr.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{========================================================================}
{=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
{========================================================================}
{=                          All Rights Reserved                         =}
{========================================================================}
{=  D 01099 Dresden             = Fax.: +49 (0)351-8037944              =}
{=  Loewenstr.7a                = info@swiftsoft.de                     =}
{========================================================================}
{=  Actual versions on http://www.swiftsoft.de/mmtools.html             =}
{========================================================================}
{=  This code is for reference purposes only and may not be copied or   =}
{=  distributed in any format electronic or otherwise except one copy   =}
{=  for backup purposes.                                                =}
{=                                                                      =}
{=  No Delphi Component Kit or Component individually or in a collection=}
{=  subclassed or otherwise from the code in this unit, or associated   =}
{=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
{=  without express permission from SwiftSoft.                          =}
{=                                                                      =}
{=  For more licence informations please refer to the associated        =}
{=  HelpFile.                                                           =}
{========================================================================}
{=  $Date: 04.09.98 - 22:15:16 $                                        =}
{========================================================================}
unit MMDSCptr;

{$I COMPILER.INC}

{.$DEFINE _MMDEBUG}

interface

uses
  Windows,
  SysUtils,
  Messages,
  Classes,
  Controls,
  Dialogs,
  MMSystem,
  MMRegs,        { Should be after MMSystem }
  MMUtils,
  MMObj,
  MMDSPObj,
  MMOLE2,
  MMDSound,
  MMD3DTyp,
  MM3D,
  MMWave,
  MMPCMSup,
  MMACMDlg,
  MMWaveIO,
  MMDSMix
  {$IFDEF _MMDEBUG}
  ,MMDebug
  {$ENDIF}
  ;

const
  NOTIFICATIONTHREAD_TIMEOUT = INFINITE;

type
  EMMDSCaptureError = class(Exception);

  TMMDSCapture = class;
  TMMDSCaptureBuffer = class;

  {----------------------------------------------------------------------------}
  TMMDSCaptureBufferNotifyThread = class(TMMThreadEx)
  private
    FBuffer          : TMMDSCaptureBuffer;
    FSystemEvent,
    FBufferStopEvent : THandle;
    FSyncing         : Boolean;

    procedure DoBufferStop;

  protected
    procedure Execute; override;

  public
    constructor Create(ABuffer: TMMDSCaptureBuffer);
    destructor Destroy; override;
  end;

  {----------------------------------------------------------------------------}
  TMMDSCaptureBuffer = class(TMMObject)
  private
    FOwned           : Boolean;
    FCaptureBuffer   : IDirectSoundCaptureBuffer;
    FNotify          : IDirectSoundNotify;
    FCapture         : TMMDSCapture;
    FNotifyThread    : TMMDSCaptureBufferNotifyThread;
    FName            : string;
    FMemory          : TMemoryStream;
    FBufferLength    : Longint;
    FFormat          : PWaveFormatEx;
    FResetPosition   : Boolean;
    FCapturing       : Boolean;
    FBufferStopEvent : THandle;
    FOnBufferStop,
    FOnRelease       : TNotifyEvent;
    FCBOrigin,                      // Origin of capture buffer in the whole stream
    FCBSize,                        // buffer size
    FCBDataPosition  : Integer;     // bytes processed

    function  GetPosition: Longint;
    function  GetReadPosition: Longint;
    function  GetCapturing: Boolean;
    function  GetCaptureLength: Longint;
    procedure SetFormat(Value: PWaveFormatEx);
    function  GetCaps: TDSCBCAPS;
    procedure SetCaptureBuffer(Value: IDirectSoundCaptureBuffer);
    function  IsThereNewData: Boolean;

  protected
    procedure Capture;
    procedure Stop;
    procedure ReleaseBuffer;
    procedure FreeBuffer;
    procedure CopyData;
    property  DirectSoundCaptureBuffer: IDirectSoundCaptureBuffer read FCaptureBuffer write SetCaptureBuffer;
    property  DirectSoundNotify: IDirectSoundNotify read FNotify;

  public
    constructor Create(Size: Longint; Format: PWaveFormatEx); virtual;
    destructor  Destroy; override;

    property OnBufferStop: TNotifyEvent read FOnBufferStop write FOnBufferStop;
    property OnRelease: TNotifyEvent read FOnRelease write FOnRelease;

    property Caps: TDSCBCAPS read GetCaps;
    property Name: string read FName;
    property Memory: TMemoryStream read FMemory;
    property PWaveFormat: PWaveFormatEx read FFormat write SetFormat;
    property BufferLength: Longint read FBufferLength write FBufferLength;
    property CaptureLength: Longint read GetCaptureLength;
    property Capturing: Boolean read GetCapturing;
    property Position: Longint read GetPosition;
    property ResetPosition: Boolean read FResetPosition write FResetPosition;
  end;

  {----------------------------------------------------------------------------}
  TMMDSCaptureCaps = class(TMMObject)
  private
    FChannels: Integer;
    FFormats : Integer;

    function  GetHasFormat(Index: Integer): Boolean;
    procedure SetHasFormat(Index: Integer; Value: Boolean);
    procedure SetIntDummy(Value: Integer);

  protected
    procedure SetCaps(const Caps: TDSCCAPS);

  public
    property Formats: Integer read FFormats;

  published
    property Channels: Integer read FChannels write SetIntDummy;
    property Has11025Mono8bit: Boolean index 0 read GetHasFormat write SetHasFormat;
    property Has11025Mono16bit: Boolean index 1 read GetHasFormat write SetHasFormat;
    property Has11025Stereo8bit: Boolean index 2 read GetHasFormat write SetHasFormat;
    property Has11025Stereo16bit: Boolean index 3 read GetHasFormat write SetHasFormat;
    property Has22050Mono8bit: Boolean index 4 read GetHasFormat write SetHasFormat;
    property Has22050Mono16bit: Boolean index 5 read GetHasFormat write SetHasFormat;
    property Has22050Stereo8bit: Boolean index 6 read GetHasFormat write SetHasFormat;
    property Has22050Stereo16bit: Boolean index 7 read GetHasFormat write SetHasFormat;
    property Has44100Mono8bit: Boolean index 8 read GetHasFormat write SetHasFormat;
    property Has44100Mono16bit: Boolean index 9 read GetHasFormat write SetHasFormat;
    property Has44100Stereo8bit: Boolean index 10 read GetHasFormat write SetHasFormat;
    property Has44100Stereo16bit: Boolean index 11 read GetHasFormat write SetHasFormat;
  end;

  TMMDSBufferEvent = procedure(Sender: TObject; Buffer: TMMDSCaptureBuffer) of object;

  {----------------------------------------------------------------------------}
  TMMDSCapture = class(TMMNonVisualComponent)
  private
    DirectCapture   : IDirectSoundCapture;
    FDevices        : TList;
    FDeviceID       : TMMDeviceID;
    FProductName    : String;
    FBuffers        : TList;
    FCaps           : TMMDSCaptureCaps;
    FOnBufferStop   : TMMDSBufferEvent;

    procedure SetCaps(Value: TMMDSCaptureCaps);
    function  GetCaps: TMMDSCaptureCaps;
    function  GetNumDevs: integer;
    function  GetDevices(Index: integer): PDSDRIVERDESC;
    procedure SetDeviceID(DeviceID: TMMDeviceID);
    procedure SetProductName(const Value: String);
    function  GetBuffer(Index: integer): TMMDSCaptureBuffer;
    function  GetBufferName(const Name: string): TMMDSCaptureBuffer;
    function  GetBufferCount: integer;
    procedure SetupBuffer(var Name: string; Buffer: TMMDSCaptureBuffer);
    procedure ClearBuffer(Buffer: TMMDSCaptureBuffer);
    function  FindFreeName(const Name: String): String;
    function  GetOpened: Boolean;

  protected
    procedure BufferStop(Buffer: TMMDSCaptureBuffer); dynamic;

  public
    constructor Create(AOwner: TComponent); override;
    destructor  Destroy; override;

    procedure Open;
    procedure Close;

    function  AddBuffer(var Name: string; BufferLength: Longint; Format: PWaveFormatEx): TMMDSCaptureBuffer;
    procedure RemoveBuffer(Buffer: TMMDSCaptureBuffer);
    procedure CaptureBuffer(Buffer: TMMDSCaptureBuffer);
    procedure StopBuffer(Buffer: TMMDSCaptureBuffer);
    procedure UpdateData(Buffer: TMMDSCaptureBuffer);
    procedure FreeBuffers;

    property  Buffer[Index: integer]: TMMDSCaptureBuffer read GetBuffer;
    property  BufferByName[const Name: string]: TMMDSCaptureBuffer read GetBufferName;
    property  BufferCount: integer read GetBufferCount;
    property  NumDevs: integer read GetNumDevs;
    property  Devices[Index: integer]: PDSDRIVERDESC read GetDevices;

    property  Opened: Boolean read GetOpened;

  published
    property  OnBufferStop: TMMDSBufferEvent read FOnBufferStop write FOnBufferStop;

    property  CaptureCaps: TMMDSCaptureCaps read GetCaps write SetCaps;
    property  DeviceID: TMMDeviceID read FDeviceID write SetDeviceID default 0;
    property  ProductName: String read FProductName write SetProductName stored False;
  end;

  {----------------------------------------------------------------------------}
  TMMDSCaptureChannel = class(TMMDSPComponent)
  private
    FCaptureBuffer : TMMDSCaptureBuffer;
    FCapture       : TMMDSCapture;
    FOnCaptureStop : TNotifyEvent;

    function  GetInputFormat: string;
    procedure SetInputFormat(aValue: string);
    function  GetPosition: Longint;
    procedure SetReset(aValue: Boolean);
    function  GetReset: Boolean;
    function  GetCapturing: Boolean;
    function  GetBufferLength: Longint;
    procedure SetBufferLength(Value: Longint);
    function  GetCaptureLength: Longint;
    procedure BufferStop(Sender: TObject);

  protected
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    procedure SetPWaveFormat(aValue: PWaveFormatEx); override;
    procedure DefineProperties(Filer: TFiler); override;
    procedure ReadData(Stream: TStream); virtual;
    procedure WriteData(Stream: TStream); virtual;

  public
    constructor Create(AOwner: TComponent); override;
    destructor  Destroy; override;

    procedure GetVUMeter(var LeftValue, RightValue, BothValue: integer; Interval: integer);

    procedure SaveFormatInRegistry(RootKey: HKEY; Localkey, Field: string);
    procedure LoadFormatFromRegistry(RootKey: HKEY; Localkey, Field: string);

    function  SelectFormat: Boolean;
    procedure SetPCMFormat(Mode: TMMMode; Bits: TMMBits; SampleRate: Longint);

    procedure Reset;
    procedure Init;
    procedure Capture;
    procedure Stop;

    function SaveToRAWFile(FName: TFileName): Boolean;
    function SaveToWaveFile(FName: TFileName): Boolean;

    property PWaveFormat;
    property CaptureBuffer: TMMDSCaptureBuffer read FCaptureBuffer;

    property Position: Longint read GetPosition;
    property CaptureLength: Longint read GetCaptureLength;
    property Capturing: Boolean read GetCapturing;

  published
    property OnCaptureStop: TNotifyEvent read FOnCaptureStop write FOnCaptureStop;

    property CaptureObject: TMMDSCapture read FCapture write FCapture;
    property BufferLength: Longint read GetBufferLength write SetBufferLength;
    property InputFormat: string read GetInputFormat write SetInputFormat stored False;
    property ResetPosition: Boolean read GetReset write SetReset default True;
  end;

implementation

{$IFDEF DELPHI3} resourcestring{$ELSE} const {$ENDIF}
  SLockFailed = 'DirectSoundCaptureBuffer Lock failed';
  SCannotConvertWave = 'Unable to convert sound data';

procedure DSCheckAvailable;
begin
  if _WinNT3_ then
    raise EMMDSCaptureError.Create(LoadResStr(IDS_DSNOTSUPPORTED));
  if not LoadDSoundDLL then
    raise EMMDSCaptureError.Create(LoadResStr(IDS_DLLERROR) + ' DSOUND.DLL...');
end;

{== TMMDSCapture ==============================================================}
constructor TMMDSCapture.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  DSCheckAvailable;

  FBuffers := TList.Create;
  FCaps := TMMDSCaptureCaps.Create;

  FDevices := TList.Create;
  if Assigned(DirectSoundCaptureEnumerate) then
     DirectSoundCaptureEnumerate(DriverEnumerate, FDevices);

  SetDeviceID(0);

  ErrorCode := ComponentRegistered(InitCode, Self, ClassName);
  if (ErrorCode <> 0) then RegisterFailed(InitCode, Self , ClassName);
end;

{-- TMMDSCapture --------------------------------------------------------------}
destructor TMMDSCapture.Destroy;
begin
  Close;
  FCaps.Free;
  FBuffers.Free;
  FreeDriverList(FDevices);
  FDevices.Free;

  inherited Destroy;
end;

{-- TMMDSCapture --------------------------------------------------------------}
procedure TMMDSCapture.BufferStop(Buffer: TMMDSCaptureBuffer);
begin
   UpdateData(Buffer);
   if Assigned(FOnBufferStop) then FOnBufferStop(Self, Buffer);
   if Assigned(Buffer.FOnBufferStop) then Buffer.FOnBufferStop(Buffer);
end;

{-- TMMDSCapture --------------------------------------------------------------}
function TMMDSCapture.GetDevices(Index: integer): PDSDRIVERDESC;
begin
  Result := PDSDRIVERDESC(FDevices.Items[Index])
end;

{-- TMMDSCapture --------------------------------------------------------------}
procedure TMMDSCapture.SetProductName(const Value: String);
begin
end;

{-- TMMDSCapture --------------------------------------------------------------}
function TMMDSCapture.GetNumDevs: integer;
begin
  Result := FDevices.Count;
end;

{-- TMMDSCapture --------------------------------------------------------------}
procedure TMMDSCapture.SetDeviceID(DeviceID: TMMDeviceID);
begin
  if (DirectCapture <> nil) then
    raise EMMDSCaptureError.Create(LoadResStr(IDS_PROPERTYOPEN));

  if (NumDevs > 0) and (DeviceID >= 0) and (DeviceID < NumDevs) then
  begin
    GetCaps;
    FProductName := Devices[DeviceID]^.Description;
    FDeviceID := DeviceID;
  end
  else
  begin
    FProductName := LoadResStr(IDS_DSNODEVICE);
    FDeviceID := InvalidID;
  end;
end;

{-- TMMDSCapture --------------------------------------------------------------}
procedure TMMDSCapture.Open;
begin
  if LoadDSoundDLL and (DirectCapture = nil) then
  begin
    if (DeviceID = InvalidID) then
      raise EMMDSCaptureError.Create(LoadResStr(IDS_INVALIDDEVICEID));
    try
      DSCheck(DirectSoundCaptureCreate(Devices[FDeviceID]^.lpGUID, DirectCapture, nil));
    except
      Close;
      raise;
    end;
  end;
end;

{-- TMMDSCapture --------------------------------------------------------------}
function TMMDSCapture.GetOpened: Boolean;
begin
  Result := DirectCapture <> nil;
end;

{-- TMMDSCapture --------------------------------------------------------------}
procedure TMMDSCapture.Close;
begin
  FreeBuffers;
  if (DirectCapture <> nil) then

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -