Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Metronom-Software -- Brauche Hilfe (https://www.delphipraxis.net/42100-metronom-software-brauche-hilfe.html)

Stresslein 13. Mär 2005 17:54


Metronom-Software -- Brauche Hilfe
 
Hallo,
ich bin grade dabei ein bisschen der Delphi-Sprache näherzukommen und will mir ein kleines Metronomprogramm basteln. Ich habe den "click-sound" einfach mit der mmplayer-komponente eingebunden, und habe einen Timer verwendet der dann bei ablauf der zeit immer diese datei abspielt...
nun brauche ich noch ein bisschen hilfe in sachen der steuerung. ich will ja in einem editfeld die bpm-zahl (beats-per-minute) einstellen, die muss aber wiederrum in Millisekunden umgerechnet werden. Wie mach ich das weil das is ja irgendwie antiproportional (1bmp = 60000ms, 2bmp = 30000ms usw.)
Zudem weis ich nicht genau wie ich das dann mache dass ich die eingegebene bpm-zahl in timer1.interval:=... übertragen kann, das funktioniert irgendwie nicht. Kann mir jemand sagen wie ich die oben genannten Probleme beheben kann??

Vielen Dank für die Antworten!!

Elite 13. Mär 2005 18:06

Re: Metronom-Software -- Brauche Hilfe
 
Das ist ein rein mathematisches Problem:
Delphi-Quellcode:
var
 BeatsPerMin: integer;
...
Timer1.Interval := round(1/(BeatsPerMin/60/1000));
Edit: Klammer ergänzt.

Tubos 13. Mär 2005 18:12

Re: Metronom-Software -- Brauche Hilfe
 
Das hat jetzt nichts mit deiner Frage zu tun, aber ich als Hobby-Musiker würde dir davon abraten ein solches Metronom zu verwenden, da der Timer nicht ganz genau ist. (nur falls du sowas vorhast...)

Elite 13. Mär 2005 18:16

Re: Metronom-Software -- Brauche Hilfe
 
Und als Hobby-Programmier möchte ich noch ergänzen, dass es noch zig andere Möglichkeiten gibt, mit Delphi ein richtig taktendes Metronom zu basteln - auch ohne Timer.

Stresslein 13. Mär 2005 18:19

Re: Metronom-Software -- Brauche Hilfe
 
zensiert
hat sich erledigt

Die Muhkuh 13. Mär 2005 18:21

Re: Metronom-Software -- Brauche Hilfe
 
Hi,

Delphi-Quellcode:
BeatsPerMin := StrToInt(Edit1.Text);

Stresslein 13. Mär 2005 18:21

Re: Metronom-Software -- Brauche Hilfe
 
hat sich mittlerweile erledigt^^ kleiner fehler von mir

Stresslein 13. Mär 2005 18:22

Re: Metronom-Software -- Brauche Hilfe
 
Zitat:

Zitat von Elite
Und als Hobby-Programmier möchte ich noch ergänzen, dass es noch zig andere Möglichkeiten gibt, mit Delphi ein richtig taktendes Metronom zu basteln - auch ohne Timer.

Wie würdet ihr das machen?

Binärbaum 13. Mär 2005 18:26

Re: Metronom-Software -- Brauche Hilfe
 
Zitat:

Zitat von Stresslein
Zitat:

Zitat von Elite
Und als Hobby-Programmier möchte ich noch ergänzen, dass es noch zig andere Möglichkeiten gibt, mit Delphi ein richtig taktendes Metronom zu basteln - auch ohne Timer.

Wie würdet ihr das machen?

Zum Beispiel mit
Delphi-Quellcode:
GetTickCount;
Diese Funktion gibt die seit dem Systemstart vergangene Zeit in Millisekunden zurück.

MfG
Binärbaum

Tubos 13. Mär 2005 18:29

Re: Metronom-Software -- Brauche Hilfe
 
MSDN-Library durchsuchenQueryPerformanceCounter
MSDN-Library durchsuchenQueryPerformanceFrequency
Solange ein Software-Metronom nicht damit programmiert ist, verwende ich es nicht. Und da ich nicht weiß wie die ganzen Metronom-Proggies intern funktionieren und ich keine Zeit habe selbst eines zu programmieren verwende ich eben ein Hardware-Metronom ;)

sandraeberlein 13. Mär 2005 18:49

Re: Metronom-Software -- Brauche Hilfe
 
Mit windows.beep kann man cool metronom machen

Stresslein 26. Apr 2005 18:06

Re: Metronom-Software -- Brauche Hilfe
 
wie kann man mithile von QueryPerformanceCounter und QueryPerformanceFrequency ein Metronom realisieren?? Ich bin mir da irgendwie unklar

tn249 26. Apr 2005 19:26

Re: Metronom-Software -- Brauche Hilfe
 
Das hier kannst du Dir mal anschaun; (für die Übung)

http://www.delphipraxis.net/internal...ormancecounter

Und hier Code für den QueryPerformanceCounter;
(ungetestet, hab grad kein Delphi zur Hand!)

