Sine wave: Difference between revisions

From Rosetta Code
Content added Content deleted
(→‎{{header|OCaml}}: added ocaml)
(Added Uiua solution)
 
(37 intermediate revisions by 17 users not shown)
Line 9: Line 9:
::# play sound
::# play sound


=={{header|AmigaBASIC}}==
<syntaxhighlight lang="basic">SOUND 440,77</syntaxhighlight>
The maximum allowed sound duration parameter in AmigaBASIC is 77 units. Since a second equals 18.2 sound units, this tone will only play for 4.23 seconds.


=={{header|BASIC256}}==
<syntaxhighlight lang="basic256">sound 440, 5000</syntaxhighlight>

=={{header|C}}==
{{trans|Python}}
<syntaxhighlight lang="c">#include <stdio.h>
#include <math.h>
#include <stdlib.h>

// AU header (CD-quality audio)
int header[] = {46, 115, 110, 100, 0, 0, 0, 24,
255, 255, 255, 255, 0, 0, 0, 3,
0, 0, 172, 68, 0, 0, 0, 1};

int main(int argc, char *argv[]){
float freq, dur;
long i, v;

if (argc < 3) {
printf("Usage:\n");
printf(" csine <frequency> <duration>\n");
exit(1);
}
freq = atof(argv[1]);
dur = atof(argv[2]);
for (i = 0; i < 24; i++)
putchar(header[i]);
for (i = 0; i < dur * 44100; i++) {
v = (long) round(32000. * sin(2. * M_PI * freq * i / 44100.));
v = v % 65536;
putchar(v >> 8);
putchar(v % 256);
}
}</syntaxhighlight>
Test:
<syntaxhighlight lang="bash">gcc -o csine csine.c -lm
./csine 440 5 | play - # Now either pipe output into SoX to play
./csine 440 5 > test.au # or redirect output to a file.</syntaxhighlight>

=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{libheader| Winapi.Windows}}
{{libheader| Winapi.MMSystem}}
Copy of Andreas Rejbrand example found here [https://stackoverflow.com/questions/7742377/how-can-i-generate-continuous-tones-of-varying-frequencies].
<syntaxhighlight lang="delphi">
program Sine_wave;

{$APPTYPE CONSOLE}

uses
System.SysUtils,
Winapi.Windows,
Winapi.MMSystem;

type
TWaveformSample = integer; // signed 32-bit; -2147483648..2147483647

TWaveformSamples = packed array of TWaveformSample; // one channel

var
Samples: TWaveformSamples;
fmt: TWaveFormatEx;

procedure InitAudioSys;
begin
with fmt do
begin
wFormatTag := WAVE_FORMAT_PCM;
nChannels := 1;
nSamplesPerSec := 44100;
wBitsPerSample := 32;
nAvgBytesPerSec := nChannels * nSamplesPerSec * wBitsPerSample div 8;
nBlockAlign := nChannels * wBitsPerSample div 8;
cbSize := 0;
end;
end;
// Hz // msec

procedure CreatePureSineTone(const AFreq: integer; const ADuration: integer;
const AVolume: double { in [0, 1] });
var
i: Integer;
omega, dt, t: double;
vol: double;
begin
omega := 2 * Pi * AFreq;
dt := 1 / fmt.nSamplesPerSec;
t := 0;
vol := MaxInt * AVolume;
SetLength(Samples, Round((ADuration / 1000) * fmt.nSamplesPerSec));
for i := 0 to high(Samples) do
begin
Samples[i] := round(vol * sin(omega * t));
t := t + dt;
end;
end;

procedure PlaySound;
var
wo: integer;
hdr: TWaveHdr;
begin

if Length(samples) = 0 then
begin
Writeln('Error: No audio has been created yet.');
Exit;
end;

if waveOutOpen(@wo, WAVE_MAPPER, @fmt, 0, 0, CALLBACK_NULL) = MMSYSERR_NOERROR then
try

ZeroMemory(@hdr, sizeof(hdr));
with hdr do
begin
lpData := @samples[0];
dwBufferLength := fmt.nChannels * Length(Samples) * sizeof(TWaveformSample);
dwFlags := 0;
end;

waveOutPrepareHeader(wo, @hdr, sizeof(hdr));
waveOutWrite(wo, @hdr, sizeof(hdr));
sleep(500);

while waveOutUnprepareHeader(wo, @hdr, sizeof(hdr)) = WAVERR_STILLPLAYING do
sleep(100);

finally
waveOutClose(wo);
end;

end;

begin
try
InitAudioSys;
CreatePureSineTone(440, 5000, 0.7);
PlaySound;
except
on E: Exception do
begin
Writeln(E.Classname, ': ', E.Message);
Readln;
end;
end;
end.</syntaxhighlight>

=={{header|Emacs Lisp}}==
Note that this code does not work on Windows because playing sound from Emacs Lisp data variables is not supported there.

===8-bit samples===
<syntaxhighlight lang="lisp">(defun play-sine (freq dur)
"Play a sine wave for dur seconds."
(setq header (unibyte-string ; AU header:
46 115 110 100 ; ".snd" magic number
0 0 0 24 ; start of data bytes
255 255 255 255 ; file size is unknown
0 0 0 3 ; 16 bit PCM samples
0 0 172 68 ; 44,100 samples/s
0 0 0 1)) ; mono
(setq s (apply #'concat header (mapcar (lambda (x) (unibyte-string
(mod (round (* 127 (sin (* 2 pi freq x (/ 44100.0))))) 256) 0))
(number-sequence 0 (* dur 44100)))))
(play-sound `(sound :data ,s)))

(play-sine 440 5)</syntaxhighlight>
While the generated AU sound file is 16 bit, the samples themselves are 8 bit because only their high byte is set by the sine function. Therefore you will hear some faint hiss in the background due to the higher noise floor of 8-bit audio.

===16-bit samples===
This (slightly slower) version of the function creates proper 16-bit samples by setting both high and low bytes, resulting in less playback noise.
<syntaxhighlight lang="lisp">(defun play-sine16 (freq dur)
"Play a sine wave for dur seconds."
(setq header (unibyte-string ; AU header:
46 115 110 100 ; ".snd" magic number
0 0 0 24 ; start of data bytes
255 255 255 255 ; file size is unknown
0 0 0 3 ; 16 bit PCM samples
0 0 172 68 ; 44,100 samples/s
0 0 0 1)) ; mono
(setq v (mapcar (lambda (x)
(mod (round (* 32000 (sin (* 2 pi freq x (/ 44100.0))))) 65536))
(number-sequence 0 (* dur 44100))))
(setq s (apply #'concat header (flatten-list (mapcar (lambda (x)
(list (unibyte-string (ash x -8))
(unibyte-string (mod x 256))))
v))))
(play-sound `(sound :data ,s)))

