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

📄 unadspdlib.pas

📁 Voice Commnucation Components for Delphi
💻 PAS
📖 第 1 页 / 共 5 页
字号:

(*

	  DSPDLib
	----------------------------------------------
	  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) 2006, 2007 Lake of Soft, Ltd
		     All rights reserved
	----------------------------------------------

	  created by:
		DSP Lib team, Jun-Aug 2006
		
	  modified by:
		Lake, Mar-Apr 2007

	----------------------------------------------

*)


{$i unaDef.inc }

unit
  unaDSPDlib;

{DP:UNIT
  General purpose DSP library in native Delphi code. 
}

interface

uses
  Windows, unaTypes, unaDSPLibH, unaClasses;

const
  //
  DSPL_P_TYPE_I = $01000000;	// must not overlap with DSPL_PID and other parameter IDs !!
  DSPL_P_TYPE_F = $02000000;
  DSPL_P_TYPE_C = $03000000;

type
  //
  // --  --
  //
  punaDspDLibParam = ^unaDspDLibParam;
  unaDspDLibParam = packed record
    //
    r_id: dspl_id;
    //
    case int of

      0: (r0_int: dspl_int);
      1: (r1_float: dspl_float);
      2: (r2_chunk: dspl_chunk);

  end;

  // --  --
  unaDspDProcessor = class;

  {DP:CLASS
    This class contains general DSP Lib parameter.
  }
  unaDspDLibParams = class(unaIdList)
  private
    f_processor: unaDspDProcessor;
  protected
    procedure releaseItem(index: unsigned; doFree: unsigned); override;
    function getId(item: pointer): int64; override;
  public
    constructor create(processor: unaDspDProcessor);
  end;


  {DP:CLASS
    This class implements a basic DSP Lib root. It uses methods of unaDspDProcessor class for implementation.
  }
  unaDspDLibRoot = class(unaDspLibAbstract)
  protected
    function dspl_create(object_id: dspl_id): dspl_handle; override;
    function dspl_destroy(handle: dspl_handle): dspl_result; override;
    function dspl_process(handle: dspl_handle; nSamples: dspl_int): dspl_result; override;
    function dspl_version(): pAnsiChar; override;
    //
    function dspl_setf(handle: dspl_handle; param_id: dspl_id; value: dspl_float): dspl_result; override;
    function dspl_seti(handle: dspl_handle; param_id: dspl_id; value: dspl_int): dspl_result; override;
    function dspl_setc(handle: dspl_handle; param_id: dspl_id; chunk: pdspl_float; length: dspl_int): dspl_result; override;
    //
    function dspl_geti(handle: dspl_handle; param: dspl_id): dspl_int; override;
    function dspl_getf(handle: dspl_handle; param: dspl_id): dspl_float; override;
    function dspl_getc(handle: dspl_handle; param: dspl_id): pdspl_chunk; override;
    //
    function dspl_getID(handle: dspl_handle): dspl_int; override;
    //
    function dspl_isseti(handle: dspl_handle; param: dspl_id): dspl_result; override;
    function dspl_issetf(handle: dspl_handle; param: dspl_id): dspl_result; override;
    function dspl_issetc(handle: dspl_handle; param: dspl_id): dspl_result; override;
  public
    constructor create();
  end;


  {DP:CLASS
    This is general purpose DSP Lib processor.
  }
  unaDspDProcessor = class (unaObject)
  private
    f_id: dspl_id;
    f_params: unaDspDLibParams;
  protected
    {$IFDEF DEBUG }
    f_nameFull: string;
    f_nameShort: string;
    {$ENDIF }
    f_modified: bool;
    //
    function process(nSamples: dspl_int): dspl_result; virtual; abstract;
    function idIsINOUT(id: dspl_id): bool;
  public
    {DP:METHOD
      Creates a DSP Lib processor. ID could be one of the following:
      <UL>
	<LI>(DSPL_OID or DSPL_EQ2B): creates EQ Two Band processor.</LI>
	<LI>(DSPL_OID or DSPL_EQMB): creates EQ Multi-Band processor.</LI>
	<LI>(DSPL_OID or DSPL_LD): creates Level Detector processor.</LI>
	<LI>(DSPL_OID or DSPL_DYNPROC): creates Dynamic Processor.</LI>
	<LI>(DSPL_OID or DSPL_SPEECHPROC): creates Speech Processor.</LI>
	<LI>(DSPL_OID or DSPL_ND): creates Noise Detection processor.</LI>
	<LI>(DSPL_OID or DSPL_MBSP): creates Multi-band Splitter processor.</LI>
      </UL>
    }
    constructor create(id: dspl_id);
    procedure AfterConstruction(); override;
    procedure BeforeDestruction(); override;
    //
    {DP:METHOD
      Sets integer parameter. Parameter ID and value meaning depends on processor type.
    }
    function seti(param_id: dspl_id; value: dspl_int): dspl_result;
    {DP:METHOD
      Sets float parameter. Parameter ID and value meaning depends on processor type.
    }
    function setf(param_id: dspl_id; value: dspl_float): dspl_result;
    {DP:METHOD
      Sets array parameter. Parameter ID and value meaning depends on processor type.
    }
    function setc(param_id: dspl_id; chunk: pdspl_float; length: dspl_int): dspl_result;
    //
    {DP:METHOD
      Returns integer parameter. Parameter ID and value meaning depends on processor type.
    }
    function geti(param_id: dspl_id): dspl_int;
    {DP:METHOD
      Returns float parameter. Parameter ID and value meaning depends on processor type.
    }
    function getf(param_id: dspl_id): dspl_float;
    {DP:METHOD
      Returns array parameter. Parameter ID and value meaning depends on processor type.
    }
    function getc(param_id: dspl_id): pdspl_chunk;
    //
    {DP:METHOD
      Returns true if specified integer parameter is set.
    }
    function isseti(param_id: dspl_id): dspl_result;
    {DP:METHOD
      Returns true if specified float parameter is set.
    }
    function issetf(param_id: dspl_id): dspl_result;
    {DP:METHOD
      Returns true if specified array parameter is set.
    }
    function issetc(param_id: dspl_id): dspl_result;
    //
    {DP:METHOD
      Returns processor's ID.
    }
    property id: dspl_id read f_id;
    //
    {$IFDEF DEBUG }
    property nameFull: string read f_nameFull;
    property nameShort: string read f_nameShort;
    {$ENDIF }
  end;


  {DP:CLASS
    Two Band Parametric Equalizer
  }
  unaDspDL_EQ2B = class(unaDspDProcessor)
  private
    f1in1, f1in2, f1out1, f1out2,
    f2in1, f2in2, f2out1, f2out2: dspl_float;
    //
    biq_f1: pdspl_biq_values;
    biq_f2: pdspl_biq_values;
    biq_f1_buff_size: dspl_int;
    biq_f2_buff_size: dspl_int;
    //
    function prepare_biq(band, len: dspl_int; var step: dspl_int; buf: pdspl_biq_values; var buff_size: dspl_int): pdspl_biq_values;
  protected
    function process(nSamples: dspl_int): dspl_result; override;
  public
    constructor create();
    procedure AfterConstruction(); override;
    procedure BeforeDestruction(); override;
  end;


  {DP:CLASS
    Multiband Equalizer/Filter
  }
  unaDspDL_EQMB = class(unaDspDProcessor)
  private
    //
    num_filtres: dspl_int;
    hpfs: pdspl_biq_valuesArray;
    acc,   bcc: pFloatArray;
    zin1,  zin2,
    zout1, zout2: pFloatArray;
    //
    buffer_length: dspl_int;
  protected
    function process(nSamples: dspl_int): dspl_result; override;
  public
    constructor create();
    procedure AfterConstruction(); override;
    procedure BeforeDestruction(); override;
  end;


  {DP:CLASS
    Level Detector
  }
  unaDspDL_LD = class(unaDspDProcessor)
  private
    peak_buffer: pDoubleArray;
    //
    peak_value,
    alpha,
    beta: dspl_double;
    //
    ld_out: dspl_double;
    peak_pos: dspl_int;
    pb_pos: dspl_int;
    pb_size: dspl_int;
    //
    ld_peak: bool;
  protected
    function process(nSamples: dspl_int): dspl_result; override;
  public
    constructor create();
    procedure AfterConstruction(); override;
    procedure BeforeDestruction(); override;
  end;


  {DP:CLASS
    Multiband Splitter
  }
  unaDspDL_MbSp = class(unaDspDProcessor)
  private
    num_bands: dspl_int;
    num_filtres: dspl_int;
    hi_order: dspl_int;
    hpfs: pdspl_biq_valuesArray;
    //
    mout: pFloatArrayPArray;
    acc: pFloatArray;
    bcc: pFloatArray;
    gain_ref: dspl_float;
    zin1,  zin2,  zout1,  zout2:  pFloatArray;
    z2in1, z2in2, z2out1, z2out2: pFloatArray;
    //
    buffer_length: dspl_int;
  protected
    function process(nSamples: dspl_int): dspl_result; override;
  public
    constructor create();
    procedure AfterConstruction(); override;
    procedure BeforeDestruction(); override;
  end;


  {DP:CLASS
    Noise Level Detector
  }
  unaDspDL_ND = class(unaDspDProcessor)
  private
    bp: unaDspDL_EQ2B;
    bl: unaDspDL_LD;
    sl: unaDspDL_LD;
    pl: unaDspDL_LD;
    //
    bl_buf: pdspl_float;
    sl_buf: pdspl_float;
    bp_buf: pdspl_float;
    pl_buf: pdspl_float;
    //
    lr: dspl_float;
    sensivity: dspl_float;
    noise_level: dspl_float;
    dr: dspl_float;
    smoothing: dspl_float;
    //
    buffer_length: dspl_int;
  protected
    function process(nSamples: dspl_int): dspl_result; override;
  public
    constructor create();
    procedure AfterConstruction(); override;
    procedure BeforeDestruction(); override;
  end;


  {DP:CLASS
    Dynamic Processor
  }
  unaDspDL_DynProc = class(unaDspDProcessor)
  private
    level_detector: unaDspDL_LD;
    //
    ld_buffer: pdspl_float;
    ld_buffer_size: dspl_int;
    //
    alpha, beta, th,
    aratio_inv, bratio_inv, ascale, bscale,
    gain_env, gr_env: dspl_double;
    //
    nsot: dspl_int;
  protected
    function process(nSamples: dspl_int): dspl_result; override;
  public
    constructor create();
    procedure AfterConstruction(); override;
    procedure BeforeDestruction(); override;
  end;


  {DP:CLASS
    Speech Processor
  }
  unaDspDL_SpeechProc = class(unaDspDProcessor)
  private
    hp: unaDspDL_EQ2B;
    enh: unaDspDL_EQ2B;
    //
    agc: unaDspDL_DynProc;
    comp: unaDspDL_DynProc;
    ng: unaDspDL_DynProc;
    lim: unaDspDL_DynProc;
    ds: unaDspDL_DynProc;
    //
    acca: pdspl_float;
    accb: pdspl_float;
    hp_out: pdspl_float;
    la_buf: pdspl_float;
    la_in: pdspl_float;
    //
    buffer_length: dspl_int;
    la_size: dspl_int;
    la_pos: dspl_int;
  protected
    function process(nSamples: dspl_int): dspl_result; override;
  public
    constructor create();
    procedure AfterConstruction(); override;
    procedure BeforeDestruction(); override;
  end;


