Musical scale: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added Processing implementation)
m (syntax highlighting fixup automation)
Line 16: Line 16:


=={{header|Action!}}==
=={{header|Action!}}==
<lang Action!>DEFINE PTR="CARD"
<syntaxhighlight lang="action!">DEFINE PTR="CARD"


PROC Wait(BYTE frames)
PROC Wait(BYTE frames)
Line 61: Line 61:
AUDCTL=$00 ;restore default configuration
AUDCTL=$00 ;restore default configuration
Wait(20)
Wait(20)
RETURN</lang>
RETURN</syntaxhighlight>
{{out}}
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Musical_scale.png Screenshot from Atari 8-bit computer]
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Musical_scale.png Screenshot from Atari 8-bit computer]
Line 74: Line 74:
=={{header|AmigaBASIC}}==
=={{header|AmigaBASIC}}==


<lang amigabasic>FOR i=1 to 8
<syntaxhighlight lang="amigabasic">FOR i=1 to 8
READ f
READ f
SOUND f,10
SOUND f,10
NEXT
NEXT


DATA 261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25</lang>
DATA 261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25</syntaxhighlight>


=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
{{works with|AutoHotkey 1.1}}
{{works with|AutoHotkey 1.1}}
<lang AutoHotkey>for key, val in [261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25]
<syntaxhighlight lang="autohotkey">for key, val in [261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25]
SoundBeep, % val, 500</lang>
SoundBeep, % val, 500</syntaxhighlight>


=={{header|BASIC256}}==
=={{header|BASIC256}}==
<lang BASIC256>sound {261.63, 500, 293.66, 500, 329.63, 500, 349.23, 500, 392, 500, 440, 500, 493.88, 500, 523.25, 500}</lang>
<syntaxhighlight lang="basic256">sound {261.63, 500, 293.66, 500, 329.63, 500, 349.23, 500, 392, 500, 440, 500, 493.88, 500, 523.25, 500}</syntaxhighlight>


=={{header|Befunge}}==
=={{header|Befunge}}==
Line 94: Line 94:
The tune to be played is specified on the first line of the code. The notes are specified as MIDI note numbers in reverse order in a Befunge string (for example, ''Middle C'' is note number 60, which is the character "<"). This is followed by the count of notes in the string - 8 in this example.
The tune to be played is specified on the first line of the code. The notes are specified as MIDI note numbers in reverse order in a Befunge string (for example, ''Middle C'' is note number 60, which is the character "<"). This is followed by the count of notes in the string - 8 in this example.


<lang befunge>> "HGECA@><"8: v
<syntaxhighlight lang="befunge">> "HGECA@><"8: v
v0*73"MThd"0006010101"MTrk"000<
v0*73"MThd"0006010101"MTrk"000<
>>#1-#,:#\_$8*74++,0,28*"'"039v
>>#1-#,:#\_$8*74++,0,28*"'"039v
v,:,\,*2,1"Hd":\<,,,,,,*3"U"*9<
v,:,\,*2,1"Hd":\<,,,,,,*3"U"*9<
>"@1",2*,\,,1-:#^_"/3d",5*,,, @</lang>
>"@1",2*,\,,1-:#^_"/3d",5*,,, @</syntaxhighlight>


=={{header|C}}==
=={{header|C}}==
Line 111: Line 111:
It is therefore essential to call nosound() at the end which ends the speaker output, otherwise the Turbo C (DOS) session will have to be ended.
It is therefore essential to call nosound() at the end which ends the speaker output, otherwise the Turbo C (DOS) session will have to be ended.


<syntaxhighlight lang="c">
<lang c>
#include<stdio.h>
#include<stdio.h>
#include<conio.h>
#include<conio.h>
Line 138: Line 138:
nosound();
nosound();
return 0;
return 0;
}</lang>
}</syntaxhighlight>


===Windows C===
===Windows C===
Line 146: Line 146:
Beep() can only play integer frequencies and thus the tones are noticeably lower than the ones played by sound() above.
Beep() can only play integer frequencies and thus the tones are noticeably lower than the ones played by sound() above.


<syntaxhighlight lang="c">
<lang c>
#include<windows.h>
#include<windows.h>
#include<stdio.h>
#include<stdio.h>
Line 170: Line 170:
}
}
return 0;
return 0;
}</lang>
}</syntaxhighlight>


=={{header|C++}}==
=={{header|C++}}==
Uses Windows MIDI device
Uses Windows MIDI device
<lang cpp>
<syntaxhighlight lang="cpp">
#include <iostream>
#include <iostream>
#include <windows.h>
#include <windows.h>
Line 248: Line 248:
return 0;
return 0;
}
}
</syntaxhighlight>
</lang>


=={{header|Clojure}}==
=={{header|Clojure}}==
{{libheader|Overtone}}
{{libheader|Overtone}}
<lang clojure>(use 'overtone.live)
<syntaxhighlight lang="clojure">(use 'overtone.live)


; Define your desired instrument
; Define your desired instrument
Line 265: Line 265:
(Thread/sleep ms))
(Thread/sleep ms))


(doseq [note (scale :c4 :major)] (play note 500))</lang>
(doseq [note (scale :c4 :major)] (play note 500))</syntaxhighlight>


=={{header|Commodore BASIC}}==
=={{header|Commodore BASIC}}==
Line 272: Line 272:


'''Commodore 64'''
'''Commodore 64'''
<lang commodorebasic>10 rem musical scale
<syntaxhighlight lang="commodorebasic">10 rem musical scale
15 rem rosetta code
15 rem rosetta code
20 print chr$(147)
20 print chr$(147)
Line 289: Line 289:
90 for d=1 to 25:next
90 for d=1 to 25:next
95 next i
95 next i
500 data 261.63,293.66,329.63,349.23,392,440,493.88,523.25</lang>
500 data 261.63,293.66,329.63,349.23,392,440,493.88,523.25</syntaxhighlight>


'''Commodore 128'''
'''Commodore 128'''
<lang commodorebasic>10 print chr$(147)
<syntaxhighlight lang="commodorebasic">10 print chr$(147)
20 play "o4 cdefgab o5 c"</lang>
20 play "o4 cdefgab o5 c"</syntaxhighlight>


Line 299: Line 299:
=={{header|Delphi}}==
=={{header|Delphi}}==
{{libheader| Winapi.Windows}}
{{libheader| Winapi.Windows}}
<syntaxhighlight lang="delphi">
<lang Delphi>
program Musical_scale;
program Musical_scale;


Line 315: Line 315:
Beep(Round(note), 500);
Beep(Round(note), 500);
readln;
readln;
end.</lang>
end.</syntaxhighlight>


=={{header|EasyLang}}==
=={{header|EasyLang}}==


<lang>n[] = [ 262 294 330 349 392 440 494 523 ]
<syntaxhighlight lang="text">n[] = [ 262 294 330 349 392 440 494 523 ]
for i range len n[]
for i range len n[]
sound [ n[i] 0.5 ]
sound [ n[i] 0.5 ]
sleep 0.6
sleep 0.6
.</lang>
.</syntaxhighlight>


=={{header|Emacs Lisp}}==
=={{header|Emacs Lisp}}==
Line 329: Line 329:


Does not work with the Windows version of Emacs.
Does not work with the Windows version of Emacs.
<lang lisp>(defun play-scale (freq-list dur)
<syntaxhighlight lang="lisp">(defun play-scale (freq-list dur)
"Play a list of frequencies."
"Play a list of frequencies."
(setq header (unibyte-string ; AU header:
(setq header (unibyte-string ; AU header:
Line 350: Line 350:
(play-sound `(sound :data ,s)))
(play-sound `(sound :data ,s)))


(play-scale '(261.63 293.66 329.63 349.23 392.00 440.00 493.88 523.25) .5)</lang>
(play-scale '(261.63 293.66 329.63 349.23 392.00 440.00 493.88 523.25) .5)</syntaxhighlight>


=={{header|Forth}}==
=={{header|Forth}}==
As a low level stack language Forth programming methodology prefers short simple definitions that extend the language in the direction that allows you to solve the problem. The creation of application specific language is common in Forth.
As a low level stack language Forth programming methodology prefers short simple definitions that extend the language in the direction that allows you to solve the problem. The creation of application specific language is common in Forth.
This demonstration code uses the PC speaker to generate musical tones. A simple device driver is created for hardware control via PORT I/O. A set of primitive operations are created to control the on:off times of the sounds. Then a small MUSIC language is created to create notes of different types. Finally 2 scales are created using "crotcheted notes" as they are called. We chose 1/8 notes. For fun we added the ability to change the expression of the notes using Italian musical terms.
This demonstration code uses the PC speaker to generate musical tones. A simple device driver is created for hardware control via PORT I/O. A set of primitive operations are created to control the on:off times of the sounds. Then a small MUSIC language is created to create notes of different types. Finally 2 scales are created using "crotcheted notes" as they are called. We chose 1/8 notes. For fun we added the ability to change the expression of the notes using Italian musical terms.
<lang>HEX
<syntaxhighlight lang="text">HEX
\ PC speaker hardware control (requires giveio or DOSBOX for windows operation)
\ PC speaker hardware control (requires giveio or DOSBOX for windows operation)
042 constant fctrl 061 constant sctrl
042 constant fctrl 061 constant sctrl
Line 444: Line 444:
: Cmajor 1/8 C3 D3 E3 F3 G3 A3 B3 C4 ;
: Cmajor 1/8 C3 D3 E3 F3 G3 A3 B3 C4 ;
: Chromatic 1/8 C3 C#3 D3 D#3 E3 F3 F#3 G3 G#3 A3 A#3 B3 C4 ;
: Chromatic 1/8 C3 C#3 D3 D#3 E3 F3 F#3 G3 G#3 A3 A#3 B3 C4 ;
</syntaxhighlight>
</lang>
Interactive test at the Console
Interactive test at the Console
<pre>music ok
<pre>music ok
Line 454: Line 454:


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
<lang freebasic>REM FreeBASIC no tiene la capacidad de emitir sonido de forma nativa.
<syntaxhighlight lang="freebasic">REM FreeBASIC no tiene la capacidad de emitir sonido de forma nativa.
REM La función Sound no es mía, incluyo los créditos correspondientes.
REM La función Sound no es mía, incluyo los créditos correspondientes.
' Sound Function v0.3 For DOS/Linux/Win by yetifoot
' Sound Function v0.3 For DOS/Linux/Win by yetifoot
Line 526: Line 526:
Sound(494, 250) 'B4
Sound(494, 250) 'B4
Sound(523, 250) 'C5
Sound(523, 250) 'C5
Sleep</lang>
Sleep</syntaxhighlight>
=={{header|FreePascal}}==
=={{header|FreePascal}}==
<lang pascal>{$mode objfpc}
<syntaxhighlight lang="pascal">{$mode objfpc}
uses windows,math;{ windows only }
uses windows,math;{ windows only }
var
var
Line 536: Line 536:
for i:= 0 to 11 do
for i:= 0 to 11 do
beep(Round(440.0*interval**i),500);
beep(Round(440.0*interval**i),500);
end.</lang>
end.</syntaxhighlight>


=={{header|Go}}==
=={{header|Go}}==
Line 542: Line 542:
<br>
<br>
As Go doesn't have any audio support in its standard library, we instead build a .wav file which can then be played using a utility such as SoX.
As Go doesn't have any audio support in its standard library, we instead build a .wav file which can then be played using a utility such as SoX.
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 608: Line 608:
}
}
}
}
}</lang>
}</syntaxhighlight>


=={{header|J}}==
=={{header|J}}==


<lang J>require'media/wav'
<syntaxhighlight lang="j">require'media/wav'
0.25 wavnote 0 2 4 5 7 9 11 12</lang>
0.25 wavnote 0 2 4 5 7 9 11 12</syntaxhighlight>


This assumes a version such as J6 which supports media/wav.
This assumes a version such as J6 which supports media/wav.
Line 623: Line 623:
=={{header|JavaScript}}==
=={{header|JavaScript}}==
Using the Web Audio API
Using the Web Audio API
<lang javascript><!doctype html>
<syntaxhighlight lang="javascript"><!doctype html>
<html>
<html>
<head>
<head>
Line 660: Line 660:
</script>
</script>
</body>
</body>
</html></lang>
</html></syntaxhighlight>


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


function paudio()
function paudio()
Line 688: Line 688:
sleep(0.4)
sleep(0.4)
end
end
</syntaxhighlight>
</lang>


=={{header|Kotlin}}==
=={{header|Kotlin}}==
Line 694: Line 694:


When building win32.klib from windows.h, one needs to make sure NOT to filter out utilapiset.h because this is where the Beep function now resides, not in winbase.h as stated in the MSDN documentation.
When building win32.klib from windows.h, one needs to make sure NOT to filter out utilapiset.h because this is where the Beep function now resides, not in winbase.h as stated in the MSDN documentation.
<lang scala>// Kotlin Native v0.3
<syntaxhighlight lang="scala">// Kotlin Native v0.3


import kotlinx.cinterop.*
import kotlinx.cinterop.*
Line 703: Line 703:
val dur = 500
val dur = 500
repeat(5) { for (freq in freqs) Beep(freq, dur) }
repeat(5) { for (freq in freqs) Beep(freq, dur) }
}</lang>
}</syntaxhighlight>