(play-sine16 440 5)</syntaxhighlight>

=={{header|FreeBASIC}}==
This subroutine is able to generate complex sounds using only Windows API.

Original code programmed by Angelo Rosina
[https://www.freebasic.net/forum/viewtopic.php?t=12733]
<syntaxhighlight lang="freebasic">Enum FLAGS
_ASYNC = &h000001
_NODEFAULT = &h000002
_MEMORY = &h000004
_LOOP = &h000008
_NOSTOP = &h000010
_PURGE = &h000040
_APPLICATION = &h000080
_NOWAIT = &h002000
_ALIAS = &h010000
_FILENAME = &h020000
_RESOURCE = &h040000 Or _MEMORY
_ALIAS_ID = &h100000 Or _ALIAS
End Enum

#define PLAYFLAG _NOWAIT Or _NOSTOP Or _MEMORY Or _ASYNC
#define SNDPLAYFLAG _NOSTOP Or _MEMORY Or _ASYNC
#define FCC(c) *(cptr(Uinteger Ptr,@##c))
Declare Function PlayMemory Alias "PlaySoundA" (Byval As Any Ptr, Byval hModule As Any Ptr = 0, Byval flag As Integer = PLAYFLAG) As Integer
Declare Function sndPlayMemory Alias "sndPlaySoundA" (Byval As Any Ptr, Byval flag As Uinteger = SNDPLAYFLAG) As Integer
#inclib "winmm"

Sub PrepareBuffer(Byval lpBuffer As Any Ptr, _
Byval nSamples As Uinteger, _
Byval nRate As Uinteger = 44100, _
Byval nBits As Uinteger = 16, _
Byval nChannels As Uinteger = 2)
Dim As Uinteger Ptr h = lpBuffer
Dim As Uinteger BlkAlign = (nBits\8) * nChannels
Dim As Uinteger DataSize = BlkAlign * nSamples
h[ 0]=FCC("RIFF") ' RIFF chunk
h[ 1]=36 + DataSize ' size of WAVE chunk + data size
h[ 2]=FCC("WAVE") ' WAVE chunk
h[ 3]=FCC("fmt ") ' fmt chunk
h[ 4]=16 ' size of fmt chunk
h[ 5]=(nChannels Shl 16) Or 1 ' channels + PCM_FORMAT flag
h[ 6]=nRate ' playback rate
h[ 7]=BlkAlign*nRate ' bytes per sec.
h[ 8]=(nBits Shl 16) Or BlkAlign ' bits per sample + blockalign
h[ 9]=FCC("data") ' data chunk
h[10]=DataSize ' size of data chunk
End Sub

Type PCM_SAMPLE Field = 2
As Short l, r ' left and right channel
End Type

Sub Sound (Frequency As Double, Duration As Single, MaxVol As Integer = 128,_
ca As Single = 0, cd As Single = 0, csl As Single = 1, cr As Single = 0,_
MFrequency As Double = 0, ModStart As Double = 0, MaxModulator As Double = 0,_
ma As Single = 0, md As Single = 0, msl As Single = 1, mr As Single = 0)
Const nBuffers = 2
Var nSamples = 44100*Int(Duration/18.2) ' seconds
Var CS = 1 - CA - CD - CR
Var MS = 1 - MA - MD - MR
Dim As Double CEnvelopeInc, CEnvelopeDecD, CEnvelopeDecR
CEnvelopeInc = 100 * MaxVol / (nSamples * CA + 1)
CEnvelopeDecD = 100 * MaxVol * (1 - CSL) / (nSamples * CD + 1)
CEnvelopeDecR = 100 * MaxVol * CSL / (nSamples * CR + 1)
CD = CD + CA : CS = CS + CD : CR = CR + CS
Dim As Double MEnvelopeInc, MEnvelopeDecD, MEnvelopeDecR
MEnvelopeInc = MaxModulator / (nSamples * MA + 1)
MEnvelopeDecD = MaxModulator * (1 - MSL) / (nSamples * MD + 1)
MEnvelopeDecR = MaxModulator * MSL / (nSamples * MR + 1)
MD = MD + MA : MS = MS + MD : MR = MR + MS
Dim As PCM_SAMPLE PlayBuffers(nBuffers-1, -22 To nSamples-1)
For i As Integer = 0 To nBuffers-1
PrepareBuffer(@PlayBuffers(i,-22), nSamples)
Next
Dim Waveform As Single
Dim Modulator As Single
Dim As Integer buffer,ret
Dim Volume As Double = 0
Dim MAmp As Double = 0
' fill the first buffer with sine wave
For i As Integer = 0 To nSamples-1
If i <= CA * nSamples Then
Volume = Volume + CEnvelopeInc
Elseif i < CD * nSamples Then
Volume = Volume - CEnvelopeDecD
Elseif i < CS * nSamples Then
Elseif i < CR * nSamples Then
Volume = Volume - CEnvelopeDecR
End If
If i <= MA * nSamples Then
Mamp = Mamp + MEnvelopeInc
Elseif i < MD * nSamples Then
Mamp = Mamp - MEnvelopeDecD
Elseif i < MS * nSamples Then
Elseif i < MR * nSamples Then
Mamp = Mamp - MEnvelopeDecR
End If
Modulator = Cos(6.28/44100 * i * MFrequency + ModStart) * MAmp
Waveform = Sin(6.28/44100 * i * Frequency + Modulator) * Volume
PlayBuffers(buffer,i).l = Waveform
PlayBuffers(buffer,i).r = Waveform
Next
ret = PlayMemory(@PlayBuffers(buffer, -22))
End Sub


Sound 440, 5000
'This is the base syntax, works exactly like in QB
'Sound Frequency, Duration , Volume, A, D, S, R, ModFreq, ModStart, ModAmplitude, MA, MD, MS, MR
</syntaxhighlight>


=={{header|Go}}==
=={{header|Go}}==
Line 15: Line 331:
<br>
<br>
Go lacks audio support in its standard library and, whilst there are third party packages that could be used, an easier approach is to invoke the SoX utility's 'play' command as was done in the second Kotlin example.
Go lacks audio support in its standard library and, whilst there are third party packages that could be used, an easier approach is to invoke the SoX utility's 'play' command as was done in the second Kotlin example.
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 31: Line 347:
fmt.Println(err)
fmt.Println(err)
}
}
}</lang>
}</syntaxhighlight>