Delphi-Quellcode:
var
  TimeBetweenTicks: Integer; // TimeBetweenTicks in ms
  Abort: Boolean;
  Freq, Start, Stop: Int64;

[..]
Abort := false;
QueryPerformanceFrequency(Freq); // Freq kann sich nur durch Neustart des PCs ändern!
QueryPerformanceCounter(Stop); // Wert vernünftig initialisieren
while not(Abort) do
begin
  QueryPerformanceCounter(Start);
  while (((Stop - Start)/Freq) < TimeBetweenTicks) do
    begin
      QueryPerformanceCounter(Stop);
      // evtl: Application.ProcessMessages(); Keine Ahnung wie sich das auf die Genauigkeit auswirkt.
    end;
  //Beep, Klick oder andere Anzeige des Ticks
  // evtl: Abort := true;
end;
[..]
Hoffe das klappt.

Auch wenn ich glaube, dass ein PC ( noch ) zu ungenau ist für diese Aufgabe,
MfG
Thomas

Stresslein 4. Jun 2005 16:49

Re: Metronom-Software -- Brauche Hilfe
 
irgendwie funktioniert das nicht so... hat jemand weitere vorschläge??

Stanlay Hanks 4. Jun 2005 17:30

Re: Metronom-Software -- Brauche Hilfe
 
Was funktioniert denn nicht?

Stresslein 5. Jun 2005 16:33

Re: Metronom-Software -- Brauche Hilfe
 
naja also ich bin noch anfänger und ich kann den code von oben irgendwie nicht richtig anwenden. ich hab mal was probiert aber dann kommt:
Abort: Unbekannte Anweisung

Hier meine Unit1:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  TimeBetweenTicks: Integer; // TimeBetweenTicks in ms
  Abort: Boolean;
  Freq, Start, Stop: Int64;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
Abort := false;
QueryPerformanceFrequency(Freq); // Freq kann sich nur durch Neustart des PCs ändern!
QueryPerformanceCounter(Stop); // Wert vernünftig initialisieren
while not(Abort) do
begin
  QueryPerformanceCounter(Start);
  while (((Stop - Start)/Freq) < TimeBetweenTicks) do
    begin
      QueryPerformanceCounter(Stop);
      // evtl: Application.ProcessMessages(); Keine Ahnung wie sich das auf die Genauigkeit auswirkt.
    end;
  //HIER die Anweisung für den Clickton abzuspielen
  windows.Beep();
  // evtl: Abort := true;
end;

end.
wäre toll wenn mir jemand helfen kann

Dax 5. Jun 2005 16:47

Re: Metronom-Software -- Brauche Hilfe
 
Niemals begin und end vergessen ;)

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  TimeBetweenTicks: Integer; // TimeBetweenTicks in ms
  Abort: Boolean;
  Freq, Start, Stop: Int64;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Abort := false;
  QueryPerformanceFrequency(Freq); // Freq kann sich nur durch Neustart des PCs ändern!
  QueryPerformanceCounter(Stop); // Wert vernünftig initialisieren
  while not(Abort) do
  begin
    QueryPerformanceCounter(Start);
    while (((Stop - Start)/Freq) < TimeBetweenTicks) do
      begin
        QueryPerformanceCounter(Stop);
        // evtl: Application.ProcessMessages(); Keine Ahnung wie sich das auf die Genauigkeit auswirkt.
      end;
    //HIER die Anweisung für den Clickton abzuspielen
    windows.Beep();
    // evtl: Abort := true;
  end;
end;

end.

Stresslein 5. Jun 2005 16:59

Re: Metronom-Software -- Brauche Hilfe
 
wie definiere ich dann das tempo??
mit
TimeBetweenTicks := 6000; ??

Dax 5. Jun 2005 17:17

Re: Metronom-Software -- Brauche Hilfe
 
Definieren wir ein bpm für die QPC-Methode wie folgt:
Delphi-Quellcode:
var
  Frequency, TicksPerMinute: Int64;

QueryPerformanceFrequency(Frequency);
TicksPerMinute := Frequency * 60; // Frequency ist in Hz angegeben == Ticks pro Sekunde
Dann kannst du für eine beliebige bpm-Zahl einfach ausrechnen:
Delphi-Quellcode:
var
  bpmTicks: Int64;

bpmTicks := TicksPerMinute div Deine_bpm_Zahl;
div ist hier hinreichend genau, da bei neuen Rechnern Frequency etwas um 3 MHz ist, also ziemlich viel ;)

Stresslein 5. Jun 2005 17:44

Re: Metronom-Software -- Brauche Hilfe
 
ich will ja aber in einem editfeld die bpm eingeben und dann einfach start drücken, damit die datei blop.wav in diesem abstand (edit1) abgespielt wird.
muss ich alles bei var oben reinschreiben??
also:
Delphi-Quellcode:
var
  Form1: TForm1;
  TimeBetweenTicks: Integer; // TimeBetweenTicks in ms
  Abort: Boolean;
  Freq, Start, Stop: Int64;
  Frequency, TicksPerMinute: Int64;
  QueryPerformanceFrequency(Frequency);
  TicksPerMinute := Frequency * 60; // Frequency ist in Hz angegeben == Ticks pro Sekunde
  bpmTicks: Int64;
  bpmTicks := TicksPerMinute div Deine_bpm_Zahl;