=={{header|Lilypond}}==
=={{header|Lilypond}}==
The lilypond tool produces musical score sheets and midi files - if asked for - but does not output notes to the sound device directly.
The lilypond tool produces musical score sheets and midi files - if asked for - but does not output notes to the sound device directly.
<lang lilypond>% Start at middle C
<syntaxhighlight lang="lilypond">% Start at middle C
\relative c' {
\relative c' {
c d e f
c d e f
g a b c
g a b c
}</lang>
}</syntaxhighlight>


=={{header|Locomotive Basic}}==
=={{header|Locomotive Basic}}==


<lang locobasic>10 mode 1
<syntaxhighlight lang="locobasic">10 mode 1
20 print "Note","Freq. (Hz)","Period"
20 print "Note","Freq. (Hz)","Period"
30 ' program loop:
30 ' program loop:
Line 730: Line 730:
140 sound 1,p,100
140 sound 1,p,100
150 return
150 return
160 data 1,3,5,6,8,10,12,13,-1</lang>
160 data 1,3,5,6,8,10,12,13,-1</syntaxhighlight>


=={{header|Lua}}==
=={{header|Lua}}==
Line 736: Line 736:
===Lua Portable===
===Lua Portable===
The most portable native solution that could actually ''play'' the scale (''with some external help from a media player'') would be to write a MIDI file..
The most portable native solution that could actually ''play'' the scale (''with some external help from a media player'') would be to write a MIDI file..
<lang lua>c = string.char
<syntaxhighlight lang="lua">c = string.char
midi = "MThd" .. c(0,0,0,6,0,0,0,1,0,96) -- header
midi = "MThd" .. c(0,0,0,6,0,0,0,1,0,96) -- header
midi = midi .. "MTrk" .. c(0,0,0,8*8+4) -- track
midi = midi .. "MTrk" .. c(0,0,0,8*8+4) -- track
Line 749: Line 749:


