Sine wave
- Task
Generate a sine wave:
- you choose the frequency of the wave
- generate a sine wave for 5 seconds
- play sound
Go
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
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) }
}</lang>
Kotlin
Using Java Sound API
<lang scala>// 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() }
}</lang>
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. <lang scala>// 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()
}</lang>
Perl 6
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; 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';</lang>