Metronome: Difference between revisions
added RPL
No edit summary |
(added RPL) |
||
(10 intermediate revisions by 6 users not shown) | |||
Line 18:
{{trans|Python}}
<
V t = 60.0 / bpm
V counter = 0
Line 29:
sleep(t)
main()</
=={{header|Ada}}==
{{This metronome only does 60 bpm with 1 Measure length.}}
<
with Ada.Text_IO; use Ada.Text_IO;
Line 55:
end loop;
end Main;</
=={{header|AppleScript}}==
<
set pauseBetweenBeeps to (60 / bpm)
repeat
beep
delay pauseBetweenBeeps
end repeat</
=={{header|Arturo}}==
<
freq: 60000/bpm
i: 0
Line 83:
beats: to :integer arg\1
startMetronome tempo beats</
=={{header|AutoHotkey}}==
Rather basic implementation, but meets the requirements and is reasonably accurate.
<
pattern = 4/4 ;
duration = 100 ; Milliseconds
Line 117:
Esc::
MsgBox % "Metronome beeped " beats " beats, over " (A_TickCount-Start)/1000 " seconds. "
ExitApp</
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f METRONOME.AWK
@load "time"
Line 141:
}
}
</syntaxhighlight>
{{out}}
<pre>
Line 155:
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<
Tempo% = 100
Line 175:
WAIT 6000/Tempo%
NEXT
UNTIL FALSE</
=={{header|C}}==
Using <code>usleep</code> with self correcting delays. Audio is the bell character, which will definitely drive one insane (but I'm ok: my computer doesn't have the bell device). Invoke with <code>./a.out [beats_per_minute]</code>, default to 60.
<
#include <stdlib.h>
#include <unistd.h>
Line 264:
return 0;
}</
=={{header|C#}}==
{{trans|Java}}
<syntaxhighlight lang="C#">
using System;
using System.Threading;
public class Program
{
public static void Main(string[] args)
{
Metronome metronome1 = new Metronome(120, 4);
metronome1.Start();
}
}
public class Metronome
{
private double bpm;
private int measure;
private int counter;
public Metronome(double bpm, int measure)
{
this.bpm = bpm;
this.measure = measure;
}
public void Start()
{
Thread thread = new Thread(() =>
{
while (true)
{
try
{
Thread.Sleep((int)(1000 * (60.0 / bpm)));
}
catch (ThreadInterruptedException e)
{
Console.WriteLine(e.StackTrace);
}
counter++;
if (counter % measure == 0)
{
Console.WriteLine("TICK");
}
else
{
Console.WriteLine("TOCK");
}
}
});
thread.Start();
}
}
</syntaxhighlight>
=={{header|C++}}==
This example has a timing loop to ensure that its timing is reliable in the long term.
<syntaxhighlight lang="c++">
#include <chrono>
#include <cstdint>
#include <iostream>
#include <thread>
class Metronome {
public:
Metronome(const int32_t& aBeats_per_minute, const int32_t& aMeasure, const int32_t& aDuration_in_minutes)
: beats_per_minute(aBeats_per_minute), measure(aMeasure), duration_in_minutes(aDuration_in_minutes) {
counter = 0;
}
void start() {
while ( counter < duration_in_minutes * beats_per_minute ) {
start_time = std::chrono::system_clock::now();
std::this_thread::sleep_until(time_to_awake());
counter++;
if ( counter % measure != 0 ) {
std::cout << "Tick " << std::flush;
} else {
std::cout << "Tock" << std::endl;
}
}
}
private:
std::chrono::system_clock::time_point time_to_awake() const {
return start_time + std::chrono::seconds(1);
}
std::chrono::system_clock::time_point start_time;
int32_t counter;
const int32_t beats_per_minute, measure, duration_in_minutes;
};
int main() {
Metronome metronome(60, 4, 1);
metronome.start();
}
</syntaxhighlight>
{{ out }}
<pre>
Tick Tick Tick Tock
Tick Tick Tick Tock
Tick Tick
// continues for the requested duration
</pre>
=={{header|Common Lisp}}==
Depends on quicklisp and OpenAL.
<
(defparameter *short-max* (- (expt 2 15) 1))
Line 331 ⟶ 444:
(h (play-it high-buffer)))
(princ symbol))
(terpri)))))))))))</
<pre>CL-USER> (metronome 100 '(h l l l))
HLLL
Line 339 ⟶ 452:
{{libheader| System.SysUtils}}
{{Trans|Java}}
<syntaxhighlight lang="delphi">
program Metronome;
Line 366 ⟶ 479:
begin
StartMetronome(120, 4);
end.</
{{out}}
<pre>TOCK
Line 383 ⟶ 496:
=={{header|EchoLisp}}==
<
;; available preloaded sounds are : ok, ko, tick, tack, woosh, beep, digit .
(lib 'timer)
Line 390 ⟶ 503:
(at-every 1000 'metronome) ;; every 1000 msec
;; CTRL-C to stop
</syntaxhighlight>
=={{header|F Sharp|F#}}==
<
open System.Threading
// You can use .wav files for your clicks.
Line 427 ⟶ 540:
Seq.initInfinite (fun i -> i + 1)
|> Seq.iter (fun _ -> tempo |> play beats 1 |> ignore)
0 </
Sample run:
<pre>$ metronome 120 6
Line 439 ⟶ 552:
=={{header|Factor}}==
<
command-line continuations io kernel math math.parser namespaces
openal.example sequences system timers ui ui.gadgets
Line 506 ⟶ 619:
[ [ metronome-cmdline metronome-ui ] [ drop metronome-usage 1 exit ] recover ] with-ui ;
MAIN: metronome-main</
=={{header|FreeBASIC}}==
<
REM La función Sound no es mía, incluyo los créditos correspondientes.
' Sound Function v0.3 For DOS/Linux/Win by yetifoot
Line 591 ⟶ 704:
Sleep(retardo)
Loop
End Sub</
=={{header|FutureBasic}}==
An Apple Mac application that, when compiled with FB, produces a packaged, stand-alone 64-bit application that will run on either Intel or the newer M-series Macs. It's GUI includes a slider control to adjust speed, as well as blinking indicator and a sound, to indicate tempo. The code has been tested on Catalina (10.15.x) to Monterey (12.4.x) with Ventura still in beta at the time of this post.
[http://www.brilorsoftware.com/fb/pages/home.html
<
/*
Basic Tempo Markings from slowest to fastest:
Line 776 ⟶ 889:
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
[Since this code generates a standalone 64-bit Macintosh application with its own window and controls, it has to be compiled with FB to see the GUI and test the output.]
</pre>
=={{header|Go}}==
Line 797 ⟶ 906:
So, as long as the output or sound production finishes before the next tick,
the timing will be reliable and will not drift which is the gist of this task.
<
import (
Line 821 ⟶ 930:
}
}
}</
{{out}}
<pre>
Line 835 ⟶ 944:
{{works with|GHC|7.4.2}}
<
import Control.Concurrent.MVar
import System.Process (runCommand)
Line 886 ⟶ 995:
_ <- forkIO $ tick b i
_ <- getChar
putMVar b [Stop]</
=={{header|J}}==
Line 893 ⟶ 1,002:
MET returns the total number of measures, beats, and elapsed time.<br>
If you leave out the left arguments, it will set them to infinity, so you can go insane without worrying about the metronome ever stopping.
<syntaxhighlight lang="j">
MET=: _ _&$: :(4 : 0)
Line 934 ⟶ 1,043:
'`print delay'=: 1!:2&4`(6!:3)
met=: _&$: :((] ({:@] [ LF print@[ (-.@{.@] [ delay@[ print@] (BEL,2#BS) , (2 2$'\ /') {~ {.@])^:({:@])) 1 , <.@%) 60&% [ print@('\ '"_))
</syntaxhighlight>
{{out}}
<pre>
Line 950 ⟶ 1,059:
=={{header|Java}}==
<
class Metronome{
double bpm;
Line 980 ⟶ 1,089:
}
}
</syntaxhighlight>
===AudioVisual===
This example provides an audible and visual indications of the metronome timing.
It uses a timing loop to ensure that its timing is reliable in the long term.
<syntaxhighlight lang="java">
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
public final class MetronomeTask {
public static void main(String[] aArgs) {
EventQueue.invokeLater( () -> { new Metronome(60, 4, 1).start(); } );
}
}
final class Metronome extends JPanel {
public Metronome(int aBeatsPerMinute, int aMeasure, int aDurationInMinutes) {
beatsPerMinute = aBeatsPerMinute; measure = aMeasure; durationInMinutes = aDurationInMinutes;
SoundEffect.initialise();
createAndShowGUI();
}
public void start() {
executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleAtFixedRate(provideService, 1, 1, TimeUnit.SECONDS);
}
private void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
frame = new JFrame("Metronome");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setIconImage( new ImageIcon("./metronomeJava.png").getImage() );
frame.add(createPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
}
private JPanel createPanel() {
setPreferredSize( new Dimension(800, 600) );
setBackground(Color.CYAN);
return this;
}
private JFrame frame;
private ScheduledExecutorService executorService;
private int beatsPerMinute, measure, durationInMinutes, counter;
private Runnable provideService = () -> {
if ( counter < durationInMinutes * beatsPerMinute ) {
counter++;
if ( counter % measure != 0 ) {
SoundEffect.Tick.play();
if ( getBackground() != Color.PINK ) {
setBackground(Color.PINK);
} else {
setBackground(Color.CYAN);
}
} else {
SoundEffect.Tock.play();
setBackground(Color.ORANGE);
}
} else {
executorService.shutdown();
frame.dispose();
Runtime.getRuntime().exit(0);
}
};
}
enum SoundEffect {
Tick("./metronomeTickJava.wav"), Tock("./metronomeTockJava.wav");
public static void initialise() {
values();
}
public void play() {
if ( clip.isRunning() ) {
clip.stop();
}
clip.setFramePosition(0);
clip.start();
}
private SoundEffect(String soundFileName) {
URL url = getClass().getClassLoader().getResource(soundFileName);
try ( AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url) ) {
clip = AudioSystem.getClip();
clip.open(audioInputStream);
} catch (IOException | LineUnavailableException | UnsupportedAudioFileException ex) {
ex.printStackTrace();
}
}
private Clip clip;
}
</syntaxhighlight>
=={{header|Julia}}==
{{works with|Julia|0.6}}
<
s = 60.0 / bpm
counter = 0
Line 997 ⟶ 1,226:
sleep(s)
end
end</
=={{header|Kotlin}}==
<
fun metronome(bpm: Int, bpb: Int, maxBeats: Int = Int.MAX_VALUE) {
Line 1,015 ⟶ 1,244:
}
fun main(args: Array<String>) = metronome(120, 4, 20) // limit to 20 beats </
{{out}}
Line 1,028 ⟶ 1,257:
=={{header|Liberty BASIC}}==
Requires two supplied wav files for accentuated & standard sounds.
<
WindowHeight =220
Line 1,112 ⟶ 1,341:
#w "flush"
wait</
=={{header|Locomotive Basic}}==
{{trans|Python}}
<
20 sleep=50*60/bpm
30 counter=0
Line 1,125 ⟶ 1,354:
120 counter=counter+1
130 if counter=bpb then counter=0
140 return</
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Shows/plays a visual and auditory metronome:
<
ss = Sound[Play[Sin[2000 t], {t, 0, 0.05}]];
bpm = 180;
Line 1,145 ⟶ 1,374:
];
Pause[slp];
]</
=={{header|Nim}}==
Textual version only.
<
proc metronome(tempo, pattern: Positive) =
Line 1,160 ⟶ 1,389:
sleep(delay)
metronome(72, 4)</
=={{header|Perl}}==
The module <code>Time::HiRes</code> provides sub-second <tt>sleep</tt>. Text output only.
<
local $| = 1; # autoflush
Line 1,183 ⟶ 1,412:
}
sleep($next_time - gettimeofday());
}</
Sample run
{{out}}
Line 1,195 ⟶ 1,424:
===Graphical version===
Visual only, unless you want to uncomment the bell call.
<
use strict;
Line 1,229 ⟶ 1,458:
-width => 5);
$mw->after( 60_000 / $bpm / 2 => \&tick );
}</
=={{header|Phix}}==
Line 1,235 ⟶ 1,464:
{{libheader|Phix/online}}
You can run this online [http://phix.x10.mx/p2js/virtunome.htm here], with a few sizing/layout issues I could use a little help with, ideally w/o breaking anything else.
<!--<
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\virtunome.exw
Line 1,523 ⟶ 1,752:
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</
=={{header|PicoLisp}}==
A short beep (440 Hz, 40 msec) is produced in a child process, while a "pendulum" is swinging left and right. Hitting any key will stop it.
<
(if (fork)
(let Pid @
Line 1,535 ⟶ 1,764:
(T (key (*/ 30000 Bpm)) (tell Pid 'bye)) )
(prinl) )
(wait) ) )</
Test:
<
/
-> NIL # A key was hit</
=={{header|Pure Data}}==
Line 1,630 ⟶ 1,859:
</ul>
[[file:MetronomeScreenShot.png|PureBasic output|thumb|200px]]
<
msPerBeat.i
BeatsPerMinute.i
Line 1,949 ⟶ 2,178:
Data.q $787A7A7976757678,$415380817C777576,$2C31000002005255,$30202C36202C3020
eClick:
EndDataSection</
=={{header|Python}}==
<syntaxhighlight lang="python">
#lang Python
import time
Line 1,971 ⟶ 2,200:
main()
</syntaxhighlight>
=={{header|Racket}}==
<syntaxhighlight lang="racket">
#lang racket
Line 2,016 ⟶ 2,245:
(send* f (center) (show #t))
(void (thread flip))
</syntaxhighlight>
=={{header|Raku}}==
Line 2,022 ⟶ 2,251:
This code only uses textual output, but any noise-generating commands may be substituted; as long as they are executed synchronously, and do not run longer than the specified duration, the timing loop will compensate, since the sequence operator is determining a list of absolute times for each <tt>sleep</tt> to target.
<syntaxhighlight lang="raku"
my $duration = 60 / $beats-per-minute;
my $base-time = now + $duration;
Line 2,036 ⟶ 2,265:
sleep $next-time - now;
}
}</
Sample run:
<pre>$ metronome 120 6
Line 2,050 ⟶ 2,279:
These REXX program examples are modeled after the Raku example.
===textual visual, no sound===
<
parse arg bpm bpb dur . /*obtain optional arguments from the CL*/
if bpm=='' | bpm=="," then bpm=72 /*the number of beats per minute. */
Line 2,068 ⟶ 2,297:
end /*until e≥es*/
end /*until et≥dur*/
/*stick a fork in it, we're all done. */</
'''output''' when using the default inputs:
<per>
Line 2,081 ⟶ 2,310:
===with sound, REGINA only===
This REXX version ''only'' executes when using the Regina REXX interpreter.
<
parse arg bpm bpb dur tockf tockd tickf tickd . /*obtain optional arguments from the CL*/
if bpm=='' | bpm=="," then bpm= 72 /*the number of beats per minute. */
Line 2,103 ⟶ 2,332:
end /*until e≥es*/
end /*until et≥dur*/
/*stick a fork in it, we're all done. */</
===with sound, PC/REXX only===
<
parse arg bpm bpb dur tockf tockd tickf tickd . /*obtain optional arguments from the CL*/
if bpm=='' | bpm=="," then bpm= 72 /*the number of beats per minute. */
Line 2,128 ⟶ 2,357:
end /*until e≥es*/
end /*until et≥dur*/
/*stick a fork in it, we're all done. */</
=={{header|RPL}}==
« .02 0 → pattern duration beat
« -56 CF <span style="color:grey">''@ sound ON'' </span>
60 SWAP / duration - →NUM
'''DO''' "Beat!" 1 DISP
440 'beat' INCR pattern MOD 1 2 IFTE * duration BEEP
CLLCD DUP WAIT
'''UNTIL''' KEY '''END''' DROP2
» » '<span style="color:blue">METRO</span>' STO <span style="color:grey">''@ ( bpm pattern → )'' </span>
=={{header|Ruby}}==
This code rings the audible bell on every beat and write "And n" to stdout where n is the bar number that was just finished
<
#!/usr/bin/ruby
Line 2,147 ⟶ 2,386:
sleep(60.0/bpm)
end
</syntaxhighlight>
=={{header|Scala}}==
<
val delay = 60000L / bpm
var beats = 0
Line 2,163 ⟶ 2,402:
}
metronome(120, 4, 20) // limit to 20</
{{Out}} See it running in your browser by [https://scastie.scala-lang.org/7iejBcWqQISAIGtBCG6BNQ Scastie (JVM)].
=={{header|Sidef}}==
<
var counter = 0
Line 2,186 ⟶ 2,425:
}
say metronome(ARGV.map{ Num(_) }...)</
{{out}}
<pre>
Line 2,202 ⟶ 2,441:
=={{header|Tcl}}==
This code only rings the bell on the high beat, which occurs at the start of the bar.
<
lassign $argv bpm bpb
Line 2,227 ⟶ 2,466:
# Run the metronome until the user uses Ctrl+C...
beat
vwait forever</
It might be executed like this:
<
=={{header|Wren}}==
{{trans|Kotlin}}
Modified to ring the bell on each beat.
<
import "io" for Stdout
Line 2,250 ⟶ 2,489:
}
metronome.call(120, 4, 20) // limit to 20 beats</
{{out}}
Line 2,260 ⟶ 2,499:
TICK tick tick tick
</pre>
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">int BPM, Odd, Time0, Delay;
[Text(0, "Beats per minute: ");
BPM:= IntIn(0);
Odd:= true;
Delay:= 60_000_000/BPM; \microseconds per beat
repeat Time0:= GetTime;
repeat until GetTime-Time0 >= Delay;
Text(0, if Odd then "tick" else " TOCK^m^j");
Odd:= not Odd;
until KeyHit;
]</syntaxhighlight>
{{out}}
<pre>
Beats per minute: 120
tick TOCK
tick TOCK
tick TOCK
tick TOCK
tick</pre>
{{omit from|GUISS}}
|