-- (optional: hex dump to screen)
-- (optional: hex dump to screen)
midi:gsub(".", function(c) io.write(string.format("%02X ", string.byte(c))) end)</lang>
midi:gsub(".", function(c) io.write(string.format("%02X ", string.byte(c))) end)</syntaxhighlight>
{{out}}
{{out}}
<pre>4D 54 68 64 00 00 00 06 00 00 00 01 00 60 4D 54 72 6B 00 00 00 44 00 90 3C 40 60 80 3C 00 00 90 3E 40 60 80 3E 00 00 90 40 40 60 80 40 00 00 90 41 40 60 80 41 00 00 90 43 40 60 80 43 00 00 90 45 40 60 80 45 00 00 90 47 40 60 80 47 00 00 90 48 40 60 80 48 00 00 FF 2F 00</pre>
<pre>4D 54 68 64 00 00 00 06 00 00 00 01 00 60 4D 54 72 6B 00 00 00 44 00 90 3C 40 60 80 3C 00 00 90 3E 40 60 80 3E 00 00 90 40 40 60 80 40 00 00 90 41 40 60 80 41 00 00 90 43 40 60 80 43 00 00 90 45 40 60 80 45 00 00 90 47 40 60 80 47 00 00 90 48 40 60 80 48 00 00 FF 2F 00</pre>
Line 755: Line 755:
===Lua ASCII===
===Lua ASCII===
The task allows for score output, which could also be done natively..
The task allows for score output, which could also be done natively..
<lang lua>staff = {
<syntaxhighlight lang="lua">staff = {
lines = { "", "", "", "", "", "", "", "", "", "", "" },
lines = { "", "", "", "", "", "", "", "", "", "", "" },
nnotes = 0,
nnotes = 0,
Line 781: Line 781:
end
end
staff:measure()
staff:measure()
staff:dump()</lang>
staff:dump()</syntaxhighlight>
{{out}}
{{out}}
<pre>|----------------|----------------|
<pre>|----------------|----------------|
Line 797: Line 797:
===Lua Windows===
===Lua Windows===
Non-portable, O/S-specific, requires <code>alien</code> library..
Non-portable, O/S-specific, requires <code>alien</code> library..
<lang lua>beep = require"alien".kernel32.Beep
<syntaxhighlight lang="lua">beep = require"alien".kernel32.Beep
beep:types{ret='long', abi='stdcall', 'long', 'long'}
beep:types{ret='long', abi='stdcall', 'long', 'long'}
for _,step in ipairs{0,2,4,5,7,9,11,12} do
for _,step in ipairs{0,2,4,5,7,9,11,12} do
beep(math.floor(261.63 * 2^(step/12) + 0.5), 1000)
beep(math.floor(261.63 * 2^(step/12) + 0.5), 1000)
end</lang>
end</syntaxhighlight>


=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
Line 809: Line 809:
TUNE use kernel [https://msdn.microsoft.com/en-us/library/windows/desktop/ms679277(v=vs.85).aspx Beep] which is synchronous and not leaving M2000 threads to process, until ends.
TUNE use kernel [https://msdn.microsoft.com/en-us/library/windows/desktop/ms679277(v=vs.85).aspx Beep] which is synchronous and not leaving M2000 threads to process, until ends.


<lang>
<syntaxhighlight lang="text">
Module checkit {
Module checkit {
\\ using internal speaker
\\ using internal speaker
Line 824: Line 824:
}
}
checkit
checkit
</syntaxhighlight>
</lang>


=={{header|Mathematica}}/{{header|Wolfram Language}}==
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<lang mathematica>EmitSound@Sound[SoundNote /@ {0, 2, 4, 5, 7, 9, 11, 12}]</lang>
<syntaxhighlight lang="mathematica">EmitSound@Sound[SoundNote /@ {0, 2, 4, 5, 7, 9, 11, 12}]</syntaxhighlight>


=={{header|Nanoquery}}==
=={{header|Nanoquery}}==
<lang nanoquery>import tonegen
<syntaxhighlight lang="nanoquery">import tonegen


note_freqs = {261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25}
note_freqs = {261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25}
Line 837: Line 837:
for freq in note_freqs
for freq in note_freqs
tg.beep(freq)
tg.beep(freq)
end</lang>
end</syntaxhighlight>


=={{header|Nim}}==
=={{header|Nim}}==
{{trans|Go}}
{{trans|Go}}
<lang Nim>import endians, math
<syntaxhighlight lang="nim">import endians, math


const
const
Line 892: Line 892:
file.write chr(y.byte) # Signed int to byte then to char as it’s easier this way.
file.write chr(y.byte) # Signed int to byte then to char as it’s easier this way.


file.close()</lang>
file.close()</syntaxhighlight>


=={{header|ooRexx}}==
=={{header|ooRexx}}==
<lang ooRexx>/* REXX ---------------------------------------------------------------
<syntaxhighlight lang="oorexx">/* REXX ---------------------------------------------------------------
* 24.02.2013 Walter Pachl derived from original REXX version
* 24.02.2013 Walter Pachl derived from original REXX version
* Changes: sound(f,sec) --> beep(trunc(f),millisec)
* Changes: sound(f,sec) --> beep(trunc(f),millisec)
Line 928: Line 928:
If f.note\==0 Then
If f.note\==0 Then
Call beep trunc(f.note),dur /* sound the "note". */
Call beep trunc(f.note),dur /* sound the "note". */
Return</lang>
Return</syntaxhighlight>


=={{header|Perl}}==
=={{header|Perl}}==
<lang perl>use MIDI::Simple;
<syntaxhighlight lang="perl">use MIDI::Simple;


# setup, 1 quarter note is 0.5 seconds (500,000 microseconds)
# setup, 1 quarter note is 0.5 seconds (500,000 microseconds)
Line 939: Line 939:
n 60; n 62; n 64; n 65; n 67; n 69; n 71; n 72;
n 60; n 62; n 64; n 65; n 67; n 69; n 71; n 72;


write_score 'scale.mid';</lang>
write_score 'scale.mid';</syntaxhighlight>


=={{header|Phix}}==
=={{header|Phix}}==
Line 945: Line 945:
{{libheader|Phix/online}}
{{libheader|Phix/online}}
You can run this online [http://phix.x10.mx/p2js/Musical_scale.htm here].
You can run this online [http://phix.x10.mx/p2js/Musical_scale.htm here].
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">--
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\Musical_scale.exw
-- demo\rosetta\Musical_scale.exw
Line 972: Line 972:
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupClose</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;">if</span>
<!--</lang>-->
<!--</syntaxhighlight>-->


=={{header|PowerShell}}==
=={{header|PowerShell}}==
List of frequencies directly taken from the Python example.
List of frequencies directly taken from the Python example.
<lang powershell>$frequencies = 261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25
<syntaxhighlight lang="powershell">$frequencies = 261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25
foreach($tone in $frequencies){
foreach($tone in $frequencies){
[Console]::beep($tone, 500)
[Console]::beep($tone, 500)
}</lang>
}</syntaxhighlight>


=={{header|Processing}}==
=={{header|Processing}}==
Requires the Processing Sound library.
Requires the Processing Sound library.


<lang java>
<syntaxhighlight lang="java">
//Aamrun, 2nd July 2022
//Aamrun, 2nd July 2022


Line 1,003: Line 1,003:
delay(500);
delay(500);
}
}
</syntaxhighlight>
</lang>


=={{header|Pure Data}}==
=={{header|Pure Data}}==
Line 1,070: Line 1,070:
=={{header|Python}}==
=={{header|Python}}==
(Windows)
(Windows)
<lang python>>>> import winsound
<syntaxhighlight lang="python">>>> import winsound
>>> for note in [261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25]:
>>> for note in [261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25]:
winsound.Beep(int(note+.5), 500)
winsound.Beep(int(note+.5), 500)
>>> </lang>
>>> </syntaxhighlight>


=={{header|R}}==
=={{header|R}}==
<syntaxhighlight lang="r">
<lang R>
install.packages("audio")
install.packages("audio")
library(audio)
library(audio)
Line 1,084: Line 1,084:
Sys.sleep(.7)
Sys.sleep(.7)
}
}
</syntaxhighlight>
</lang>


=={{header|Racket}}==
=={{header|Racket}}==
With a quick and dirty WinMM interface.
With a quick and dirty WinMM interface.
<lang racket>
<syntaxhighlight lang="racket">
#lang racket
#lang racket
(require ffi/unsafe ffi/unsafe/define)
(require ffi/unsafe ffi/unsafe/define)
Line 1,100: Line 1,100:
(for ([i '(60 62 64 65 67 69 71 72)]) (midi #x90 i 127) (sleep 0.5))
(for ([i '(60 62 64 65 67 69 71 72)]) (midi #x90 i 127) (sleep 0.5))
(sleep 2)
(sleep 2)
</syntaxhighlight>
</lang>


=={{header|Raku}}==
=={{header|Raku}}==
(formerly Perl 6)
(formerly Perl 6)
<lang perl6>for 0,2,4,5,7,9,11,12 {
<syntaxhighlight lang="raku" line>for 0,2,4,5,7,9,11,12 {
shell "play -n -c1 synth 0.2 sin %{$_ - 9}"
shell "play -n -c1 synth 0.2 sin %{$_ - 9}"
}</lang>
}</syntaxhighlight>


=={{header|REXX}}==
=={{header|REXX}}==
Line 1,112: Line 1,112:
{{works with|Personal REXX}}
{{works with|Personal REXX}}
{{works with|Regina}}
{{works with|Regina}}
<lang rexx>/*REXX program sounds eight notes of the C major natural diatonic music scale.*/
<syntaxhighlight lang="rexx">/*REXX program sounds eight notes of the C major natural diatonic music scale.*/
parse arg ! /*obtain optional arguments from the CL*/
parse arg ! /*obtain optional arguments from the CL*/
/* [↓] invoke boilerplate REXX code. */
/* [↓] invoke boilerplate REXX code. */
Line 1,149: Line 1,149:
!rex: parse upper version !ver !vernum !verdate .; !brexx= 'BY'==!vernum; !kexx= "KEXX"==!ver; !pcrexx= 'REXX/PERSONAL'==!ver | "REXX/PC"==!ver; !r4= 'REXX-R4'==!ver; !regina= "REXX-REGINA"==left(!ver, 11); !roo= 'REXX-ROO'==!ver; call !env; return
!rex: parse upper version !ver !vernum !verdate .; !brexx= 'BY'==!vernum; !kexx= "KEXX"==!ver; !pcrexx= 'REXX/PERSONAL'==!ver | "REXX/PC"==!ver; !r4= 'REXX-R4'==!ver; !regina= "REXX-REGINA"==left(!ver, 11); !roo= 'REXX-ROO'==!ver; call !env; return
!sys: !cms= !sys=='CMS'; !os2= !sys=="OS2"; !tso= !sys=='TSO' | !sys=="MVS"; !vse= !sys=='VSE'; !dos= pos("DOS", !sys)\==0 | pos('WIN', !sys)\==0 | !sys=="CMD"; !crx= left(!sys, 6)=='DOSCRX'; call !rex; return
!sys: !cms= !sys=='CMS'; !os2= !sys=="OS2"; !tso= !sys=='TSO' | !sys=="MVS"; !vse= !sys=='VSE'; !dos= pos("DOS", !sys)\==0 | pos('WIN', !sys)\==0 | !sys=="CMD"; !crx= left(!sys, 6)=='DOSCRX'; call !rex; return
!var: call !fid; if !kexx then return space( dosenv( arg(1) ) ); return space( value( arg(1), , !env) )</lang>
!var: call !fid; if !kexx then return space( dosenv( arg(1) ) ); return space( value( arg(1), , !env) )</syntaxhighlight>


Programming note: &nbsp;
Programming note: &nbsp;
Line 1,171: Line 1,171:


=={{header|Ring}}==
=={{header|Ring}}==
<lang ring>
<syntaxhighlight lang="ring">
# Project : Musical scale
# Project : Musical scale


Line 1,180: Line 1,180:
beep(freqs[f][1],300)
beep(freqs[f][1],300)
next
next
</syntaxhighlight>
</lang>
Output video:
Output video:


Line 1,188: Line 1,188:
===Windows===
===Windows===
{{libheader|net.java.dev.sna.SNA}}
{{libheader|net.java.dev.sna.SNA}}
<lang Scala>import net.java.dev.sna.SNA
<syntaxhighlight lang="scala">import net.java.dev.sna.SNA


object PlayMusicScale extends App with SNA {
object PlayMusicScale extends App with SNA {
Line 1,199: Line 1,199:
foreach(f => Beep((261.63 * math.pow(2, f / 12.0)).toInt, if (f == 12) 1000 else 500))
foreach(f => Beep((261.63 * math.pow(2, f / 12.0)).toInt, if (f == 12) 1000 else 500))
println("That's all")
println("That's all")
}</lang>
}</syntaxhighlight>


=={{header|Sparkling}}==
=={{header|Sparkling}}==
The following Sparkling program generates a WAVE audio file named "notes.wav"
The following Sparkling program generates a WAVE audio file named "notes.wav"
that can be played in order to achieve the required effect:
that can be played in order to achieve the required effect:
<lang Sparkling>var sampleRate = 44100.0;
<syntaxhighlight lang="sparkling">var sampleRate = 44100.0;
var duration = 8.0;
var duration = 8.0;
var dataLength = round(sampleRate * duration);
var dataLength = round(sampleRate * duration);
Line 1,253: Line 1,253:
}
}


fclose(f);</lang>
fclose(f);</syntaxhighlight>


=={{header|Tcl}}==
=={{header|Tcl}}==
{{libheader|Snack}}
{{libheader|Snack}}
<lang tcl>package require sound
<syntaxhighlight lang="tcl">package require sound


# Encapsulate the tone generation
# Encapsulate the tone generation
Line 1,279: Line 1,279:
foreach i {0 2 4 5 7 9 11 12 11 9 7 5 4 2 0} {
foreach i {0 2 4 5 7 9 11 12 11 9 7 5 4 2 0} {
play [expr {$tonicFrequency*2**($i/12.0)}] [expr {$i%12?250:500}]
play [expr {$tonicFrequency*2**($i/12.0)}] [expr {$i%12?250:500}]
}</lang>
}</syntaxhighlight>


=={{header|Ursa}}==
=={{header|Ursa}}==
{{trans|Python}}
{{trans|Python}}
<lang ursa>decl double<> notes
<syntaxhighlight lang="ursa">decl double<> notes
append 261.63 293.66 329.63 349.23 392.00 440.00 493.88 523.25 notes
append 261.63 293.66 329.63 349.23 392.00 440.00 493.88 523.25 notes


for (decl int i) (< i (size notes)) (inc i)
for (decl int i) (< i (size notes)) (inc i)
ursa.util.sound.beep notes<i> 0.5
ursa.util.sound.beep notes<i> 0.5
end for</lang>
end for</syntaxhighlight>


=={{header|VBA}}==
=={{header|VBA}}==
<lang vb>Option Explicit
<syntaxhighlight lang="vb">Option Explicit


Declare Function Beep Lib "kernel32" (ByVal Freq As Long, ByVal Dur As Long) As Long
Declare Function Beep Lib "kernel32" (ByVal Freq As Long, ByVal Dur As Long) As Long
Line 1,301: Line 1,301:
Beep Fqs(i), 500
Beep Fqs(i), 500
Next
Next
End Sub</lang>
End Sub</syntaxhighlight>


=={{header|Vlang}}==
=={{header|Vlang}}==
Line 1,307: Line 1,307:
<br>
<br>
As Vlang doesn't have any audio support in its standard library, we instead build a .wav file which can then be played using a utility such as SoX.
As Vlang doesn't have any audio support in its standard library, we instead build a .wav file which can then be played using a utility such as SoX.
<lang vlang>import strings
<syntaxhighlight lang="vlang">import strings
import os
import os
import encoding.binary
import encoding.binary
Line 1,367: Line 1,367:
}
}
}
}
}</lang>
}</syntaxhighlight>


=={{header|Wren}}==
=={{header|Wren}}==
Line 1,373: Line 1,373:
{{libheader|Wren-sound}}
{{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.
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.
<lang ecmascript>import "/sound" for Wav
<syntaxhighlight lang="ecmascript">import "/sound" for Wav


var sampleRate = 44100
var sampleRate = 44100
Line 1,387: Line 1,387:
}
}
}
}
Wav.create("musical_scale.wav", data, sampleRate)</lang>
Wav.create("musical_scale.wav", data, sampleRate)</syntaxhighlight>
<br>
<br>
It's also possible to play .wav files which (preferably) have a sample rate of 44.1 kHz using DOME:
It's also possible to play .wav files which (preferably) have a sample rate of 44.1 kHz using DOME:
{{libheader|DOME}}
{{libheader|DOME}}
<lang ecmascript>import "audio" for AudioEngine
<syntaxhighlight lang="ecmascript">import "audio" for AudioEngine


class Main {
class Main {
Line 1,406: Line 1,406:
}
}


var Game = Main.new()</lang>
var Game = Main.new()</syntaxhighlight>


=={{header|XPL0}}==
=={{header|XPL0}}==
<lang XPL0>\Square waves on the beeper speaker:
<syntaxhighlight lang="xpl0">\Square waves on the beeper speaker:
code Sound=39;
code Sound=39;
real Period; int I;
real Period; int I;
Line 1,429: Line 1,429:
Note:= Note + (if I&3 then 2 else 1);
Note:= Note + (if I&3 then 2 else 1);
];
];
]</lang>
]</syntaxhighlight>


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


Line 1,486: Line 1,486:
else // Linux
else // Linux
system("aplay notesyab.wav")
system("aplay notesyab.wav")
endif</lang>
endif</syntaxhighlight>


=={{header|ZX Spectrum Basic}}==
=={{header|ZX Spectrum Basic}}==
<lang zxbasic>10 REM Musical scale
<syntaxhighlight lang="zxbasic">10 REM Musical scale
20 LET n=0: REM Start at middle C
20 LET n=0: REM Start at middle C
30 LET d=0.2: REM Make each note 0.2 seconds in duration
30 LET d=0.2: REM Make each note 0.2 seconds in duration
Line 1,498: Line 1,498:
80 NEXT l
80 NEXT l
90 STOP
90 STOP
9000 DATA 2,2,1,2,2,2,1,2:REM WWHWWWH</lang>
9000 DATA 2,2,1,2,2,2,1,2:REM WWHWWWH</syntaxhighlight>

Revision as of 23:17, 27 August 2022

Task
Musical scale
You are encouraged to solve this task according to the task description, using any language you may know.
Task

Output the 8 notes of the C major diatonic scale to the default musical sound device on the system. Specifically, pitch must be tuned to 12-tone equal temperament (12TET) with the modern standard A=440Hz.

These are the notes "C, D, E, F, G, A, B, C(1 octave higher)", or "Do, Re, Mi, Fa, Sol, La, Si/Ti, Do(1 octave higher)" on Fixed do Solfège.

For the purpose of this task, Middle C (in the case of the above tuning, around 261.63 Hz) should be used as the starting note, and any note duration is allowed.

For languages that cannot utilize a sound device, it is permissible to output to a musical score sheet (or midi file), or the task can be omitted.

Action!

DEFINE PTR="CARD"

PROC Wait(BYTE frames)
  BYTE RTCLOK=$14
  frames==+RTCLOK
  WHILE frames#RTCLOK DO OD
RETURN

PROC Main()
  BYTE AUDCTL=$D208,AUDF1=$D200,AUDC1=$D201,AUDF2=$D202,AUDC2=$D203
  PTR ARRAY notes(8)
  BYTE ARRAY pitch8=[60 53 47 45 40 35 31 30]
  CARD ARRAY pitch16=[1703 1517 1350 1274 1134 1010 899 848]
  BYTE i
  CARD p

  notes(0)="Do" notes(1)="Re" notes(2)="Mi" notes(3)="Fa"
  notes(4)="Sol" notes(5)="La" notes(6)="Si" notes(7)="Do"

  PrintE("8-bit precision pitch values:")
  FOR i=0 TO 7
  DO
    PrintF("%S-%B ",notes(i),pitch8(i))
    Sound(0,pitch8(i),10,10)
    Wait(20)
  OD
  SndRst()
  Wait(20)
  PutE() PutE()

  AUDCTL=$50 ;join channel 1 and 2 to get 16-bit
  AUDC1=$A0  ;turn off channel 1
  AUDC2=$AA  ;turn on channel 2
  PrintE("16-bit precision pitch values:")
  FOR i=0 TO 7
  DO
    PrintF("%S-%U ",notes(i),pitch16(i))
    p=pitch16(i)
    AUDF2=p RSH 8
    AUDF1=p&$FF
    Wait(20)
  OD
  SndRst()
  AUDCTL=$00 ;restore default configuration
  Wait(20)
RETURN
Output:

Screenshot from Atari 8-bit computer

8-bit precision pitch values:
Do-60 Re-53 Mi-47 Fa-45 Sol-40 La-35 Si-31 Do-30

16-bit precision pitch values:
Do-1703 Re-1517 Mi-1350 Fa-1274 Sol-1134 La-1010 Si-899 Do-848

AmigaBASIC

FOR i=1 to 8
  READ f
  SOUND f,10
NEXT

DATA 261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25

AutoHotkey

Works with: AutoHotkey 1.1
for key, val in [261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25]
	SoundBeep, % val, 500

BASIC256

sound {261.63, 500, 293.66, 500, 329.63, 500, 349.23, 500, 392, 500, 440, 500, 493.88, 500, 523.25, 500}

Befunge

Befunge has no sound support, so this example generates a MIDI file that plays the sequence of notes. The file is written to stdout, so requires an interpreter that can cleanly redirect its output to a file (for example the bef reference implementation requires the -q option to suppress its version banner).

The tune to be played is specified on the first line of the code. The notes are specified as MIDI note numbers in reverse order in a Befunge string (for example, Middle C is note number 60, which is the character "<"). This is followed by the count of notes in the string - 8 in this example.

>         "HGECA@><"8:        v
v0*73"MThd"0006010101"MTrk"000<
>>#1-#,:#\_$8*74++,0,28*"'"039v
v,:,\,*2,1"Hd":\<,,,,,,*3"U"*9<
>"@1",2*,\,,1-:#^_"/3d",5*,,, @

C

Although C provides low level access to devices, there is no standardized way. Here are illustrated two approaches.

Borland's Turbo C

Borland's Turbo C system has the dos.h header file which contains the functions sound() and nosound(). sound() takes an argument which is the frequency of the note to be played through the device speaker. delay(), also part of dos.h tells the code how long to suspend execution. The sound will however still be playing. It is therefore essential to call nosound() at the end which ends the speaker output, otherwise the Turbo C (DOS) session will have to be ended.

#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<dos.h>

typedef struct{
	char str[3];
	int key;
	}note;
	
note sequence[] = {{"Do",0},{"Re",2},{"Mi",4},{"Fa",5},{"So",7},{"La",9},{"Ti",11},{"Do",12}};

int main(void)
{
	int i=0;
	
	while(!kbhit())
	{
		printf("\t%s",sequence[i].str);
		sound(261.63*pow(2,sequence[i].key/12.0));
		delay(sequence[i].key%12==0?500:1000);
		i = (i+1)%8;
		i==0?printf("\n"):printf("");
	}
	nosound();
	return 0;
}

Windows C

I named it Windows C for want of a better name. This is actually more constrained than the above example, since although it will run on any Windows machine, Beep() can only play integer frequencies and thus the tones are noticeably lower than the ones played by sound() above.

#include<windows.h>
#include<stdio.h>
#include<math.h>

typedef struct{
	char str[3];
	int key;
	}note;
	
note sequence[] = {{"Do",0},{"Re",2},{"Mi",4},{"Fa",5},{"So",7},{"La",9},{"Ti",11},{"Do",12}};

int main(void)
{
	int i=0;
	
	while(1)
	{
		printf("\t%s",sequence[i].str);
		Beep(261.63*pow(2,sequence[i].key/12.0),sequence[i].key%12==0?500:1000);
		i = (i+1)%8;
		i==0?printf("\n"):printf("");
	}
	return 0;
}

C++

Uses Windows MIDI device

#include <iostream>
#include <windows.h>
#include <mmsystem.h>

#pragma comment ( lib, "winmm.lib" )

typedef unsigned char byte;

typedef union 
{ 
    unsigned long word; 
    unsigned char data[4]; 
}
midi_msg;

class midi
{
public:
    midi()
    {
	if( midiOutOpen( &device, 0, 0, 0, CALLBACK_NULL) != MMSYSERR_NOERROR ) 
	{
	    std::cout << "Error opening MIDI Output..." << std::endl;
	    device = 0;
	}
    }
    ~midi()
    {
	midiOutReset( device );
	midiOutClose( device );
    }
    bool isOpen() { return device != 0; }
    void setInstrument( byte i )
    {
	message.data[0] = 0xc0; message.data[1] = i;
	message.data[2] = 0; message.data[3] = 0;
	midiOutShortMsg( device, message.word );
    }
    void playNote( byte n, unsigned i )
    {
	playNote( n ); Sleep( i ); stopNote( n );
    }

private:
    void playNote( byte n )
    {
	message.data[0] = 0x90; message.data[1] = n;
	message.data[2] = 127; message.data[3] = 0;
	midiOutShortMsg( device, message.word );
    }
    void stopNote( byte n )
    {
	message.data[0] = 0x90; message.data[1] = n;
	message.data[2] = 0; message.data[3] = 0;
	midiOutShortMsg( device, message.word );
    }
    HMIDIOUT device;
    midi_msg message;
};

int main( int argc, char* argv[] )
{
    midi m;
    if( m.isOpen() )
    {
	byte notes[] = { 60, 62, 64, 65, 67, 69, 71, 72 };
	m.setInstrument( 42 );
	for( int x = 0; x < 8; x++ )
	    m.playNote( notes[x], rand() % 100 + 158 );
	Sleep( 1000 );
    }
    return 0;
}

Clojure

Library: Overtone
(use 'overtone.live)

; Define your desired instrument
; Using saw-wave from: https://github.com/overtone/overtone/wiki/Chords-and-scales
(definst saw-wave [freq 440 attack 0.01 sustain 0.4 release 0.1 vol 0.4] 
  (* (env-gen (env-lin attack sustain release) 1 1 0 1 FREE)
     (saw freq)
     vol))

(defn play [note ms]
  (saw-wave (midi->hz note))
  (Thread/sleep ms))

(doseq [note (scale :c4 :major)] (play note 500))

Commodore BASIC

The Commodore 128 has available the PLAY command to make quick work of this task. The Commodore 64 lacks this command, so work must be done to initialize the SID chip and play the appropriate frequencies. The DATA statements in the Commodore 64 version are provided in hertz to show direct correlation to the appropriate musical notes (C4 through C5), and are converted to a 16-bit integer in lines 60-65 for output.

Commodore 64

10 rem musical scale                    
15 rem rosetta code                     
20 print chr$(147)           
25 s=54272                              
30 for l=s to s+23:poke l,0:next        
35 poke s+5,9:poke s+6,0                
40 poke s+24,15                                            
45 for i=1 to 8                         
50 read fq                              
60 ff=int(fq/.06097)                    
65 fh=int(ff/256):fl=ff-(256*fh)        
70 poke s+1,fh:poke s,fl                                                    
75 poke s+4,17                          
80 for d=1 to 350:next                  
85 poke s+4,16                          
90 for d=1 to 25:next                   
95 next i                               
500 data 261.63,293.66,329.63,349.23,392,440,493.88,523.25

Commodore 128

10 print chr$(147)
20 play "o4 cdefgab o5 c"


Delphi

program Musical_scale;

{$APPTYPE CONSOLE}

uses
  Winapi.Windows;

var
  notes: TArray<Double> = [261.63, 293.66, 329.63, 349.23, 392.00, 440.00,
    493.88, 523.25];

begin
  for var note in notes do
    Beep(Round(note), 500);
  readln;
end.

EasyLang

n[] = [ 262 294 330 349 392 440 494 523 ]
for i range len n[]
  sound [ n[i] 0.5 ]
  sleep 0.6
.

Emacs Lisp

(Slightly reworked code from Sine wave#Emacs Lisp)

Does not work with the Windows version of Emacs.

(defun play-scale (freq-list dur)
  "Play a list of frequencies."
  (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 nil)
  (dolist (freq freq-list)
    (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 s (flatten-list (mapcar (lambda (x)
              (list (unibyte-string (ash x -8))
                    (unibyte-string (mod x 256))))
              v)))))
  (setq s (concat header s))
  (play-sound `(sound :data ,s)))

(play-scale '(261.63 293.66 329.63 349.23 392.00 440.00 493.88 523.25) .5)

Forth

As a low level stack language Forth programming methodology prefers short simple definitions that extend the language in the direction that allows you to solve the problem. The creation of application specific language is common in Forth. This demonstration code uses the PC speaker to generate musical tones. A simple device driver is created for hardware control via PORT I/O. A set of primitive operations are created to control the on:off times of the sounds. Then a small MUSIC language is created to create notes of different types. Finally 2 scales are created using "crotcheted notes" as they are called. We chose 1/8 notes. For fun we added the ability to change the expression of the notes using Italian musical terms.

HEX
\ PC speaker hardware control (requires giveio or DOSBOX for windows operation)
 042 constant fctrl        061 constant sctrl
 0FC constant smask        043 constant tctrl
 0B6 constant spkr

: sing      ( -- ) sctrl pc@               03 or  sctrl pc! ;
: silence   ( -- ) sctrl pc@   smask and   01 or  sctrl pc! ;

: tone     ( divisor -- )
            ?dup                                         \ check for non-zero input
            if   spkr  tctrl pc!                         \ enable PC speaker
                 dup   fctrl pc!                         \ load low byte
                 8 rshift fctrl pc!                      \ load high byte
                 sing
            else silence
            then ;

DECIMAL
1193181. 2constant clock                                 \ internal oscillator freq. MHz x 10

: Hz ( freq -- divisor) clock rot um/mod nip  ;          \ convert Freq to osc. divisor

\ duration control variables and values
variable on_time
variable off_time
variable feel                                            \ controls the on/off time ratio

60 value tempo

4000 tempo um* 2constant timebase                        \ 1 whole note=4000 ms @ 60 Beats/min

: bpm>ms    ( bpm -- ms) timebase rot um/mod nip ;       \ convert beats per minute to milliseconds
: wholenote ( -- ms )  tempo bpm>ms ;                    \ using tempo set the BPM

: play      ( divisor -- )
            tone on_time @ ms   silence  off_time @ ms ;

: expression ( ms n --)                                  \ adjust the on:off ratio using n
           over swap -  tuck -   ( -- on-mS off-mS )
           off_time !  on_time ! ;                       \ store times in variables

: note      ( -- ms ) on_time @ off_time @ + ;           \ returns duration of current note

: duration!    ( ms -- )  feel @ expression ;

: 50%       ( n -- n/2)    2/ ;
: %         ( n n2  -- n%) 100 */ ;                      \ calculate n2% of n
: 50%+      ( n -- n+50%)  dup 50% + ;                   \ dotted notes have 50% more time

VOCABULARY MUSIC

MUSIC DEFINITIONS
: BPM       ( bpm -- )                                  \ set tempo in beats per minute
            to tempo
            wholenote duration! ;

: legato      0 feel ! ;
: staccatto   note 8 %  feel ! ;
: Marcato     note 3 %  feel ! ;

: 1/1      wholenote      duration! ;
: 1/2      wholenote 50%  duration! ;
: 1/2.     1/2  note 50%+ duration! ;
: 1/4      1/2  note 50%  duration! ;
: 1/4.     1/4  note 50%+ duration! ;
: 1/8      1/4  note 50%  duration! ;
: 1/8.     1/8  note 50%+ duration! ;
: 1/16     1/8  note 50%  duration! ;
: 1/32     1/16 note 50%  duration! ;
: rest     note ms ;

\ note object creator
: note:    create  hz ,                    \ compile time: compile divisor into the note
           does>  @ play ;                 \ run time: fetch the value and play the tone

\ freq  Natural    Freq  Accidental    En-harmonic
\ -------------    ----------------   ----------------
  131 note: C3     139 note: C#3       synonym Db3 C#3
  147 note: D3     156 note: D#3       synonym Eb3 D#3
  165 note: E3
  175 note: F3     185 note: F#3       synonym Gb3 F#3
  196 note: G3     208 note: G#3       synonym Ab3 G#3
  220 note: A3     233 note: A#3       synonym Bb3 A#3
  247 note: B3
  262 note: C4     277 note: C#4       synonym Db4 C#4

: Cmajor      1/8  C3 D3 E3  F3 G3 A3  B3  C4 ;
: Chromatic   1/8  C3 C#3 D3 D#3 E3 F3 F#3 G3 G#3 A3 A#3 B3 C4 ;

Interactive test at the Console

music ok
120 bpm legato cmajor ok
200 bpm marcato chromatic ok
72 bpm legato c3 eb3 g3 c4 ok 


FreeBASIC

REM FreeBASIC no tiene la capacidad de emitir sonido de forma nativa.
REM La función Sound no es mía, incluyo los créditos correspondientes.
' Sound Function v0.3 For DOS/Linux/Win by yetifoot
' Credits:
'    http://www.frontiernet.net/~fys/snd.htm
'    http://delphi.about.com/cs/adptips2003/a/bltip0303_3.htm
#ifdef __FB_WIN32__
#include Once "windows.bi"
#endif
Sub Sound_DOS_LIN(Byval freq As Uinteger, dur As Uinteger)
    Dim t As Double
    Dim As Ushort fixed_freq = 1193181 \ freq
    
    Asm
        mov  dx, &H61                  ' turn speaker on
        in   al, dx
        or   al, &H03
        out  dx, al
        mov  dx, &H43                  ' get the timer ready
        mov  al, &HB6
        out  dx, al
        mov  ax, word Ptr [fixed_freq] ' move freq to ax
        mov  dx, &H42                  ' port to out
        out  dx, al                    ' out low order
        xchg ah, al                   
        out  dx, al                    ' out high order
    End Asm
    
    t = Timer
    While ((Timer - t) * 1000) < dur ' wait for out specified duration
        Sleep(1)
    Wend
    
    Asm
        mov  dx, &H61                  ' turn speaker off
        in   al, dx
        and  al, &HFC
        out  dx, al
    End Asm
End Sub

Sub Sound(Byval freq As Uinteger, dur As Uinteger)
    #ifndef __fb_win32__
    ' If not windows Then call the asm version.
    Sound_DOS_LIN(freq, dur)
    #Else
    ' If Windows
    Dim osv As OSVERSIONINFO
    
    osv.dwOSVersionInfoSize = Sizeof(OSVERSIONINFO)
    GetVersionEx(@osv)
    
    Select Case osv.dwPlatformId
    Case VER_PLATFORM_WIN32_NT       
        ' If NT then use Beep from API
        Beep_(freq, dur)
    Case Else
        ' If not on NT then use the same as DOS/Linux
        Sound_DOS_LIN(freq, dur)
    End Select
    #endif
End Sub

'----------
Sound(262, 250)  'C4
Sound(294, 250)  'D4
Sound(330, 250)  'E4
Sound(349, 250)  'F4
Sound(392, 250)  'G4
Sound(440, 250)  'A4
Sound(494, 250)  'B4
Sound(523, 250)  'C5
Sleep

FreePascal

{$mode objfpc}
uses windows,math;{ windows only }
var
  Interval:Double =  1.0594630943592953;
  i:integer;
begin
  for  i:= 0 to 11 do
    beep(Round(440.0*interval**i),500);
end.

Go

Translation of: Sparkling


As Go doesn't have any audio support in its standard library, we instead build a .wav file which can then be played using a utility such as SoX.

package main

import (
    "encoding/binary"
    "log"
    "math"
    "os"
    "strings"
)

func main() {
    const (
        sampleRate = 44100
        duration   = 8
        dataLength = sampleRate * duration
        hdrSize    = 44
        fileLen    = dataLength + hdrSize - 8
    )

    // buffers
    buf1 := make([]byte, 1)
    buf2 := make([]byte, 2)
    buf4 := make([]byte, 4)

    // WAV header
    var sb strings.Builder
    sb.WriteString("RIFF")
    binary.LittleEndian.PutUint32(buf4, fileLen)
    sb.Write(buf4) // file size - 8
    sb.WriteString("WAVE")
    sb.WriteString("fmt ")
    binary.LittleEndian.PutUint32(buf4, 16)
    sb.Write(buf4) // length of format data (= 16)
    binary.LittleEndian.PutUint16(buf2, 1)
    sb.Write(buf2) // type of format (= 1 (PCM))
    sb.Write(buf2) // number of channels (= 1)
    binary.LittleEndian.PutUint32(buf4, sampleRate)
    sb.Write(buf4) // sample rate
    sb.Write(buf4) // sample rate * bps(8) * channels(1) / 8 (= sample rate)
    sb.Write(buf2) // bps(8) * channels(1) / 8  (= 1)
    binary.LittleEndian.PutUint16(buf2, 8)
    sb.Write(buf2) // bits per sample (bps) (= 8)
    sb.WriteString("data")
    binary.LittleEndian.PutUint32(buf4, dataLength)
    sb.Write(buf4) // size of data section
    wavhdr := []byte(sb.String())

    // write WAV header
    f, err := os.Create("notes.wav")
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()
    f.Write(wavhdr)

    // compute and write actual data
    freqs := [8]float64{261.6, 293.6, 329.6, 349.2, 392.0, 440.0, 493.9, 523.3}
    for j := 0; j < duration; j++ {
        freq := freqs[j]
        omega := 2 * math.Pi * freq
        for i := 0; i < dataLength/duration; i++ {
            y := 32 * math.Sin(omega*float64(i)/float64(sampleRate))
            buf1[0] = byte(math.Round(y))
            f.Write(buf1)
        }
    }
}

J

require'media/wav'
0.25 wavnote 0 2 4 5 7 9 11 12

This assumes a version such as J6 which supports media/wav.

0=C, 1=C#, 2=D, ... of main octave

0.25 is the duration of each note (in seconds).

JavaScript

Using the Web Audio API

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Sample Page</title>
</head>
<body>
Upon loading the page you should hear the scale.
<script type="text/javascript">
function musicalScale(freqArr){
    // create web audio api context
    var AudioContext = window.AudioContext || window.webkitAudioContext;
    var audioCtx = new AudioContext();

    // create oscillator and gain node
    var oscillator = audioCtx.createOscillator();
    var gainNode = audioCtx.createGain();

    // connect oscillator to gain node to speakers
    oscillator.connect(gainNode);
    gainNode.connect(audioCtx.destination);
    
    // set frequencies to play
    duration = 0.5   // seconds
    freqArr.forEach(function (freq, i){
        oscillator.frequency.setValueAtTime(freq, audioCtx.currentTime + i * duration);
    });
    
    // start playing!
    oscillator.start();
    // stop playing!
    oscillator.stop(audioCtx.currentTime + freqArr.length * duration);
}

musicalScale([261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25]);
</script>
</body>
</html>

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 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

# C major scale starting with middle C
# pitches from //pages.mtu.edu/~suits/notefreqs.html
const scale = [261.6, 293.7, 329.6, 349.2, 392, 440, 493.9, 523.3]
const ostream = paudio()
for pitch in scale
    play(ostream, pitch, 0.5)
    sleep(0.4)
end

Kotlin

This uses the same frequencies and duration as the Python entry and works fine on Windows 10.

When building win32.klib from windows.h, one needs to make sure NOT to filter out utilapiset.h because this is where the Beep function now resides, not in winbase.h as stated in the MSDN documentation.

// Kotlin Native v0.3

import kotlinx.cinterop.*
import win32.*

fun main(args: Array<String>) {
    val freqs = intArrayOf(262, 294, 330, 349, 392, 440, 494, 523)  // CDEFGABc
    val dur = 500
    repeat(5) { for (freq in freqs) Beep(freq, dur) }   
}

Lilypond

The lilypond tool produces musical score sheets and midi files - if asked for - but does not output notes to the sound device directly.

% Start at middle C
\relative c' {
  c d e f
  g a b c
}

Locomotive Basic

10 mode 1
20 print "Note","Freq. (Hz)","Period"
30 ' program loop:
40 if sq(1)<128 then gosub 70  ' play next note if channel is inactive
50 goto 40
60 ' play next note
70 read n
80 if n<0 then end
90 note=note+1
100 ' calculation from chapter 7, page 26 of the CPC manual:
110 f=440*(2^((n-10)/12))
120 p=round(62500/f)
130 print mid$("cdefgabc",note,1),round(f,2),p
140 sound 1,p,100
150 return
160 data 1,3,5,6,8,10,12,13,-1

Lua

Lua has no native sound support.

Lua Portable

The most portable native solution that could actually play the scale (with some external help from a media player) would be to write a MIDI file..

c = string.char
midi = "MThd" .. c(0,0,0,6,0,0,0,1,0,96) -- header
midi = midi .. "MTrk" .. c(0,0,0,8*8+4) -- track
for _,note in ipairs{60,62,64,65,67,69,71,72} do
  midi = midi .. c(0, 0x90, note, 0x40, 0x60, 0x80, note, 0) -- notes
end
midi = midi .. c(0, 0xFF, 0x2F, 0) -- end

file = io.open("scale.mid", "wb")
file:write(midi)
file:close()

-- (optional:  hex dump to screen)
midi:gsub(".", function(c) io.write(string.format("%02X ", string.byte(c))) end)
Output:
4D 54 68 64 00 00 00 06 00 00 00 01 00 60 4D 54 72 6B 00 00 00 44 00 90 3C 40 60 80 3C 00 00 90 3E 40 60 80 3E 00 00 90 40 40 60 80 40 00 00 90 41 40 60 80 41 00 00 90 43 40 60 80 43 00 00 90 45 40 60 80 45 00 00 90 47 40 60 80 47 00 00 90 48 40 60 80 48 00 00 FF 2F 00

Lua ASCII

The task allows for score output, which could also be done natively..

staff = {
  lines = { "", "", "", "", "", "", "", "", "", "", "" },
  nnotes = 0,
  measure = function(self)
    for i, line in ipairs(self.lines) do
      self.lines[i] = line .. (i<#self.lines-1 and "|" or " ")
    end
  end,
  play = function(self, note)
    if self.nnotes%4==0 then self:measure() end
    local n = #self.lines-note
    for i, line in ipairs(self.lines) do
      local linechar = (i%2==0) and " " or "-"
      local fillchar = (i<#self.lines) and linechar or " "
      self.lines[i] = line .. (i==n and linechar.."@"..linechar..fillchar or (i==n-1 or i==n-2) and string.rep(fillchar,2).."|"..fillchar or string.rep(fillchar,4))
    end
    self.nnotes = self.nnotes + 1
  end,
  dump = function(self)
    for i, line in ipairs(self.lines) do print(line) end
  end
}
for note = 0,7 do
  staff:play(note)
end
staff:measure()
staff:dump()
Output:
|----------------|----------------|
|                |              | |
|----------------|----------|---|-|
|                |      |   |  @  |
|----------------|--|---|--@------|
|              | |  |  @          |
|----------|---|-|-@--------------|
|      |   |  @  |                |
|--|---|--@------|----------------|
   |  @
 -@-

Lua Windows

Non-portable, O/S-specific, requires alien library..

beep = require"alien".kernel32.Beep
beep:types{ret='long', abi='stdcall', 'long', 'long'}
for _,step in ipairs{0,2,4,5,7,9,11,12} do
  beep(math.floor(261.63 * 2^(step/12) + 0.5), 1000)
end

M2000 Interpreter

Score make an internal bank (replace a previous one), on a voice, (1 to 16), where 10 is for drum machine. Play assign a midi organ to a score and start play, in a "music" thread. We can can use Play 0 to stop all scores, or Play number, 0 to stop as specific score. Beat value 300 is in milliseconds, so play each not in Tune each 300 milliseconds, and the same for Score (scores may use @1 to @6 to play 300/1 to 300/32 for specific note, and can use V1 to V127 for volume control per note). Spaces in strings are pauses, and for scores we can use @1 to @6 to reduce pause value). We can use a thread to send a drum score every some seconds, to play a rhythm. Thread { score 10... : play 10,10 ....} as drums interval 1000 (second value for play 10 maybe 0 or any other 1 to 127 but always assign the drum machine. Midi

TUNE use kernel Beep which is synchronous and not leaving M2000 threads to process, until ends.

Module checkit {
      \\ using internal speaker
      TUNE 300, "C3DEFGABC4"
      TUNE 300, "C3C#DD#EFF#GG#AA#BC4"
      Thread {
            score 10, 100,  "CAC"
            Play 10, 1
      } as drums interval 1000
      \\ Play in background (16 scores - no 10 for drum machine)
      SCORE 1, 300, "C3DEFGABC4"
      PLAY 1, 19  ' use score 1 with organ 19
      Wait 2400
}
checkit

Mathematica/Wolfram Language

EmitSound@Sound[SoundNote /@ {0, 2, 4, 5, 7, 9, 11, 12}]

Nanoquery

import tonegen

note_freqs = {261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25}

tg = new(tonegen)
for freq in note_freqs
        tg.beep(freq)
end

Nim

Translation of: Go
import endians, math

const
  SampleRate = 44100
  Duration = 8
  DataLength = SampleRate * Duration
  HdrSize = 44
  FileLen = DataLength + HdrSize - 8
  Bps = 8
  Channels = 1

proc writeUint16(f: File; x: uint16) =
  var x = x
  var y: array[2, byte]
  littleEndian16(y.addr, x.addr)
  let n = f.writeBytes(y, 0, 2)
  doAssert n == 2

proc writeUint32(f: File; x: uint32) =
  var x = x
  var y: array[4, byte]
  littleEndian32(y.addr, x.addr)
  let n = f.writeBytes(y, 0, 4)
  doAssert n == 4


let file = open("notes.wav", fmWrite)

# Wav header.
file.write "RIFF"
file.writeUint32(FileLen)
file.write "WAVE"
file.write "fmt "
file.writeUint32(16)                # length of format data.
file.writeUint16(1)                 # type of format(PCM).
file.writeUint16(Channels)
file.writeUint32(SampleRate)
file.writeUint32(SampleRate * Bps * Channels div 8)
file.writeUint16(Bps * Channels div 8)
file.writeUint16(Bps)
file.write "data"
file.writeUint32(DataLength)        # size of data section.

# Compute and write actual data.
const Freqs = [261.6, 293.6, 329.6, 349.2, 392.0, 440.0, 493.9, 523.3]
for freq in Freqs:
  let omega = 2 * Pi * freq
  for i in 0..<(DataLength div Duration):
    let y = (32 * sin(omega * i.toFloat / SampleRate.toFloat)).toInt
    file.write chr(y.byte)  # Signed int to byte then to char as it’s easier this way.

file.close()

ooRexx

/* REXX ---------------------------------------------------------------
* 24.02.2013 Walter Pachl derived from original REXX version
* Changes: sound(f,sec) --> beep(trunc(f),millisec)
*          $ -> sc
*          @. -> f.
*          re > ra (in sc)
*--------------------------------------------------------------------*/
  sc='do ra mi fa so la te do'
  dur=1250                          /* milliseconds                   */
  Do j=1 For words(sc)              /* sound each "note" in the string*/
    Call notes word(sc,j),dur       /* invoke a subroutine for sounds.*/
    End                             /* j                              */
  Exit                              /* stick a fork in it, we're done.*/
notes: Procedure
  Arg note,dur
  f.=0                              /* define common names for sounds.*/
  f.la=220
  f.si=246.94
  f.te=f.si
  f.ta=f.te
  f.ti=f.te
  f.do=261.6256
  f.ut=f.do
  f.ra=293.66
  f.re=f.ra     /* re is to be a synonym for ra */
  f.mi=329.63
  f.ma=f.mi
  f.fa=349.23
  f.so=392
  f.sol=f.so
  Say note trunc(f.note) dur
  If f.note\==0 Then
    Call beep trunc(f.note),dur     /* sound the "note".              */
  Return

Perl

use MIDI::Simple;

# setup, 1 quarter note is 0.5 seconds (500,000 microseconds)
set_tempo 500_000;

# C-major scale
n 60; n 62; n 64; n 65; n 67; n 69; n 71; n 72;

write_score 'scale.mid';

Phix

Library: Phix/pGUI
Library: Phix/online

You can run this online here.

--
-- demo\rosetta\Musical_scale.exw
--
with javascript_semantics
include pGUI.e
include builtins\beep.e

constant freq = {261.63,293.66,329.63,349.23,392,440,493.88,523.25},
    durations = repeat(500,length(freq)-1) & 1000

function button_cb(Ihandle /*playbtn*/)
    beep(freq,durations,0.5)
    return IUP_DEFAULT
end function

IupOpen()
Ihandle label = IupLabel("Please don't shoot the piano player, he's doing the best that he can!"),
        playbtn = IupButton("Play",Icallback("button_cb"),"PADDING=30x0"),
        hbox = IupHbox({IupFill(),playbtn,IupFill()},"MARGIN=0x20"),
        vbox = IupVbox({label,hbox}, "MARGIN=10x5, GAP=5"),
        dlg = IupDialog(vbox,`TITLE="Musical Scale"`)
IupShow(dlg)
if platform()!=JS then
    IupMainLoop()
    IupClose()
end if

PowerShell

List of frequencies directly taken from the Python example.

$frequencies = 261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25
foreach($tone in $frequencies){
    [Console]::beep($tone, 500)
}

Processing

Requires the Processing Sound library.

//Aamrun, 2nd July 2022

import processing.sound.*;

float[] frequencies = {261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25};

SinOsc sine;

size(500,500);

sine = new SinOsc(this);

for(int i=0;i<frequencies.length;i++){
   sine.freq(frequencies[i]);
   sine.play();

   delay(500);
}

Pure Data

scale.pd

#N canvas 898 363 360 460 10;
#X obj 63 21 bng 15 250 50 0 empty start start 17 7 0 10 -262144 -1 -1;
#X floatatom 135 21 5 0 0 1 bpm bpm -;
#X obj 135 40 expr 1000 / ($f1/60);
#X obj 135 62 int;
#X obj 117 123 + 1;
#X obj 117 145 mod 9;
#X obj 63 123 int 1;
#X obj 63 176 hradio 15 1 0 9 empty empty empty 0 -8 0 10 -262144 -1 -1 0;
#X obj 63 196 route 0 1 2 3 4 5 6 7;
#X msg 15 248 0;
#X msg 93 248 62;
#X msg 123 248 64;
#X msg 63 248 60;
#X msg 153 248 65;
#X msg 183 248 67;
#X msg 213 248 69;
#X msg 243 248 71;
#X msg 273 248 72;
#X obj 111 313 mtof;
#X obj 84 357 osc~;
#X obj 84 384 dac~;
#X obj 237 323 loadbang;
#X obj 63 101 metro;
#X msg 237 345 \; pd dsp 1 \; bpm 136 \; start 1;
#X connect 0 0 22 0;
#X connect 1 0 2 0;
#X connect 2 0 3 0;
#X connect 3 0 22 1;
#X connect 4 0 5 0;
#X connect 5 0 6 1;
#X connect 6 0 4 0;
#X connect 6 0 7 0;
#X connect 7 0 8 0;
#X connect 8 0 9 0;
#X connect 8 1 12 0;
#X connect 8 2 10 0;
#X connect 8 3 11 0;
#X connect 8 4 13 0;
#X connect 8 5 14 0;
#X connect 8 6 15 0;
#X connect 8 7 16 0;
#X connect 8 8 17 0;
#X connect 9 0 19 0;
#X connect 9 0 22 0;
#X connect 10 0 18 0;
#X connect 11 0 18 0;
#X connect 12 0 18 0;
#X connect 13 0 18 0;
#X connect 14 0 18 0;
#X connect 15 0 18 0;
#X connect 16 0 18 0;
#X connect 17 0 18 0;
#X connect 18 0 19 0;
#X connect 19 0 20 0;
#X connect 19 0 20 1;
#X connect 21 0 23 0;
#X connect 22 0 6 0;

Python

(Windows)

>>> import winsound
>>> for note in [261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25]:
	winsound.Beep(int(note+.5), 500)	
>>>

R

install.packages("audio")
library(audio)
hz=c(1635,1835,2060,2183,2450,2750,3087,3270)
for (i in 1:8){
  play(audioSample(sin(1:1000), hz[i]))
  Sys.sleep(.7)
}

Racket

With a quick and dirty WinMM interface.

#lang racket
(require ffi/unsafe ffi/unsafe/define)
(define-ffi-definer defmm (ffi-lib "Winmm"))
(defmm midiOutOpen (_fun [h : (_ptr o _int32)] [_int = -1] [_pointer = #f]
                         [_pointer = #f] [_int32 = 0] -> _void -> h))
(defmm midiOutShortMsg (_fun _int32 _int32 -> _void))
(define M (midiOutOpen))
(define (midi x y z) (midiOutShortMsg M (+ x (* 256 y) (* 65536 z))))

(for ([i '(60 62 64 65 67 69 71 72)]) (midi #x90 i 127) (sleep 0.5))
(sleep 2)

Raku

(formerly Perl 6)

for 0,2,4,5,7,9,11,12 {
    shell "play -n -c1 synth 0.2 sin %{$_ - 9}"
}

REXX

Works with: PC/REXX
Works with: Personal REXX
Works with: Regina
/*REXX program  sounds  eight notes  of the    C  major   natural diatonic  music scale.*/
parse arg !                                      /*obtain optional arguments from the CL*/
                                                 /* [↓]  invoke boilerplate REXX code.  */
if !all( arg() )  then exit                      /*determine which REXX is running,  if */
                                                 /*    any form of help requested, exit.*/
if \!regina   & \!pcrexx  then do
                               say "***error***  this program can't execute under:"   !ver
                               exit 13
                               end

$ = 'do ra me fa so la te do'                    /*the words for music scale sounding.  */
dur = 1/4                                        /*define duration as a quarter second. */
           do j=1  for words($)                  /*sound each "note" in the string.     */
           call notes word($, j), dur            /*invoke a subroutine for the sounds.  */
           end   /*j*/                           /* [↑]   sound each of the words.      */
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
notes: procedure expose !regina !pcrexx; arg note,dur /*obtain the arguments from list. */
       @.= 0                                          /*define common names for sounds. */
       @.la= 220;        @.si= 246.94;    @.te= @.si;      @.ta= @.te;    @.ti=  @.te
       @.do= 261.6256;   @.ut= @.do;      @.re= 293.66;    @.ra= @.re;    @.mi=  329.63
       @.ma= @.mi;       @.fa= 349.23;    @.so= 392;                      @.sol= @.so
       if @.note==0  then return                      /*if frequency is zero,  skip it. */
       if !pcrexx  then call  sound @.note,dur        /*sound the note using SOUND bif. */
       if !regina  then do                            /* [↓]  reformat some numbers.    */
                        ms= format(dur*1000, , 0)     /*Regina requires DUR in millisec.*/
                        intN= format(@.note, , 0)     /*   "      "     NOTE is integer.*/
                        call  beep  intN, ms          /*sound the note using  BEEP  BIF.*/
                        end
       return
/*─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────*/
!all: !!=!;!=space(!);upper !;call !fid;!nt=right(!var('OS'),2)=='NT';!cls=word('CLS VMFCLEAR CLRSCREEN',1+!cms+!tso*2);if arg(1)\==1 then return 0;if wordpos(!,'? ?SAMPLES ?AUTHOR ?FLOW')==0 then return 0;!call=']$H';call '$H' !fn !;!call=;return 1
!cal: if symbol('!CALL')\=="VAR"  then !call=;                             return !call
!env: !env= 'ENVIRONMENT';   if !sys=="MSDOS"  |  !brexx  |  !r4  |  !roo  then !env= 'SYSTEM';   if !os2  then !env= "OS2"!env;   !ebcdic= 3=='f3'x;   if !crx  then !env="DOS";                    return
!fid: parse upper source !sys !fun !fid . 1 . . !fn !ft !fm .;  call !sys;  if !dos  then do;  _= lastpos('\',!fn);  !fm= left(!fn,_);  !fn= substr(!fn,_+1);  parse var !fn !fn "." !ft;  end;      return word(0 !fn !ft !fm, 1 + ('0'arg(1) ) )
!rex: parse upper version !ver !vernum !verdate .;  !brexx= 'BY'==!vernum; !kexx= "KEXX"==!ver; !pcrexx= 'REXX/PERSONAL'==!ver | "REXX/PC"==!ver; !r4= 'REXX-R4'==!ver; !regina= "REXX-REGINA"==left(!ver, 11); !roo= 'REXX-ROO'==!ver; call !env; return
!sys: !cms= !sys=='CMS';   !os2= !sys=="OS2";   !tso= !sys=='TSO'  |  !sys=="MVS";   !vse= !sys=='VSE';   !dos= pos("DOS", !sys)\==0  |  pos('WIN', !sys)\==0  |  !sys=="CMD";   !crx= left(!sys, 6)=='DOSCRX';                         call !rex; return
!var: call !fid;   if !kexx  then return space( dosenv( arg(1) ) );        return space( value( arg(1), , !env) )

Programming note:   The general 1-line subroutines at the end of the REXX program are boilerplate code which:

  • check for invocation with a   ?                   single argument to support general documentation (help).
  • check for invocation with a   ?SAMPLES   single argument to support documentation for sample usages.
  • check for invocation with a   ?FLOW         single argument to support documentation for program logic flow.
  • check for invocation with a   ?AUTHOR     single argument to support showing the author of the REXX pgm.
  • defines several   !ααα   variables indicating:
  • name and version of the REXX interpreter being used.
  • name of the program used to clear the terminal screen.
  • name of the (host) operating system being used.
  • name of the subsystem to issue commands (via address).
  • name of the pool used to set environmental variables.
  • name by which the REXX program was invoked.
  • name by which the REXX program was loaded (executed).
  • how the REXX program is being invoked:
  • as a command
  • as a function
  • as a subroutine

Ring

# Project : Musical scale

loadlib("C:\Ring\extensions\ringbeep\ringbeep.dll")
freqs = [[262,"Do"], [294,"Ra"], [330,"Me"], [349,"Fa"], [392,"So"], [440,"La"], [494,"Te"], [523,"do"]]
for f = 1 to len(freqs)
     see freqs[f][2] + nl
     beep(freqs[f][1],300)
next

Output video:

Musical scale

Scala

Windows

import net.java.dev.sna.SNA

object PlayMusicScale extends App with SNA {

  snaLibrary = "Kernel32"
  val Beep = SNA[Int, Int, Unit]

  println("Please don't shoot the piano player, he's doing the best that he can!")
  List(0, 2, 4, 5, 7, 9, 11, 12).
    foreach(f => Beep((261.63 * math.pow(2, f / 12.0)).toInt, if (f == 12) 1000 else 500))
  println("That's all")
}

Sparkling

The following Sparkling program generates a WAVE audio file named "notes.wav" that can be played in order to achieve the required effect:

var sampleRate = 44100.0;
var duration = 8.0;
var dataLength = round(sampleRate * duration);
var dataLength_b0 = dataLength >> 0  & 0xff;
var dataLength_b1 = dataLength >> 8  & 0xff;
var dataLength_b2 = dataLength >> 16 & 0xff;
var dataLength_b3 = dataLength >> 24 & 0xff;

const adjustedHdrSize = 36;

var len = dataLength - adjustedHdrSize;
var len_b0 = len >> 0  & 0xff;
var len_b1 = len >> 8  & 0xff;
var len_b2 = len >> 16 & 0xff;
var len_b3 = len >> 24 & 0xff;

// WAV header
var wavhdr   = "RIFF";
    wavhdr ..= fmtstr("%c%c%c%c", len_b0, len_b1, len_b2, len_b3);
    wavhdr ..= "WAVE";
    wavhdr ..= "fmt ";
    wavhdr ..= "\x10\x00\x00\x00";
    wavhdr ..= "\x01\x00";
    wavhdr ..= "\x01\x00";
    wavhdr ..= "\x44\xac\x00\x00";
    wavhdr ..= "\x44\xac\x00\x00";
    wavhdr ..= "\x01\x00";
    wavhdr ..= "\x08\x00";
    wavhdr ..= "data";
    wavhdr ..= fmtstr("%c%c%c%c", dataLength_b0, dataLength_b1, dataLength_b2, dataLength_b3);

// write wav header
var f = fopen("notes.wav", "w");
fwrite(f, wavhdr);


// compute and write actual data
var frequs = { 261.6, 293.6, 329.6, 349.2, 392.0, 440.0, 493.9, 523.3 };

for var j = 0; j < duration; j++ {
	var frequ = frequs[j];
	var omega = 2 * M_PI * frequ;
	for var i = 0; i < dataLength / 8; i++ {
		var y = 32 * sin(omega * i / sampleRate);
		var byte = fmtstr("%c", round(y));
		fwrite(f, byte);
	}
}

fclose(f);

Tcl

Library: Snack
package require sound

# Encapsulate the tone generation
set filter [snack::filter generator 1 20000 0.5 sine -1]
set sound  [snack::sound -rate 22050]
proc play {frequency length} {
    global filter sound

    $filter configure $frequency
    $sound play -filter $filter

    # Need to run event loop; Snack uses it internally
    after $length {set donePlay 1}
    vwait donePlay

    $sound stop
}

# Major scale up, then down; extra delay at ends of scale
set tonicFrequency 261.63; # C4
foreach i {0 2 4 5 7 9 11 12 11 9 7 5 4 2 0} {
    play [expr {$tonicFrequency*2**($i/12.0)}] [expr {$i%12?250:500}]
}

Ursa

Translation of: Python
decl double<> notes
append 261.63 293.66 329.63 349.23 392.00 440.00 493.88 523.25 notes

for (decl int i) (< i (size notes)) (inc i)
        ursa.util.sound.beep notes<i> 0.5
end for

VBA

Option Explicit

Declare Function Beep Lib "kernel32" (ByVal Freq As Long, ByVal Dur As Long) As Long

Sub Musical_Scale()
Dim Fqs, i As Integer
   Fqs = Array(264, 297, 330, 352, 396, 440, 495, 528)
   For i = LBound(Fqs) To UBound(Fqs)
      Beep Fqs(i), 500
   Next
End Sub

Vlang

Translation of: Go


As Vlang doesn't have any audio support in its standard library, we instead build a .wav file which can then be played using a utility such as SoX.

import strings
import os
import encoding.binary
import math
 
const (
    sample_rate = 44100
    duration   = 8
    data_length = sample_rate * duration
    hdr_size    = 44
    file_len    = data_length + hdr_size - 8
)
fn main() {
 
    // buffers
    mut buf1 := []byte{len:1}
    mut buf2 := []byte{len:2}
    mut buf4 := []byte{len:4}
 
    // WAV header
    mut sb := strings.new_builder(128)
    sb.write_string("RIFF")
    binary.little_endian_put_u32(mut &buf4, file_len)
    sb.write(buf4)? // file size - 8
    sb.write_string("WAVE")
    sb.write_string("fmt ")
    binary.little_endian_put_u32(mut &buf4, 16)
    sb.write(buf4)? // length of format data (= 16)
    binary.little_endian_put_u16(mut &buf2, 1)
    sb.write(buf2)? // type of format (= 1 (PCM))
    sb.write(buf2)? // number of channels (= 1)
    binary.little_endian_put_u32(mut &buf4, sample_rate)
    sb.write(buf4)? // sample rate
    sb.write(buf4)? // sample rate * bps(8) * channels(1) / 8 (= sample rate)
    sb.write(buf2)? // bps(8) * channels(1) / 8  (= 1)
    binary.little_endian_put_u16(mut &buf2, 8)
    sb.write(buf2)? // bits per sample (bps) (= 8)
    sb.write_string("data")
    binary.little_endian_put_u32(mut &buf4, data_length)
    sb.write(buf4)? // size of data section
    wavhdr := sb.str().bytes()
 
    // write WAV header
    mut f := os.create("notes.wav")?
    defer {
        f.close()
    }
    f.write(wavhdr)?
 
    // compute and write actual data
    freqs := [261.6, 293.6, 329.6, 349.2, 392.0, 440.0, 493.9, 523.3]!
    for j in 0..duration {
        freq := freqs[j]
        omega := 2 * math.pi * freq
        for i in 0..data_length/duration {
            y := 32 * math.sin(omega*f64(i)/f64(sample_rate))
            buf1[0] = u8(math.round(y))
            f.write(buf1)?
        }
    }
}

Wren

Translation of: Sparkling
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 sampleRate = 44100
var duration = 8
var data = List.filled(sampleRate * duration, 0)
var freqs = [261.6, 293.6, 329.6, 349.2, 392.0, 440.0, 493.9, 523.3]
for (j in 0...duration) {
    var freq = freqs[j]
    var omega = 2 * Num.pi * freq
    for (i in 0...sampleRate) {
        var y = (32 * (omega * i / sampleRate).sin).round & 255
        data[i + j * sampleRate] = y
    }
}
Wav.create("musical_scale.wav", data, sampleRate)


It's also possible to play .wav files which (preferably) have a sample rate of 44.1 kHz using DOME:

Library: DOME
import "audio" for AudioEngine

class Main {
    construct new() {}

    init() {
        AudioEngine.load("doremi", "musical_scale.wav")
        AudioEngine.play("doremi")
    }

    update() {}

    draw(alpha) {}
}

var Game = Main.new()

XPL0

\Square waves on the beeper speaker:
code Sound=39;
real Period;  int I;
[Period:= 1190000.0/261.625565;     \middle C
for I:= 2 to 9 do
    [Sound(1, 4, fix(Period));      \times 2^(-1/6) else 2^(-1/12)
    Period:= Period * (if I&3 then 0.890898719 else 0.943874313);
    ];
]

\MIDI grand piano (requires 32-bit Windows or Sound Blaster 16):
code Sound=39;
int  Note, I;
[port($331):= $3F;      \set MPU-401 into UART mode
Note:= 60;              \start at middle C
for I:= 2 to 9+1 do     \(last note is not played)
    [port($330):= $90;  port($330):= Note;  port($330):= $7F;
    Sound(0, 4, 1);     \This "Sound" is off, but convenient 0.22 sec delay
    Note:= Note + (if I&3 then 2 else 1);
    ];
]

Yabasic

Translation of: Phix
// Rosetta Code problem: http://rosettacode.org/wiki/Musical_scale
// by Galileo, 03/2022

sample_rate = 44100
duration = 8
dataLength = sample_rate * duration
hdrSize = 44
fileLen = dataLength + hdrSize - 8
data 261.6, 293.6, 329.6, 349.2, 392.0, 440.0, 493.9, 523.3

sub int_to_bytes(dato, long)
    local dato$, esp, esp$, i
    
    esp$ = "00000000"
    dato$ = hex$(dato)
    esp = long * 2
    dato$ = right$(esp$ + dato$, esp)
    for i = esp - 1 to 1 step -2
        poke #fn, dec(mid$(dato$, i, 2))
    next
end sub

fn = open("notesyab.wav", "wb")

print #fn, "RIFF";
int_to_bytes(fileLen, 4)
print #fn, "WAVEfmt ";
int_to_bytes(16, 4)             // length of format data (= 16)
int_to_bytes(1, 2)              // type of format (= 1 (PCM))
int_to_bytes(1, 2)              // number of channels (= 1)
int_to_bytes(sample_rate, 4)    // sample rate
int_to_bytes(sample_rate, 4)    // sample rate * bps(8) * channels(1) / 8 (= sample rate)
int_to_bytes(1,2)               // bps(8) * channels(1) / 8  (= 1)
int_to_bytes(8,2)               // bits per sample (bps) (= 8)
print #fn, "data";
int_to_bytes(dataLength, 4)     // size of data section

for j = 1 to duration
    read f
    omega = 2 * PI * f
    for i = 0 to dataLength/duration-1 
        y = 32 * sin(omega * i / sample_rate)
        byte = and(y, 255)
        poke #fn, byte
    next
next

close(fn)
 
if peek$("os") = "windows" then
    system("notesyab.wav")
else // Linux
    system("aplay notesyab.wav")
endif

ZX Spectrum Basic

10 REM Musical scale
20 LET n=0: REM Start at middle C
30 LET d=0.2: REM Make each note 0.2 seconds in duration
40 FOR l=1 TO 8
50 BEEP d,n
60 READ i: REM Number of semitones to increment
70 LET n=n+i           
80 NEXT l
90 STOP
9000 DATA 2,2,1,2,2,2,1,2:REM WWHWWWH