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

📄 u_vcloopback_main.pas

📁 Voice Commnucation Components for Delphi
💻 PAS
字号:

(*
	----------------------------------------------

	  u_vcLoopback_Main.pas - loopback demo application main form
	  Voice Communicator components version 2.5 Pro

	----------------------------------------------
	  This source code cannot be used without
	  proper license granted to you as a private
	  person or an entity by the Lake of Soft, Ltd

	  Visit http://lakeofsoft.com/ for more information.

	  Copyright (c) 2001, 2007 Lake of Soft, Ltd
		     All rights reserved
	----------------------------------------------

	  created by:
		Lake, 10 Jun 2002

	  modified by:
		Lake, Jun-Aug 2002
		Lake, Feb-May 2003
		Lake, Jan 2004
		Lake, Oct 2005
		Lake, Feb-Apr 2007

	----------------------------------------------
*)

{$I unaDef.inc}

{$DEFINE VC_LB_TWEAKS }		// enable chunk size tweaking code

{xx $DEFINE VC_USE_DSPLIB_IN_DLL }	// use DSPLib from DLL rather than linked into code

unit
  u_vcLoopback_Main;

interface

uses
  Windows, unaTypes, MMSystem, unaClasses,
{$IFDEF VC_USE_DSPLIB_IN_DLL }
  unaDspDLL,
{$ELSE }
  unaDspDLib,
{$ENDIF }
  unaDspLibH, unaDspLibAutomation,
  Classes, Controls, ComCtrls, Forms, unavcIDE, StdCtrls, ExtCtrls,
  ActnList, CheckLst;

type
  Tc_form_main = class(TForm)
    waveIn: TunavclWaveInDevice;
    waveOut: TunavclWaveOutDevice;
    c_statusBar_main: TStatusBar;
    c_timer_update: TTimer;
    codecIn: TunavclWaveCodecDevice;
    codecOut: TunavclWaveCodecDevice;
    c_label_inBytes: TLabel;
    c_label_outBytes: TLabel;
    c_label_inBuffSize: TLabel;
    c_label_latency: TLabel;
    c_label_outBuffSize: TLabel;
    c_button_config: TButton;
    c_button_start: TButton;
    c_button_stop: TButton;
    c_actionList_main: TActionList;
    a_start: TAction;
    a_stop: TAction;
    a_config: TAction;
    Bevel1: TBevel;
    Bevel2: TBevel;
    c_label_codec: TLabel;
    c_pb_left: TProgressBar;
    c_pb_right: TProgressBar;
    c_checkListBox_main: TCheckListBox;
    c_label_format: TLabel;
    c_comboBox_cps: TComboBox;
    Label1: TLabel;
    c_label_chunkSize: TLabel;
    Bevel3: TBevel;
    Bevel4: TBevel;
    c_timer_qUpdate: TTimer;
    c_button_filters: TButton;
    //
    procedure formCreate(sender: tObject);
    procedure formShow(sender: tObject);
    procedure formDestroy(sender: tObject);
    procedure formCloseQuery(sender: tObject; var canClose: boolean);
    //
    procedure a_startExecute(Sender: TObject);
    procedure a_stopExecute(Sender: TObject);
    procedure a_configExecute(Sender: TObject);
    //
    procedure c_timer_updateTimer(sender: tObject);
    procedure c_comboBox_cpsChange(Sender: TObject);
    procedure c_timer_qUpdateTimer(Sender: TObject);
    procedure waveInDataDSP(sender: unavclInOutPipe; data: pointer; len: cardinal);
    procedure c_button_filtersClick(sender: tObject);
  private
    { Private declarations }
    f_config: unaIniFile;
    f_sampleSize: unsigned;
    //
{$IFDEF VC_USE_DSPLIB_IN_DLL }
    f_dspRoot: unaDspDLLRoot;
{$ELSE }
    f_dspRoot: unaDspDLibRoot;
{$ENDIF }
    f_dspAutomat: unaDSPLibAutomat;
    //
    procedure applyFormat();
  public
    { Public declarations }
  end;

var
  c_form_main: Tc_form_main;


implementation


uses
  unaUtils, unaVCLUtils, unaWave, unaMsAcmClasses,
  u_common_audioConfig, u_common_dsplFilters;


{$R *.dfm}