=={{header|J}}==
Approximately 1751 Hz (slightly flat A, two octaves above middle C), five seconds duration:
<syntaxhighlight lang="j"> require'media/wav'
4 wavplay wavmake <.1e3*1 o.i.55e3
</syntaxhighlight>

For simplicity, we use rely on a default wav sample rate of 11khz. Also, for simplicity, we are taking the sine of integer values (0, 1, 2, 3, 4, 5, 6), which gives us slightly more than six samples per cycle. 1e3 here represents the amplitude of our wave, which is interpreted as a signed 16 bit integer. So we're about 30 decibels below max volume (a factor of 10 in amplitude is a difference of 20 decibels):

<syntaxhighlight lang="j"> 20*10 ^. (2^15) % 1e3, 2^15
30.309 0</syntaxhighlight>


=={{header|JavaScript}}==
=={{header|JavaScript}}==
<lang javascript>let ctx = new (window.AudioContext || window.webkitAudioContext)();
<syntaxhighlight lang="javascript">let ctx = new (window.AudioContext || window.webkitAudioContext)();
let osc = ctx.createOscillator();
let osc = ctx.createOscillator();
osc.frequency.setValueAtTime(440, ctx.currentTime);
osc.frequency.setValueAtTime(440, ctx.currentTime);
osc.connect(ctx.destination);
osc.connect(ctx.destination);
osc.start();
osc.start();
osc.stop(ctx.currentTime + 5);</lang>
osc.stop(ctx.currentTime + 5);</syntaxhighlight>

=={{header|Julia}}==
PortAudio library version.
<syntaxhighlight lang="julia">using PortAudio

function paudio()
devs = PortAudio.devices()
devnum = findfirst(x -> x.maxoutchans > 0, devs)
(devnum == nothing) && error("No output device for audio found")
return ostream = PortAudioStream(devs[devnum].name, 0, 2)
end

function play(ostream, pitch, durationseconds)
sinewave(t) = 0.6sin(t) + 0.2sin(2t) + .05sin(8t)
timesamples = 0:(1 / 44100):(durationseconds * 0.98)
v = Float64[sinewave(2π * pitch * t) for t in timesamples]
write(ostream, v)
sleep(durationseconds * 0.9)
end

play(paudio(), 440.0, 5.0)
</syntaxhighlight>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
===Using Java Sound API===
===Using Java Sound API===
<lang scala>// Version 1.2.41
<syntaxhighlight lang="scala">// Version 1.2.41


import javax.sound.sampled.AudioFormat
import javax.sound.sampled.AudioFormat
Line 73: Line 422:
close()
close()
}
}
}</lang>
}</syntaxhighlight>


===Invoking SoX===
===Invoking SoX===
An easier approach invoking the SoX utility's 'play' command which has this stuff built-in. The following was tested on Ubuntu 16.04.
An easier approach invoking the SoX utility's 'play' command which has this stuff built-in. The following was tested on Ubuntu 16.04.
<lang scala>// Version 1.2.41
<syntaxhighlight lang="scala">// Version 1.2.41


fun main(args:Array<String>) {
fun main(args:Array<String>) {
Line 87: Line 436:
val proc = pb.start()
val proc = pb.start()
proc.waitFor()
proc.waitFor()
}</lang>
}</syntaxhighlight>


=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">EmitSound[Play[Sin[440 2 Pi t], {t, 0, 5}]]</syntaxhighlight>

=={{header|Nim}}==
Using Sox external player.
<syntaxhighlight lang="nim">import osproc, strutils

proc getIntValue(msg: string; minval, maxval: int): int =
while true:
stdout.write msg
stdout.flushFile()
try:
result = stdin.readLine.strip().parseInt()
if result notin minval..maxval:
echo "Invalid value"
else:
return
except ValueError:
echo "Error: invalid value."
except EOFError:
echo()
quit "Quitting.", QuitFailure

let freq = getIntValue("Enter frequency in Hz (40 to 10000): ", 40, 10_000)
let duration = 5
let kind = "sine"
let args = ["-n", "synth", $duration, $kind, $freq]
echo execProcess("play", args = args, options = {poStdErrToStdOut, poUsePath})</syntaxhighlight>


=={{header|OCaml}}==
=={{header|OCaml}}==


{{libheader|SFML}}
<lang ocaml>module BA = Bigarray
{{libheader|ocaml-sfml}}

<syntaxhighlight lang="ocaml">module BA = Bigarray
module BA1 = Bigarray.Array1
module BA1 = Bigarray.Array1


Line 119: Line 499:
while true do
while true do
SFTime.sleep (SFTime.of_milliseconds 100_l);
SFTime.sleep (SFTime.of_milliseconds 100_l);
done</lang>
done</syntaxhighlight>


To run this code in script mode you can add this at the beginning of the file:
To run this code in script mode you can add this at the beginning of the file:


<lang ocaml>#directory "+sfml"
<syntaxhighlight lang="ocaml">#directory "+sfml"
#load "bigarray.cma"
#load "bigarray.cma"
#load "sfml_system.cma"
#load "sfml_system.cma"
#load "sfml_audio.cma"</lang>
#load "sfml_audio.cma"</syntaxhighlight>
Then run:
Then run:
<pre>ocaml sine_wave.ml</pre>
<pre>ocaml sine_wave.ml</pre>
Line 135: Line 515:
</pre>
</pre>


=={{header|Perl}}==
<syntaxhighlight lang="perl">use Audio::NoiseGen qw(play sine);


Audio::NoiseGen::init() || die 'No access to sound hardware?';
=={{header|Perl 6}}==

alarm 5;
play( gen => sine( freq => 440 ) );</syntaxhighlight>

