Einzelnen Beitrag anzeigen

dac424

Registriert seit: 11. Dez 2004
21 Beiträge
 
#1

Silence erkennen dan Taste Emulieren

  Alt 27. Feb 2005, 00:07
Hallo liebe freunde gibt es einen weg den mir jemand erklären kann ich habe in meinem PRG
eine Zeile
Delphi-Quellcode:
 DTMF:= TdspDTMF.Create;
  DTMF.OnTone:= OnTone;
  DTMF.SampleRate:= cSampleRate;
  DTMF.Threshold:= 100; // Set amplitude threshold
  DTMF.Initialize;
nun möchte ich die Funktion Treshold noch mals verwenden

Sobald ein Signal kommt egal welches sprich der Silenc überwunden ist
sol die Linke STRG taste gedrückt werden auf der Tastatur

sprich ich sage in mein Mikrofon etwas dan soll die Taste STRG gedrückt werden solange bis wieder Ruhe ist.

wer kann helfen?
Delphi-Quellcode:
interface

uses SysUtils, dspFFT, dspWindow;

const
  cMinDTFMSampleRate = 11025;
  cDefaultDTFMSampleRate = 11025;
  cSupportedSampleRates: Array[0..2] of Integer = (11025, 22050, 44100);
  cDTMFInvalidSampleRateMsg = 'Unsupported sample rate'#13#10'Please use: 11025, 22050 or 44100';

type
  EdspDTMFInvalidSampleRate = class(Exception);
  TdspOnTone = procedure(Sender: TObject; Tone: Char) of object;
  TdspDTMFArray = Array[0..3] of Single;
  PdspDTMFArray = ^TdspDTMFArray;

  TdspDTMF = class
  private
    FFT: TdspFFT;
    FOnTone: TdspOnTone;
    FSampleRate: Integer;
    FThreshold: Single;
    FSkipCnt, FCounter: Integer;
    FPos: Integer;
    FRow, FCol: Integer;
    FCols, FRows: TdspDTMFArray;

    procedure FSetSampleRate(V: Integer);
    procedure FindTones;

  public
    constructor Create;
    destructor Destroy; override;

    procedure Initialize;
    procedure Finilize;
    procedure Put(V: Single);

    property Threshold: Single read FThreshold write FThreshold;
    property SampleRate: Integer read FSampleRate write FSetSampleRate default cDefaultDTFMSampleRate;
    property OnTone: TdspOnTone read FOnTone write FOnTone;
  end;


implementation

constructor TdspDTMF.Create;
begin
  FFT:= TdspFFT.Create(nil);
  FFT.BufferSize:= 256;
  FFT.Window:= fwBlackman;
  SampleRate:= cDefaultDTFMSampleRate;
end;


destructor TdspDTMF.Destroy;
begin
  FFT.Free;
  inherited;
end;


procedure TdspDTMF.FSetSampleRate(V: Integer);
var
  Iz: Integer;
  Supported: Boolean;
begin
  if FSampleRate <> V then
  begin
    Supported:= false;
    for Iz:= Low(cSupportedSampleRates) to High(cSupportedSampleRates) do
      Supported:= Supported or (cSupportedSampleRates[Iz] = V);

    if not Supported then
      raise EdspDTMFInvalidSampleRate.Create(cDTMFInvalidSampleRateMsg)
    else begin
      FSampleRate:= V;
      FSkipCnt:= FSampleRate div cMinDTFMSampleRate;
    end;
  end;
end;


procedure TdspDTMF.Initialize;
begin
  FPos:= 0;
  FRow:= -1;
  FCol:= -1;
  FFT.Clear;
end;


procedure TdspDTMF.Finilize;
begin
  if FPos > 0 then FindTones;
end;


procedure TdspDTMF.Put(V: Single);
begin
  if FCounter mod FSkipCnt = 0 then
  begin
    FFT.RealIn[FPos]:= V;
    Inc(FPos);
    if FPos >= FFT.BufferSize then FindTones;
  end;
  Inc(FCounter);
end;


procedure TdspDTMF.FindTones;
  procedure LocateTones;
     function GetFreqAmp(Freq: Single): Single;
     const Step = 11025 / 256;
     var Pos: Integer;
     begin
       Pos:= Round(Freq / Step);
       Result:= FFT.RealOut[Pos];
     end;

     function FindPeak(Data: PdspDTMFArray; var Position: Integer): Boolean;
     var Iz: Integer;
     begin
       Position:= 0;
       for Iz:= 1 to 3 do
         if Data[Position] < Data[Iz] then Position:= Iz;

       Result:= true;
       for Iz:= 0 to 3 do
         if Iz <> Position then Result:= Result and (Data[Iz] * 3 < Data[Position]);

       Result:= Result and (Data[Position] > FThreshold);
     end;

  const Tones: Array[0..3, 0..3] of Char = (
    ('1', '4', '7', '*'),
    ('2', '5', '8', '0'),
    ('3', '6', '9', '#'),
    ('A', 'B', 'C', 'D'));
  var Col, Row: Integer;
  begin
    FCols[0]:= GetFreqAmp(1209);
    FCols[1]:= GetFreqAmp(1336);
    FCols[2]:= GetFreqAmp(1477);
    FCols[3]:= GetFreqAmp(1633);

    FRows[0]:= GetFreqAmp(697);
    FRows[1]:= GetFreqAmp(770);
    FRows[2]:= GetFreqAmp(852);
    FRows[3]:= GetFreqAmp(941);

    if FindPeak(@FCols, Col) and FindPeak(@FRows, Row) and
       (Col <> -1) and (Row <> -1) then
    begin
      if (Row <> FRow) or (Col <> FCol) then
      begin
        FCol:= Col; FRow:= Row;
        if Assigned(FOnTone) then FOnTone(Self, Tones[FCol, FRow]);
      end;
    end else
    begin
      FRow:= -1;
      FCol:= -1;
    end;
  end;
begin
  FFT.FFT;
  FFT.CalculateMagnitudes;
  LocateTones;
  FFT.Clear;
  FPos:= -1;
end;

end.
ich denke das muss ich damit lösen nur weis ich nicht wie
das Modul wir von dem 1 Feld verwendet.
mann fängt klein an
  Mit Zitat antworten Zitat