// --  --
procedure Tc_form_main.applyFormat();
begin
  a_stop.execute();
  //
  c_label_format.caption := waveIn.waveInDevice.dstFormatInfo + ' -> ';
  case (codecIn.driverMode) of

    unacdm_acm:
      c_label_format.caption := c_label_format.caption + codecIn.codec.dstFormatInfo;

    unacdm_openH323plugin:
      c_label_format.caption := c_label_format.caption + codecIn.driverLibrary;

  end;    
end;

// --  --
procedure Tc_form_main.formCreate(sender: tObject);
begin
  f_config := unaIniFile.create();
  //
{$IFDEF VC_USE_DSPLIB_IN_DLL }
  f_dspRoot := unaDspDLLRoot.create();
{$ELSE }
  f_dspRoot := unaDspDLibRoot.create();
{$ENDIF }
  //
  f_dspAutomat := unaDSPLibAutomat.create(f_dspRoot);
  f_dspAutomat.automatLoad(f_config);
end;

// --  --
procedure Tc_form_main.formShow(sender: tObject);
begin
  loadControlPosition(self, f_config);
  //
{$IFDEF DEBUG }
  c_checkListBox_main.visible := true;
{$ENDIF}

{$IFDEF VC_LB_TWEAKS }
  c_comboBox_cps.itemIndex := f_config.get('cps.index', int(2));
{$ELSE }
  c_comboBox_cps.itemIndex := 2;
  c_comboBox_cps.enabled := false;
{$ENDIF }
  c_comboBox_cpsChange(c_comboBox_cps);
  //
  c_form_common_audioConfig.setupUI(true, false, false);
  c_form_common_audioConfig.doLoadConfig(waveIn, waveOut, codecIn, nil, f_config);
  //
  applyFormat();
  //
  c_timer_update.enabled := true;
  c_timer_qUpdate.enabled := true;
end;

// --  --
procedure Tc_form_main.formDestroy(sender: tObject);
begin
  a_stop.execute();
  //
  freeAndNil(f_dspAutomat);
  freeAndNil(f_dspRoot);
  //
  freeAndNil(f_config);
end;

// --  --
procedure Tc_form_main.formCloseQuery(sender: tObject; var canClose: boolean);
begin
  c_timer_update.enabled := false;
  c_timer_qupdate.enabled := false;
  //
  f_config.setValue('cps.index', c_comboBox_cps.itemIndex);
  //
  saveControlPosition(self, f_config);
  f_dspAutomat.automatSave(f_config);
end;

// --  --
procedure Tc_form_main.c_timer_updateTimer(Sender: TObject);
var
  latency: int64;
begin
  if (not (csDestroying in componentState)) then begin
    //
    a_start.enabled := not waveIn.active;
    a_stop.enabled := not a_start.enabled;
    a_config.enabled := a_start.enabled;
    c_comboBox_cps.enabled := a_config.enabled;
    //
    if (waveIn.active) then
      latency := ((waveIn.getPosition() - waveOut.getPosition() - (waveOut.device.inOverloadTotal div f_sampleSize)) * 1000) div waveIn.pcm_SamplesPerSec 
    else
      latency := 0;
    //
    c_statusBar_main.panels[0].text := int2str(ams() shr 10, 10, 3) + ' KB ';
    //
    c_label_inBytes.caption     := 'WaveIn Position   : ' + int2Str(waveIn.getPosition(), 10, 3);
    c_label_outBytes.caption    := 'WaveOut Position  : ' + int2Str(waveOut.getPosition(), 10, 3);
    //
    c_label_inBuffSize.caption  := 'Playback Chunks   : ' + int2Str(waveOut.waveOutDevice.inProgress);
    c_label_outBuffSize.caption := 'Playback Buffer   : ' + int2Str(waveOut.waveOutDevice.getDataAvailable(true));
    c_label_codec.caption       := 'Compression Ratio : ' + int2Str(100 - percent(codecIn.outBytes, codecIn.inBytes)) + '%';
    //
    c_label_latency.caption     := 'Loopback Latency  : ' + int2str(latency) + ' ms';
    //
 {$IFDEF DEBUG }
    c_checkListBox_main.checked[0] := waveIn.active;
    c_checkListBox_main.checked[1] := codecIn.active;
    c_checkListBox_main.checked[2] := codecOut.active;
    c_checkListBox_main.checked[3] := waveOut.active;
 {$ENDIF}
    //
  end;
end;