=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (dll/c_proc, system, prompt_number)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">k32</span><span style="color: #0000FF;">=</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">xBeep</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">beep</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">frequency</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">duration</span><span style="color: #0000FF;">=</span><span style="color: #000000;">5000</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">WINDOWS</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">k32</span><span style="color: #0000FF;">=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">k32</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">open_dll</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"kernel32.dll"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">xBeep</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">define_c_proc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k32</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Beep"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">C_INT</span><span style="color: #0000FF;">,</span><span style="color: #000000;">C_INT</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">c_proc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xBeep</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">frequency</span><span style="color: #0000FF;">,</span><span style="color: #000000;">duration</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">elsif</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">LINUX</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">system</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"play -n synth %f sine %d"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">duration</span><span style="color: #0000FF;">/</span><span style="color: #000000;">1000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">frequency</span><span style="color: #0000FF;">}))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">beep</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">prompt_number</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"Enter Frequency (100..10000 recommended):"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">0x25</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0x7FFF</span><span style="color: #0000FF;">}))</span>
<!--</syntaxhighlight>-->

=={{header|Processing}}==
Requires Processing Sound library.
<syntaxhighlight lang="java">
import processing.sound.*;

SinOsc sine;

size(500,500);

sine = new SinOsc(this);
sine.freq(500);
sine.play();

delay(5000);
</syntaxhighlight>

=={{header|Python}}==
{{trans|Emacs Lisp}}
<syntaxhighlight lang="python">#!/usr/bin/env python

import os
from math import pi, sin

# AU file header
au_header = bytearray(
[46, 115, 110, 100, # ".snd" magic number
0, 0, 0, 24, # start of data bytes
255, 255, 255, 255, # file size is unknown
0, 0, 0, 3, # 16 bit PCM samples
0, 0, 172, 68, # 44,100 samples/s
0, 0, 0, 1]) # mono

def f(x, freq):
"Compute sine wave as 16-bit integer"
return round(32000 * sin(2 * pi * freq * x / 44100)) % 65536

def play_sine(freq=440, duration=5, oname="pysine.au"):
"Play a sine wave for `duration` seconds"
out = open(oname, 'wb')
out.write(au_header)
v = [f(x, freq) for x in range(duration * 44100 + 1)]
s = []
for i in v:
s.append(i >> 8)
s.append(i % 256)
out.write(bytearray(s))
out.close()
os.system("vlc " + oname) # starts an external media player to play file

play_sine()</syntaxhighlight>
Creates an AU file with the sine wave and plays it with VLC.

=={{header|Racket}}==
See https://docs.racket-lang.org/rsound/index.html
<syntaxhighlight lang="racket">
#lang racket
(require rsound)
; 440 Hz, 50% volume, 5 seconds
(play (make-tone 440 0.50 (* 5 FRAME-RATE)))
</syntaxhighlight>

=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2018.04.01}}
{{works with|Rakudo|2018.04.01}}
What a horribly underspecified task. Ah well, gives me lots of wiggle room to cheat in various ways.
What a horribly underspecified task. Ah well, gives me lots of wiggle room to cheat in various ways.


<lang perl6>my ($rows,$cols) = qx/stty size/.words;
<syntaxhighlight lang="raku" line>my ($rows,$cols) = qx/stty size/.words;
my $v = floor $rows / 2;
my $v = floor $rows / 2;
print "\e[H\e[J", 'Generating sine wave of zero amplitude and zero frequency for 5 seconds...',
print "\e[H\e[J", 'Generating sine wave of zero amplitude and zero frequency for 5 seconds...',
Line 163: Line 632:
say 'Oops, too late.';
say 'Oops, too late.';
say 'Still no? Ok how about:';
say 'Still no? Ok how about:';
shell 'play -n -c1 synth 5.0 sin %-12';</lang>
shell 'play -n -c1 synth 5.0 sin %-12';</syntaxhighlight>


=={{header|Phix}}==
=={{header|REXX}}==
Note: &nbsp; This REXX program will <u>only</u> work for PC/REXX or Personal REXX.
<lang Phix>atom k32=NULL, xBeep
<syntaxhighlight lang="rexx">/*REXX program produces a sine wave (of a specified frequency) for N seconds. */
parse arg freq time . /*obtain optional arguments from the CL*/
procedure beep(integer frequency, duration=5000)
if freq=='' | freq=="," then freq= 880 /*Not specified? Then use the default.*/
if platform()=WINDOWS then
if time=='' | time=="," then time= 5 /* " " " " " " */
if k32=NULL then
call sound freq, time /*invoke a BIF to generate a sine wave.*/
k32 = open_dll("kernel32.dll")
exit 0 /*stick a fork in it, we're all done. */</syntaxhighlight><br><br<
xBeep = define_c_proc(k32, "Beep", {C_INT,C_INT})
end if
c_proc(xBeep,{frequency,duration})
elsif platform()=LINUX then
system(sprintf("play -n synth %f sine %d", {duration/1000, frequency}))
end if
end procedure
beep(prompt_number("Enter Frequency (100..10000 recommended):",{0x25,0x7FFF}))</lang>


=={{header|Scala}}==
=={{header|Scala}}==
<lang Scala>import javax.sound.sampled.{AudioFormat, AudioSystem, SourceDataLine}
<syntaxhighlight lang="scala">import javax.sound.sampled.{AudioFormat, AudioSystem, SourceDataLine}


import scala.math.{Pi, sin}
import scala.math.{Pi, sin}
Line 207: Line 668:
line.close()
line.close()


}</lang>
}</syntaxhighlight>

=={{header|Uiua}}==
{{works with|Uiua|0.11.0-dev.1}}
[https://www.uiua.org Uiua Pad] has built-in audio support for suitable arrays, so this will play a standard A for 5 seconds.
<syntaxhighlight lang="Uiua">
∿×τ×440×⟜(÷⟜⇡.×&asr) 5
</syntaxhighlight>

=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-sound}}
As Wren-cli doesn't have any built-in audio support, we instead build a .wav file which can then be played using a utility such as rhythmbox or SoX,
<syntaxhighlight lang="wren">import "./sound" for Wav

var sineWave = Fn.new { |frequency, seconds, sampleRate|
var samples = seconds * sampleRate
var result = List.filled(samples, 0)
var interval = sampleRate / frequency
for (i in 0...samples) {
var angle = 2 * Num.pi * i / interval
var b = (angle.sin * 127).truncate
result[i] = (b >= 0) ? b : 256 + b
}
return result
}

var sampleRate = 44000
var buffer = sineWave.call(440, 5, sampleRate)
Wav.create("sinewave.wav", buffer, sampleRate)</syntaxhighlight>

=={{header|Yabasic}}==
<syntaxhighlight lang="yabasic">// Rosetta Code problem: http://rosettacode.org/wiki/Sine_wave
// by Galileo, 05/2022

sub MyBeep(frequency, duration)
local n
if duration = 0 duration = 5000
if peek$("os") = "unix" then
system("play -n synth " + str$(duration/1000) + " sine " + str$(frequency))
else
n = foreign_function_call("kernel32.dll", "uint8","Beep","uint32",frequency,"uint32",duration)
end if
end sub

MyBeep(440)</syntaxhighlight>

=={{header|zkl}}==
{{trans|Go}}
Running on Mint Linux
<syntaxhighlight lang="zkl">fcn sineWave(durationInSec=5, frequency=440){
synthType:="sine";
cmd:="play -n synth %d %s %d".fmt(durationInSec,synthType,frequency);
s:=System.cmd(cmd);
// if(s!=0) play issued error
}

sineWave();</syntaxhighlight>

Latest revision as of 22:52, 13 April 2024

Sine wave is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.


Task

Generate a sine wave:

  1. you choose the frequency of the wave
  2. generate a sine wave for 5 seconds
  3. play sound

AmigaBASIC

SOUND 440,77

The maximum allowed sound duration parameter in AmigaBASIC is 77 units. Since a second equals 18.2 sound units, this tone will only play for 4.23 seconds.

BASIC256

sound 440, 5000

C

Translation of: Python
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

// AU header (CD-quality audio)
int header[] = {46, 115, 110, 100, 0, 0, 0, 24,
                255, 255, 255, 255, 0, 0, 0, 3,
                0, 0, 172, 68, 0, 0, 0, 1};

int main(int argc, char *argv[]){
        float freq, dur;
        long i, v;

        if (argc < 3) {
                printf("Usage:\n");
                printf("  csine <frequency> <duration>\n");
                exit(1);
        }
        freq = atof(argv[1]);
        dur = atof(argv[2]);
        for (i = 0; i < 24; i++)
                putchar(header[i]);
        for (i = 0; i < dur * 44100; i++) {
                v = (long) round(32000. * sin(2. * M_PI * freq * i / 44100.));
                v = v % 65536;
                putchar(v >> 8);
                putchar(v % 256);
        }
}

Test:

gcc -o csine csine.c -lm
./csine 440 5 | play -    # Now either pipe output into SoX to play
./csine 440 5 > test.au   # or redirect output to a file.

Delphi

Copy of Andreas Rejbrand example found here [1].

program Sine_wave;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  Winapi.Windows,
  Winapi.MMSystem;

type
  TWaveformSample = integer; // signed 32-bit; -2147483648..2147483647

  TWaveformSamples = packed array of TWaveformSample; // one channel

var
  Samples: TWaveformSamples;
  fmt: TWaveFormatEx;

procedure InitAudioSys;
begin
  with fmt do
  begin
    wFormatTag := WAVE_FORMAT_PCM;
    nChannels := 1;
    nSamplesPerSec := 44100;
    wBitsPerSample := 32;
    nAvgBytesPerSec := nChannels * nSamplesPerSec * wBitsPerSample div 8;
    nBlockAlign := nChannels * wBitsPerSample div 8;
    cbSize := 0;
  end;
end;
                                          // Hz                     // msec

procedure CreatePureSineTone(const AFreq: integer; const ADuration: integer;
  const AVolume: double { in [0, 1] });
var
  i: Integer;
  omega, dt, t: double;
  vol: double;
begin
  omega := 2 * Pi * AFreq;
  dt := 1 / fmt.nSamplesPerSec;
  t := 0;
  vol := MaxInt * AVolume;
  SetLength(Samples, Round((ADuration / 1000) * fmt.nSamplesPerSec));
  for i := 0 to high(Samples) do
  begin
    Samples[i] := round(vol * sin(omega * t));
    t := t + dt;
  end;
end;

procedure PlaySound;
var
  wo: integer;
  hdr: TWaveHdr;
begin

  if Length(samples) = 0 then
  begin
    Writeln('Error: No audio has been created yet.');
    Exit;
  end;

  if waveOutOpen(@wo, WAVE_MAPPER, @fmt, 0, 0, CALLBACK_NULL) = MMSYSERR_NOERROR then
  try

    ZeroMemory(@hdr, sizeof(hdr));
    with hdr do
    begin
      lpData := @samples[0];
      dwBufferLength := fmt.nChannels * Length(Samples) * sizeof(TWaveformSample);
      dwFlags := 0;
    end;

    waveOutPrepareHeader(wo, @hdr, sizeof(hdr));
    waveOutWrite(wo, @hdr, sizeof(hdr));
    sleep(500);

    while waveOutUnprepareHeader(wo, @hdr, sizeof(hdr)) = WAVERR_STILLPLAYING do
      sleep(100);

  finally
    waveOutClose(wo);
  end;

end;

begin
  try
    InitAudioSys;
    CreatePureSineTone(440, 5000, 0.7);
    PlaySound;
  except
    on E: Exception do
    begin
      Writeln(E.Classname, ': ', E.Message);
      Readln;
    end;
  end;
end.

Emacs Lisp

Note that this code does not work on Windows because playing sound from Emacs Lisp data variables is not supported there.

8-bit samples

(defun play-sine (freq dur)
  "Play a sine wave for dur seconds."
  (setq header (unibyte-string     ; AU header:
                  46 115 110 100   ;   ".snd" magic number
                  0 0 0 24         ;   start of data bytes
                  255 255 255 255  ;   file size is unknown
                  0 0 0 3          ;   16 bit PCM samples
                  0 0 172 68       ;   44,100 samples/s
                  0 0 0 1))        ;   mono
  (setq s (apply #'concat header (mapcar (lambda (x) (unibyte-string
               (mod (round (* 127 (sin (* 2 pi freq x (/ 44100.0))))) 256) 0))
               (number-sequence 0 (* dur 44100)))))
  (play-sound `(sound :data ,s)))

(play-sine 440 5)

While the generated AU sound file is 16 bit, the samples themselves are 8 bit because only their high byte is set by the sine function. Therefore you will hear some faint hiss in the background due to the higher noise floor of 8-bit audio.

16-bit samples

This (slightly slower) version of the function creates proper 16-bit samples by setting both high and low bytes, resulting in less playback noise.

(defun play-sine16 (freq dur)
  "Play a sine wave for dur seconds."
  (setq header (unibyte-string     ; AU header:
                  46 115 110 100   ;   ".snd" magic number
                  0 0 0 24         ;   start of data bytes
                  255 255 255 255  ;   file size is unknown
                  0 0 0 3          ;   16 bit PCM samples
                  0 0 172 68       ;   44,100 samples/s
                  0 0 0 1))        ;   mono
  (setq v (mapcar (lambda (x)
               (mod (round (* 32000 (sin (* 2 pi freq x (/ 44100.0))))) 65536))
               (number-sequence 0 (* dur 44100))))
  (setq s (apply #'concat header (flatten-list (mapcar (lambda (x)
            (list (unibyte-string (ash x -8))
                  (unibyte-string (mod x 256))))
            v))))
  (play-sound `(sound :data ,s)))

(play-sine16 440 5)

FreeBASIC

This subroutine is able to generate complex sounds using only Windows API.

Original code programmed by Angelo Rosina [2]

Enum FLAGS
    _ASYNC       = &h000001
    _NODEFAULT   = &h000002
    _MEMORY      = &h000004
    _LOOP        = &h000008
    _NOSTOP      = &h000010
    _PURGE       = &h000040
    _APPLICATION = &h000080
    _NOWAIT      = &h002000
    _ALIAS       = &h010000
    _FILENAME    = &h020000
    _RESOURCE    = &h040000 Or _MEMORY
    _ALIAS_ID    = &h100000 Or _ALIAS
End Enum

#define    PLAYFLAG _NOWAIT Or _NOSTOP Or _MEMORY Or _ASYNC
#define SNDPLAYFLAG            _NOSTOP Or _MEMORY Or _ASYNC
#define FCC(c) *(cptr(Uinteger Ptr,@##c))
Declare Function    PlayMemory Alias "PlaySoundA"    (Byval As Any Ptr, Byval hModule As Any Ptr = 0, Byval flag As Integer = PLAYFLAG) As Integer
Declare Function sndPlayMemory Alias "sndPlaySoundA" (Byval As Any Ptr, Byval flag As Uinteger = SNDPLAYFLAG) As Integer
#inclib "winmm"

Sub PrepareBuffer(Byval lpBuffer As Any Ptr, _
    Byval nSamples  As Uinteger, _
    Byval nRate     As Uinteger = 44100, _
    Byval nBits     As Uinteger = 16, _
    Byval nChannels As Uinteger = 2)
    
    Dim As Uinteger Ptr h = lpBuffer 
    Dim As Uinteger BlkAlign = (nBits\8) * nChannels
    Dim As Uinteger DataSize = BlkAlign * nSamples
    h[ 0]=FCC("RIFF")                   ' RIFF chunk
    h[ 1]=36 + DataSize                 ' size of WAVE chunk + data size
    h[ 2]=FCC("WAVE")                   ' WAVE chunk
    h[ 3]=FCC("fmt ")                   ' fmt chunk
    h[ 4]=16                            ' size of fmt chunk
    h[ 5]=(nChannels Shl 16) Or 1       ' channels + PCM_FORMAT flag
    h[ 6]=nRate                         ' playback rate
    h[ 7]=BlkAlign*nRate                ' bytes per sec.
    h[ 8]=(nBits Shl 16) Or BlkAlign    ' bits per sample + blockalign
    h[ 9]=FCC("data")                   ' data chunk
    h[10]=DataSize                      ' size of data chunk
End Sub

Type PCM_SAMPLE Field = 2
    As Short l, r                       ' left and right channel
End Type

Sub Sound (Frequency As Double, Duration As Single, MaxVol As Integer = 128,_
    ca As Single = 0, cd As Single = 0, csl As Single = 1, cr As Single = 0,_
    MFrequency As Double = 0, ModStart As Double = 0, MaxModulator As Double = 0,_
    ma As Single = 0, md As Single = 0, msl As Single = 1, mr As Single = 0)
    
    Const nBuffers = 2
    Var nSamples = 44100*Int(Duration/18.2) ' seconds
    Var CS = 1 - CA - CD - CR
    Var MS = 1 - MA - MD - MR
    
    Dim As Double CEnvelopeInc, CEnvelopeDecD, CEnvelopeDecR
    CEnvelopeInc  = 100 * MaxVol / (nSamples * CA + 1)
    CEnvelopeDecD = 100 * MaxVol * (1 - CSL) / (nSamples * CD + 1)
    CEnvelopeDecR = 100 * MaxVol * CSL / (nSamples * CR + 1)
    
    CD = CD + CA : CS = CS + CD : CR = CR + CS
    
    Dim As Double MEnvelopeInc, MEnvelopeDecD, MEnvelopeDecR
    MEnvelopeInc  = MaxModulator / (nSamples * MA + 1)
    MEnvelopeDecD = MaxModulator * (1 - MSL) / (nSamples * MD + 1)
    MEnvelopeDecR = MaxModulator * MSL / (nSamples * MR + 1)
    
    MD = MD + MA : MS = MS + MD : MR = MR + MS
    
    Dim As PCM_SAMPLE PlayBuffers(nBuffers-1, -22 To nSamples-1)
    For i As Integer = 0 To nBuffers-1
        PrepareBuffer(@PlayBuffers(i,-22), nSamples)
    Next
    
    Dim Waveform As Single
    Dim Modulator As Single
    Dim As Integer buffer,ret
    Dim Volume As Double = 0
    Dim MAmp As Double = 0
    
    ' fill the first buffer with sine wave
    For i As Integer = 0 To nSamples-1
        
        If i <= CA * nSamples Then
            Volume = Volume + CEnvelopeInc
        Elseif i < CD * nSamples Then
            Volume = Volume - CEnvelopeDecD
        Elseif i < CS * nSamples Then
        Elseif i < CR * nSamples Then
            Volume = Volume - CEnvelopeDecR
        End If
        
        If i <= MA * nSamples Then
            Mamp = Mamp + MEnvelopeInc
        Elseif i < MD * nSamples Then
            Mamp = Mamp - MEnvelopeDecD
        Elseif i < MS * nSamples Then
        Elseif i < MR * nSamples Then
            Mamp = Mamp - MEnvelopeDecR
        End If
        
        Modulator = Cos(6.28/44100 * i * MFrequency + ModStart) * MAmp
        Waveform  = Sin(6.28/44100 * i * Frequency + Modulator) * Volume
        PlayBuffers(buffer,i).l = Waveform
        PlayBuffers(buffer,i).r = Waveform
    Next
    
    ret = PlayMemory(@PlayBuffers(buffer, -22))
End Sub


Sound 440, 5000
'This is the base syntax, works exactly like in QB
'Sound Frequency, Duration , Volume, A, D, S, R, ModFreq, ModStart, ModAmplitude, MA, MD, MS, MR

Go

Works with: Ubuntu 16.04


Go lacks audio support in its standard library and, whilst there are third party packages that could be used, an easier approach is to invoke the SoX utility's 'play' command as was done in the second Kotlin example.

package main

import (
    "fmt"
    "os/exec"
)

func main() {
    synthType := "sine"
    duration := "5"
    frequency := "440"
    cmd := exec.Command("play", "-n", "synth", duration, synthType, frequency)
    err := cmd.Run()
    if err != nil {
        fmt.Println(err)
    }
}

J

Approximately 1751 Hz (slightly flat A, two octaves above middle C), five seconds duration:

   require'media/wav'
   4 wavplay wavmake <.1e3*1 o.i.55e3

For simplicity, we use rely on a default wav sample rate of 11khz. Also, for simplicity, we are taking the sine of integer values (0, 1, 2, 3, 4, 5, 6), which gives us slightly more than six samples per cycle. 1e3 here represents the amplitude of our wave, which is interpreted as a signed 16 bit integer. So we're about 30 decibels below max volume (a factor of 10 in amplitude is a difference of 20 decibels):

   20*10 ^. (2^15) % 1e3, 2^15
30.309 0

JavaScript

let ctx = new (window.AudioContext || window.webkitAudioContext)();
let osc = ctx.createOscillator();
osc.frequency.setValueAtTime(440, ctx.currentTime);
osc.connect(ctx.destination);
osc.start();
osc.stop(ctx.currentTime + 5);

Julia

PortAudio library version.

using PortAudio

function paudio()
    devs = PortAudio.devices()
    devnum = findfirst(x -> x.maxoutchans > 0, devs)
    (devnum == nothing) && error("No output device for audio found")
    return ostream = PortAudioStream(devs[devnum].name, 0, 2)
end

function play(ostream, pitch, durationseconds)
    sinewave(t) = 0.6sin(t) + 0.2sin(2t) + .05sin(8t)
    timesamples = 0:(1 / 44100):(durationseconds * 0.98)
    v = Float64[sinewave(2π * pitch * t) for t in timesamples]
    write(ostream, v)
    sleep(durationseconds * 0.9)
end

play(paudio(), 440.0, 5.0)

Kotlin

Using Java Sound API

// Version 1.2.41

import javax.sound.sampled.AudioFormat
import javax.sound.sampled.AudioSystem
import kotlin.math.sin
import kotlin.math.PI

fun sineWave(frequency: Int, seconds: Int, sampleRate: Int): ByteArray {
    val samples = seconds * sampleRate
    val result = ByteArray(samples)
    val interval = sampleRate.toDouble() / frequency
    for (i in 0 until samples) {
        val angle = 2.0 * PI * i / interval
        result[i] = (sin(angle) * 127).toByte()
    }
    return result
}

fun main(args: Array<String>) {
    val sampleRate = 44000
    val buffer = sineWave(440, 5, sampleRate)
    val format = AudioFormat(sampleRate.toFloat(), 8, 1, true, true)
    val line = AudioSystem.getSourceDataLine(format)
    with (line) {
        open(format)
        start()
        write(buffer, 0, buffer.size)
        drain()
        close()
    }
}

Invoking SoX

An easier approach invoking the SoX utility's 'play' command which has this stuff built-in. The following was tested on Ubuntu 16.04.

// Version 1.2.41

fun main(args:Array<String>) {
    val synthType = "sine"
    val duration = "5"
    val frequency = "440"
    val pb = ProcessBuilder("play", "-n", "synth", duration, synthType, frequency)
    pb.directory(null)
    val proc = pb.start()
    proc.waitFor()
}

Mathematica/Wolfram Language

EmitSound[Play[Sin[440 2 Pi t], {t, 0, 5}]]

Nim

Using Sox external player.

import osproc, strutils

proc getIntValue(msg: string; minval, maxval: int): int =
  while true:
    stdout.write msg
    stdout.flushFile()
    try:
      result = stdin.readLine.strip().parseInt()
      if result notin minval..maxval:
        echo "Invalid value"
      else:
        return
    except ValueError:
      echo "Error: invalid value."
    except EOFError:
      echo()
      quit "Quitting.", QuitFailure

let freq = getIntValue("Enter frequency in Hz (40 to 10000): ", 40, 10_000)
let duration = 5
let kind = "sine"
let args = ["-n", "synth", $duration, $kind, $freq]
echo execProcess("play", args = args, options = {poStdErrToStdOut, poUsePath})

OCaml

Library: SFML
Library: ocaml-sfml
module BA = Bigarray
module BA1 = Bigarray.Array1

let () =
  let samples = 44100 in
  let sample_rate = 44100 in
  let amplitude = 30000. in
  
  let raw = BA1.create BA.int16_signed BA.c_layout samples in

  let two_pi = 6.28318 in
  let increment = 440.0 /. 44100.0 in
  let x = ref 0.0 in

  for i = 0 to samples - 1 do
    raw.{i} <- truncate (amplitude *. sin (!x *. two_pi));
    x := !x +. increment;
  done;
  
  let buffer = SFSoundBuffer.loadFromSamples raw 1 sample_rate in

  let snd = SFSound.create () in
  SFSound.setBuffer snd buffer;
  SFSound.setLoop snd true;
  SFSound.play snd;
  while true do
    SFTime.sleep (SFTime.of_milliseconds 100_l);
  done

To run this code in script mode you can add this at the beginning of the file:

#directory "+sfml"
#load "bigarray.cma"
#load "sfml_system.cma"
#load "sfml_audio.cma"

Then run:

ocaml sine_wave.ml

Or to compile to native code:

ocamlopt -I +sfml bigarray.cmxa sfml_system.cmxa sfml_audio.cmxa sine_wave.ml -o sine_wave.exe

Perl

use Audio::NoiseGen qw(play sine);

Audio::NoiseGen::init() || die 'No access to sound hardware?';

alarm 5;
play( gen => sine( freq => 440 ) );

Phix

without js -- (dll/c_proc, system, prompt_number)
atom k32=NULL, xBeep
 
procedure beep(integer frequency, duration=5000)
    if platform()=WINDOWS then
        if k32=NULL then
            k32 = open_dll("kernel32.dll")
            xBeep = define_c_proc(k32, "Beep", {C_INT,C_INT})
        end if
        c_proc(xBeep,{frequency,duration})
    elsif platform()=LINUX then
	system(sprintf("play -n synth %f sine %d", {duration/1000, frequency}))
    end if
end procedure
 
beep(prompt_number("Enter Frequency (100..10000 recommended):",{0x25,0x7FFF}))

Processing

Requires Processing Sound library.

import processing.sound.*;

SinOsc sine;

size(500,500);

sine = new SinOsc(this);
sine.freq(500);
sine.play();

delay(5000);

Python

Translation of: Emacs Lisp
#!/usr/bin/env python

import os
from math import pi, sin

# AU file header
au_header = bytearray(
            [46, 115, 110, 100,   #   ".snd" magic number
              0,   0,   0,  24,   #   start of data bytes
            255, 255, 255, 255,   #   file size is unknown
              0,   0,   0,   3,   #   16 bit PCM samples
              0,   0, 172,  68,   #   44,100 samples/s
              0,   0,   0,   1])  #   mono

def f(x, freq):
    "Compute sine wave as 16-bit integer"
    return round(32000 * sin(2 * pi * freq * x / 44100)) % 65536

def play_sine(freq=440, duration=5, oname="pysine.au"):
    "Play a sine wave for `duration` seconds"
    out = open(oname, 'wb')
    out.write(au_header)
    v = [f(x, freq) for x in range(duration * 44100 + 1)]
    s = []
    for i in v:
        s.append(i >> 8)
        s.append(i % 256)
    out.write(bytearray(s))
    out.close()
    os.system("vlc " + oname)   # starts an external media player to play file

play_sine()

Creates an AU file with the sine wave and plays it with VLC.

Racket

See https://docs.racket-lang.org/rsound/index.html

#lang racket
(require rsound)
; 440 Hz, 50% volume, 5 seconds
(play (make-tone 440 0.50 (* 5 FRAME-RATE)))

Raku

(formerly Perl 6)

Works with: Rakudo version 2018.04.01

What a horribly underspecified task. Ah well, gives me lots of wiggle room to cheat in various ways.

my ($rows,$cols) = qx/stty size/.words;
my $v = floor $rows / 2;
print "\e[H\e[J", 'Generating sine wave of zero amplitude and zero frequency for 5 seconds...',
  "\e[$v;0H", '_' x $cols;
sleep 5;
say "\e[H\e[J", 'No?, ok how about this:';

use SVG;
my $filename = 'sine.svg';
my $out = open($filename, :w) orelse .die;
$out.say: SVG.serialize(
    svg => [
        width => 400, height => 150, style => 'stroke:rgb(0,0,255)',
        :rect[:width<100%>, :height<100%>, :fill<white>],
        :path[ :fill<none>, :d('M0,25 C36.42,25,63.58,125,100,125 M100,125 C136.42,125,163.58,25,200,25 M200,25 C236.42,25,263.58,125,300,125 M300,125 C336.42,125,363.58,25,400,25') ],
    ],
);
close $out;
say "Sine wave generated to {$filename.IO.absolute}, better open it quickly...";
sleep 5;
unlink $filename;
say 'Oops, too late.';
say 'Still no? Ok how about:';
shell 'play -n -c1 synth 5.0 sin %-12';

REXX

Note:   This REXX program will only work for PC/REXX or Personal REXX.

/*REXX program  produces  a sine wave  (of a specified frequency)   for   N   seconds.  */
parse arg freq time .                            /*obtain optional arguments from the CL*/
if freq=='' | freq==","  then freq= 880          /*Not specified?  Then use the default.*/
if time=='' | time==","  then time=   5          /* "      "         "   "   "     "    */
call sound freq, time                            /*invoke a BIF to generate a sine wave.*/
exit 0                                           /*stick a fork in it,  we're all done. */


<br<

Scala

import javax.sound.sampled.{AudioFormat, AudioSystem, SourceDataLine}

import scala.math.{Pi, sin}

object SineWave extends App {
  val sampleRate = 44000
  val buffer = beep(440, 5, sampleRate)
  val line: SourceDataLine = AudioSystem.getSourceDataLine(format)

  def format = new AudioFormat(sampleRate.toFloat, 8, 1, true, false)

  def beep(frequency: Int, seconds: Int, sampleRate: Int) = {
    val samples = seconds * sampleRate
    val interval = sampleRate / frequency
    val angle = 2.0 * Pi  / interval
    (0 until samples).map(i => (sin(angle * i) * 127).toByte).toArray
  }

  line.open()
  line.start()
  line.write(buffer, 0, buffer.length)
  line.drain()
  line.close()

}

Uiua

Works with: Uiua version 0.11.0-dev.1

Uiua Pad has built-in audio support for suitable arrays, so this will play a standard A for 5 seconds.

∿×τ×440×⟜(÷⟜⇡.×&asr) 5

Wren

Translation of: Kotlin
Library: Wren-sound

As Wren-cli doesn't have any built-in audio support, we instead build a .wav file which can then be played using a utility such as rhythmbox or SoX,

import "./sound" for Wav

var sineWave = Fn.new { |frequency, seconds, sampleRate|
    var samples = seconds * sampleRate
    var result = List.filled(samples, 0)
    var interval = sampleRate / frequency
    for (i in 0...samples) {
        var angle = 2 * Num.pi * i / interval
        var b = (angle.sin * 127).truncate
        result[i] = (b >= 0) ? b : 256 + b
    }
    return result
} 

var sampleRate = 44000
var buffer = sineWave.call(440, 5, sampleRate)
Wav.create("sinewave.wav", buffer, sampleRate)

Yabasic

// Rosetta Code problem: http://rosettacode.org/wiki/Sine_wave
// by Galileo, 05/2022

sub MyBeep(frequency, duration)
    local n
    
    if duration = 0 duration = 5000
    
    if peek$("os") = "unix" then
        system("play -n synth " + str$(duration/1000) + " sine " + str$(frequency))
    else
        n = foreign_function_call("kernel32.dll", "uint8","Beep","uint32",frequency,"uint32",duration)
    end if
end sub

MyBeep(440)

zkl

Translation of: Go

Running on Mint Linux

fcn sineWave(durationInSec=5, frequency=440){
   synthType:="sine";
   cmd:="play -n synth %d %s %d".fmt(durationInSec,synthType,frequency);
   s:=System.cmd(cmd);
//   if(s!=0) play issued error
}

sineWave();