![]() |
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!! |
Re: Metronom-Software -- Brauche Hilfe
Das ist ein rein mathematisches Problem:
Delphi-Quellcode:
Edit: Klammer ergänzt.
var
BeatsPerMin: integer; ... Timer1.Interval := round(1/(BeatsPerMin/60/1000)); |
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...)
|
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.
|
Re: Metronom-Software -- Brauche Hilfe
zensiert
hat sich erledigt |
Re: Metronom-Software -- Brauche Hilfe
Hi,
Delphi-Quellcode:
BeatsPerMin := StrToInt(Edit1.Text);
|
Re: Metronom-Software -- Brauche Hilfe
hat sich mittlerweile erledigt^^ kleiner fehler von mir
|
Re: Metronom-Software -- Brauche Hilfe
Zitat:
|
Re: Metronom-Software -- Brauche Hilfe
Zitat:
Delphi-Quellcode:
Diese Funktion gibt die seit dem Systemstart vergangene Zeit in Millisekunden zurück.
GetTickCount;
MfG Binärbaum |
Re: Metronom-Software -- Brauche Hilfe
![]() ![]() 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 ;) |
Re: Metronom-Software -- Brauche Hilfe
Mit windows.beep kann man cool metronom machen
|
Re: Metronom-Software -- Brauche Hilfe
wie kann man mithile von QueryPerformanceCounter und QueryPerformanceFrequency ein Metronom realisieren?? Ich bin mir da irgendwie unklar
|
Re: Metronom-Software -- Brauche Hilfe
Das hier kannst du Dir mal anschaun; (für die Übung)
![]() Und hier Code für den QueryPerformanceCounter; (ungetestet, hab grad kein Delphi zur Hand!)
Delphi-Quellcode:
Hoffe das klappt.
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; [..] Auch wenn ich glaube, dass ein PC ( noch ) zu ungenau ist für diese Aufgabe, MfG Thomas |
Re: Metronom-Software -- Brauche Hilfe
irgendwie funktioniert das nicht so... hat jemand weitere vorschläge??
|
Re: Metronom-Software -- Brauche Hilfe
Was funktioniert denn nicht?
|
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:
wäre toll wenn mir jemand helfen kann
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. |
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. |
Re: Metronom-Software -- Brauche Hilfe
wie definiere ich dann das tempo??
mit TimeBetweenTicks := 6000; ?? |
Re: Metronom-Software -- Brauche Hilfe
Definieren wir ein bpm für die QPC-Methode wie folgt:
Delphi-Quellcode:
Dann kannst du für eine beliebige bpm-Zahl einfach ausrechnen:
var
Frequency, TicksPerMinute: Int64; QueryPerformanceFrequency(Frequency); TicksPerMinute := Frequency * 60; // Frequency ist in Hz angegeben == Ticks pro Sekunde
Delphi-Quellcode:
div ist hier hinreichend genau, da bei neuen Rechnern Frequency etwas um 3 MHz ist, also ziemlich viel ;)
var
bpmTicks: Int64; bpmTicks := TicksPerMinute div Deine_bpm_Zahl; |
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; |
Re: Metronom-Software -- Brauche Hilfe
man könnte auch genauso sagen wie wende ich deine Definition der bpm von oben an??
|
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:
Der Code ist ungetestet, sollte aber funktionieren.
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; |
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!
|
Re: Metronom-Software -- Brauche Hilfe
Delphi-Quellcode:
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...)
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. naja also ich hoffe ihr könnt mir helfen! wie gesagt es kommen keine fehlermeldungen aber irgendwie gehts trotzdem nicht |
Re: Metronom-Software -- Brauche Hilfe
gibts eigentlich noch ne bessere möglichkeit den click-sound abzuspielen?
|
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