// --  --
procedure Tc_form_main.a_startExecute(Sender: TObject);
{$IFDEF VC_LB_TWEAKS }
var
  pcm: unsigned;
  newValue: unsigned;
{$ENDIF}
begin
{$IFDEF VC_LB_TWEAKS }
  newValue := str2intInt(c_comboBox_cps.text, c_defChunksPerSecond);
  if (newValue <> c_defChunksPerSecond) then begin
    // tweaking code
    pcm := waveIn.pcm_samplesPerSec;
    //
    // need this to ensure new CPS value will be used
    //
    waveIn.pcm_samplesPerSec := 36000;	// any non-standard value is OK
    waveOut.pcm_samplesPerSec := 36000;
    codecOut.pcm_samplesPerSec := 36000;
    codecIn.pcm_samplesPerSec := 36000;
    //
    c_defChunksPerSecond := newValue;
    c_defPlaybackChunksAheadNumber := 2;
    c_def_max_playbackChunksAheadNumber := 3;
    //
    // restore proper value
    waveIn.pcm_samplesPerSec := pcm;
    waveOut.pcm_samplesPerSec := pcm;
    codecOut.pcm_samplesPerSec := pcm;
    codecIn.pcm_samplesPerSec := pcm;
  end;
{$ENDIF }
  //
  f_dspAutomat.setFormat(waveIn.pcm_samplesPerSec, waveIn.pcm_bitsPerSample, waveIn.pcm_numChannels);
  //
  if (WAVE_FORMAT_PCM = codecIn.formatTag) then
    waveIn.consumer := waveOut
  else
    waveIn.consumer := codecIn;
  //
  waveIn.open();
  //
 {$IFDEF DEBUG }
    c_checkListBox_main.items[0] := 'waveIn - ' + int2str(waveIn.waveInDevice.chunkPerSecond);
    c_checkListBox_main.items[1] := 'codecIn - ' + int2str(codecIn.codec.chunkPerSecond);
    c_checkListBox_main.items[2] := 'codecOut - ' + int2str(codecOut.codec.chunkPerSecond);
    c_checkListBox_main.items[3] := 'waveOut - ' + int2str(waveOut.waveOutDevice.chunkPerSecond);
 {$ENDIF}
  //
  f_sampleSize := waveOut.pcm_bitsPerSample shr 3 * waveOut.pcm_numChannels;
  if (1 > f_sampleSize) then
    f_sampleSize := 1;
  //  
  c_label_chunkSize.caption := 'Chunk Size: ' + int2str(1000 div newValue) + ' ms. (' + int2str(codecIn.codec.chunkSize) + ' -> '+ int2str(codecIn.codec.dstChunkSize) + ')';
end;

// --  --
procedure Tc_form_main.a_stopExecute(Sender: TObject);
begin
  waveIn.close();
end;

// --  --
procedure Tc_form_main.a_configExecute(Sender: TObject);
begin
  if (windows.succeeded(c_form_common_audioConfig.doConfig(waveIn, waveOut, codecIn, nil, f_config))) then
    applyFormat()
end;

// --  --
procedure Tc_form_main.c_comboBox_cpsChange(Sender: TObject);
var
  newValue: unsigned;
begin
  newValue := str2intInt(c_comboBox_cps.text, c_defChunksPerSecond);
  c_label_chunkSize.caption := 'Chunk Size: ' + int2str(1000 div newValue) + ' ms. (' + int2str(codecIn.codec.dstChunkSize) + ' -> '+ int2str(codecIn.codec.dstChunkSize) + ')';
end;

// --  --
procedure Tc_form_main.c_timer_qUpdateTimer(Sender: TObject);
begin
  c_pb_left.position  := int(waveGetLogVolume(waveOut.waveOutDevice.getVolume(0)));
  c_pb_right.position := int(waveGetLogVolume(waveOut.waveOutDevice.getVolume(1)));
end;

// --  --
procedure Tc_form_main.waveInDataDSP(sender: unavclInOutPipe; data: pointer; len: cardinal);
begin
  // process data with DSP filters
  if (nil <> f_dspAutomat) then
    f_dspAutomat.processChunk(data, len);
end;

// --  --
procedure Tc_form_main.c_button_filtersClick(sender: tObject);
var
  config: string;
begin
  // manage filters
  f_dspAutomat.automatSave(config);
  //
  if (c_from_dspFilters.configureFilters(f_dspRoot, config)) then
    f_dspAutomat.automatLoad(config);
end;


end.

⌨️ 快捷键说明

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