Stresslein 5. Jun 2005 19:00

Re: Metronom-Software -- Brauche Hilfe
 
man könnte auch genauso sagen wie wende ich deine Definition der bpm von oben an??

Dax 6. Jun 2005 10:30

Re: Metronom-Software -- Brauche Hilfe
 
Also, du hast die Definition eines bpm. Entspricht wie gesagt einem Schlag pro Minute. Die Variable "bpmTicks" speichert, wie viele Ticks eines Taktgebers im Rechner einer Minute entsprechen. Oder wir stellen eine Frage: Wenn ich zwischen zwei Schlägen (1 bpm) eine Minute warten will, wie groß muss der Unterschied zwischen dem QueryPerformanceCounter-Wert des letzten Schlags und jetzt sein? Nun, ganz genau "bpmTicks". Willst du 2 Schläge (2 bpm) haben, wäre es dann logischerweise "bpmTicks div 2" ;)

Hier mal ein kleiner Code, der ungefähr tun sollte, was du willst.

Delphi-Quellcode:
var
  TempTicks, LastBeatTicks: Int64;
  bpm: IntegerM

bpm := StrToInt(Edit.Text); // bpm enthält nun deine gewünschte bpm-Zahl
QueryPerformanceCounter(LastBeatTicks);
DoBeat; // Am Anfang gleich den ersten Schlag abspielen
while MetronomeRunning do // solange wie das Metronom laufen soll..
begin
  QueryPerformanceCounter(TempTicks);
  if SameValue(LastBeatTicks - TempTicks, bpmTicks div bpm, Frequency div 10000) then
  // mit SameValue (unit Math) überprüfen wir, ob die Zeitdifferenz zwischen dem letzten Beat
  // und jetzt ungefähr mit der Zeit übereinstimmt, die zwischen 2 Beats liegen soll.
  // Frequency div 10000 heißt hier: Selbst, wenn die Werte noch 100µs auseinander liegen,
  // wird angenommen die Werte seien gleich
  begin
    DoBeat;
    LastBeatTicks := TempTicks;
  end;
end;
Der Code ist ungetestet, sollte aber funktionieren.

Stresslein 7. Jun 2005 15:34

Re: Metronom-Software -- Brauche Hilfe
 
also ich nehme an DoBeat ist dann meine Funktion dass die Wavdatei "Klick" abgespielt werden soll. Ebenso ist (while) MetronomRunning die Schleife, wie lange alles gemacht werden soll, also wenn ich reinschreib while panel1.caption='Metronom ON' do... wird solange alles in der schleife gemacht, bis panel1.caption irgendeinen anderen Wert hat. Geh ich davon richtig aus?? Weil ich habs jetzt so ausprobiert aber irgendwie passiert garnix wenn ich auf button1 drücke. es werden keine fehlermeldungen beim compilen angezeigt nur es geht halt nix^^ woran kann das liegen? ich werde gleich mal die unit zeigen!

Stresslein 8. Jun 2005 14:14

Re: Metronom-Software -- Brauche Hilfe
 
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, MPlayer, ExtCtrls, Math;

type
  TForm1 = class(TForm)
    Button1: TButton;
    MediaPlayer1: TMediaPlayer;
    Edit1: TEdit;
    Panel1: TPanel;
    procedure Button1Click(Sender: TObject);

  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  TimeBetweenTicks: Integer;
  Abort: Boolean;
  Freq, Start, Stop: Int64;
     bpmTicks: Int64;
       Frequency, TicksPerMinute: Int64;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  TempTicks, LastBeatTicks: Int64;
  bpm: Integer;
 begin
bpm := StrToInt(Edit1.Text);

QueryPerformanceCounter(LastBeatTicks);
MediaPlayer1.play; // Am Anfang gleich den ersten Schlag abspielen
while Panel1.Caption='ON' do // solange wie das Metronom laufen soll..
begin
  QueryPerformanceCounter(TempTicks);
  if SameValue(LastBeatTicks - TempTicks, bpmTicks div bpm, Frequency div 10000) then
  begin
    MediaPlayer1.Play;
    LastBeatTicks := TempTicks;
  end;
end;
  end;
end.
Bitte nicht lachen wenn ich irgendwelche saublöden Fehler gemacht habe^^ bin noch im anfängerstadium und möchte jetzt soviel programmieren wir möglich (learning by doing...)
naja also ich hoffe ihr könnt mir helfen! wie gesagt es kommen keine fehlermeldungen aber irgendwie gehts trotzdem nicht

Stresslein 10. Jun 2005 15:17

Re: Metronom-Software -- Brauche Hilfe
 
gibts eigentlich noch ne bessere möglichkeit den click-sound abzuspielen?

Stresslein 29. Jun 2005 17:37

Re: Metronom-Software -- Brauche Hilfe
 
ich habe immer noch keine lösung warum das nicht geht, vllt kann mir jemand helfen?? wäre sehr dankbar...


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:50 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz