Sine wave

From Rosetta Code
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


Kotlin[edit]

Using Java Sound API[edit]

// 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[edit]

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()
}

Perl 6[edit]

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) or die "$!\n";
$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';