implementation


uses
  Math, unaUtils;


{ unaDspDLibParams }

// --  --
constructor unaDspDLibParams.create(processor: unaDspDProcessor);
begin
  f_processor := processor;
  //
  inherited create(false);
  //
  autoFree := true;
end;

// --  --
function unaDspDLibParams.getId(item: pointer): int64;
begin
  if (nil <> item) then
    result := punaDspDLibParam(item).r_id
  else
    result := 0;
end;

// --  --
procedure unaDspDLibParams.releaseItem(index, doFree: unsigned);
var
  p: pointer;
  id: dspl_int;
begin
  if (mapDoFree(doFree)) then begin
    //
    p := get(index);
    if (p <> nil) then
      id := punaDspDLibParam(p).r_id
    else
      id := 0;
    //
    if (
	(nil <> p) and
	(nil <> punaDspDLibParam(p).r2_chunk.r_fp) and
	(DSPL_P_TYPE_C = ($0F000000 and id)) and
	(not f_processor.idIsINOUT(id))
       ) then begin
      // IN/OUT buffers are always assigned by value, so no additional memory is taken
      // other buffers are allocated by copy, so we need to release the memory
      //
      mrealloc(punaDspDLibParam(p).r2_chunk.r_fp);
    end;
    //
    mrealloc(p);
  end;
end;


// biquad coefficients calculation
//
procedure dspl_biq(btype: dspl_int; gain: dspl_float; w: dspl_float; q: dspl_float; var r: dspl_biq_values; norm: bool);
var
  A: dspl_double;
  w2pi: dspl_double;
  cosw: dspl_double;
  sinw: dspl_double;
  alpha: dspl_double;
  alpha_div_a: dspl_double;
  alpha2sqrtA: dspl_double;
  a0_1: dspl_double;
begin
  //const dspl_double pi=2.0*asin(1);
  try
    //
    A := pow(gain, 0.5);
    w2pi := 2 * pi * w;
    cosw := cos(w2pi);
    sinw := sin(w2pi);
    alpha := sinw / (2 * q);
    //
    case (btype) of

      //
      DSPL_BIQ_LP: begin
	//
	r.b1 := 1.0 - cosw;
	r.b0 := 0.5 * r.b1;
	r.b2 := r.b0;
	//
	r.a0 := 1.0 + alpha;
	r.a1 := -2.0 * cosw;
	r.a2 := 1.0 - alpha;
      end;

      //
      DSPL_BIQ_HP: begin
	//
	r.b1 := -cosw - 1.0;
	r.b0 := -0.5 * r.b1;
	r.b2 := r.b0;
	//
	r.a0 := 1.0 + alpha;
	r.a1 := -2.0 * cosw;
	r.a2 := 1.0 - alpha;
      end;

      //
      DSPL_BIQ_PEAK: begin
	//
	alpha_div_a := alpha / A;
	//
	r.b0 := 1.0 + alpha * A;
	r.b1 := -2.0 * cosw;
	r.b2 := 1.0 - alpha * A;
	//
	r.a0 := 1.0 + alpha_div_a;
	r.a1 := r.b1;
	r.a2 := 1.0 - alpha_div_a;
      end;

      //
      DSPL_BIQ_LS: begin
	//
	alpha2sqrtA := 2.0 * pow(A, 0.5) * alpha;
	//
	r.b0 :=       A * ((A + 1.0) - (A - 1.0) * cosw + alpha2sqrtA);
	r.b1 := 2.0 * A * ((A - 1.0) - (A + 1.0) * cosw);
	r.b2 :=       A * ((A + 1.0) - (A - 1.0) * cosw - alpha2sqrtA);
	//
	r.a0 :=            (A + 1.0) + (A - 1.0) * cosw + alpha2sqrtA;
	r.a1 :=    -2.0 * ((A - 1.0) + (A + 1.0) * cosw );

⌨️ 快捷键说明

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