Musical scale: Difference between revisions
Content deleted Content added
Simple9371 (talk | contribs) →{{header|JavaScript}}: Music playing on page load doesn't work anymore |
|||
(13 intermediate revisions by 9 users not shown) | |||
Line 71:
Do-1703 Re-1517 Mi-1350 Fa-1274 Sol-1134 La-1010 Si-899 Do-848
</pre>
=={{header|Ada}}==
{{works with|GNAT Ada 2022}}
Ada runs everywhere, so we can't assume a sound device. This program outputs both a MIDI and a WAV audio file.
<syntaxhighlight lang="ada">
pragma Ada_2022;
with Ada.Numerics; use Ada.Numerics;
with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions;
with Ada.Sequential_IO;
with Interfaces; use Interfaces;
procedure Musical_Scale is
package Byte_IO is new Ada.Sequential_IO (Unsigned_8); use Byte_IO;
SAMPLE_RATE : constant Unsigned_32 := 44100;
DURATION : constant Unsigned_32 := 8;
DATA_LENGTH : constant Unsigned_32 := SAMPLE_RATE * DURATION;
WAV_HDR_LEN : constant Integer := 44;
FILE_SIZE_8 : constant Unsigned_32 := Unsigned_32 (WAV_HDR_LEN) + DATA_LENGTH + 4;
type Byte_Arr is array (Positive range <>) of Unsigned_8;
Wav_Header : constant Byte_Arr (1 .. WAV_HDR_LEN) := [
Character'Pos ('R'), Character'Pos ('I'), Character'Pos ('F'), Character'Pos ('F'),
Unsigned_8 (FILE_SIZE_8 and 16#ff#),
Unsigned_8 (Shift_Right (FILE_SIZE_8, 8) and 16#ff#),
Unsigned_8 (Shift_Right (FILE_SIZE_8, 16) and 16#ff#),
Unsigned_8 (Shift_Right (FILE_SIZE_8, 24) and 16#ff#),
Character'Pos ('W'), Character'Pos ('A'), Character'Pos ('V'), Character'Pos ('E'),
Character'Pos ('f'), Character'Pos ('m'), Character'Pos ('t'), Character'Pos (' '),
16#10#, 0, 0, 0, 1, 0, 1, 0, 16#44#, 16#ac#, 0, 0, 16#44#, 16#ac#, 0, 0, 1, 0, 8, 0,
Character'Pos ('d'), Character'Pos ('a'), Character'Pos ('t'), Character'Pos ('a'),
Unsigned_8 (DATA_LENGTH and 16#ff#),
Unsigned_8 (Shift_Right (DATA_LENGTH, 8) and 16#ff#),
Unsigned_8 (Shift_Right (DATA_LENGTH, 16) and 16#ff#),
Unsigned_8 (Shift_Right (DATA_LENGTH, 24) and 16#ff#)
];
MIDI_Header : constant Byte_Arr (1 .. 22) := [
Character'Pos ('M'), Character'Pos ('T'), Character'Pos ('h'), Character'Pos ('d'),
0, 0, 0, 6, 0, 0, 0, 1, 0, 96, -- File header
Character'Pos ('M'), Character'Pos ('T'), Character'Pos ('r'), Character'Pos ('k'),
0, 0, 0, 8 * 8 + 4 -- Track header
];
MIDI_Trailer : constant Byte_Arr := [0, 16#ff#, 16#2f#, 0];
type Freq_Arr is array (Positive range <>) of Float;
Freqs : constant Freq_Arr := [261.63, 293.67, 329.63, 349.23, 392.0, 440.0, 493.88, 523.25];
Notes : constant Byte_Arr := [60, 62, 64, 65, 67, 69, 71, 72];
Note_On_Off : Byte_Arr := [0, 16#90#, 0, 16#40#, 16#60#, 16#80#, 0, 0];
Wav_File, MIDI_File : File_Type;
Omega : Float;
procedure Write_Arr (File : File_Type; Arr : Byte_Arr) is
begin
for B of Arr loop
Write (File, B);
end loop;
end Write_Arr;
begin
Create (Wav_File, Out_File, "scale.wav");
Write_Arr (Wav_File, Wav_Header);
for Freq of Freqs loop
Omega := 2.0 * Pi * Freq;
for Tick in 0 .. Integer (DATA_LENGTH) / 8 loop
Write (Wav_File, Unsigned_8 (32.0 * (Sin (Omega * Float (Tick) / Float (SAMPLE_RATE)) + 1.0)));
end loop;
end loop;
Close (Wav_File);
Create (MIDI_File, Out_File, "scale.mid");
Write_Arr (MIDI_File, MIDI_Header);
for Note of Notes loop
Note_On_Off (3) := Note;
Note_On_Off (7) := Note;
Write_Arr (MIDI_File, Note_On_Off);
end loop;
Write_Arr (MIDI_File, MIDI_Trailer);
Close (MIDI_File);
end Musical_Scale;
</syntaxhighlight>
=={{header|AmigaBASIC}}==
Line 319 ⟶ 399:
=={{header|EasyLang}}==
<syntaxhighlight lang="text">
n[] = [ 262 294 330 349 392 440 494 523 ]
for t
sound [ t 0.5 ]
sleep 0.6
.
</syntaxhighlight>
=={{header|Emacs Lisp}}==
Line 537 ⟶ 619:
beep(Round(440.0*interval**i),500);
end.</syntaxhighlight>
=={{header|FutureBasic}}==
This code generates a fully playable 3-ocatave piano keyboard with Middle C on the eighth white key.
<syntaxhighlight lang="futurebasic">
output file "FB Piano Keyboard"
include "Tlbx AudioToolbox.incl"
_window = 1
begin enum output 1
_whiteKey01
_whiteKey02
_whiteKey03
_whiteKey04
_whiteKey05
_whiteKey06
_whiteKey07
_whiteKey08
_whiteKey09
_whiteKey10
_whiteKey11
_whiteKey12
_whiteKey13
_whiteKey14
_whiteKey15
_whiteKey16
_whiteKey17
_whiteKey18
_whiteKey19
_whiteKey20
_whiteKey21
_whiteKey22
_blackKey23
_blackKey24
_blackKey25
_blackKey26
_blackKey27
_blackKey28
_blackKey29
_blackKey30
_blackKey31
_blackKey32
_blackKey33
_blackKey34
_blackKey35
_blackKey36
_blackKey37
_infoField
_playBtn
_note01
_note02
_note03
_note04
_note05
_note06
_note07
_note08
_note09
_note10
_note11
_note12
_note13
_note14
_note15
_note16
_note17
_note18
_note19
_note20
_note21
_note22
end enum
begin enum output
_kMidiMessageControlChange = 0xB
_kMidiMessageProgramChange = 0xC
_kMidiMessageBankMSBControl = 0
_kMidiMessageBankLSBControl = 32
_kMidiMessageNoteOn = 0x9
end enum
BeginCDeclaration
AudioUnit synthUnit;
AUGraph graph;
EndC
void local fn PlayNote( noteNum as UInt32 )
BeginCCode
UInt8 midiChannelInUse = 0;
MusicDeviceMIDIEvent( synthUnit, kMidiMessageControlChange << 4 | midiChannelInUse, kMidiMessageBankMSBControl, 0, 0 ); //2022-Jan-04 Brian
MusicDeviceMIDIEvent( synthUnit, kMidiMessageProgramChange << 4 | midiChannelInUse, 0, 0, 0 );
AUGraphStart( graph );
UInt32 onVelocity = 127;
UInt32 noteOnCommand = kMidiMessageNoteOn << 4 | midiChannelInUse; //2022-Jan-04 Brian
MusicDeviceMIDIEvent( synthUnit, noteOnCommand, noteNum, onVelocity, 0 );
usleep ( 1 * 500 * 600 ); // 0.6 second sleep
MusicDeviceMIDIEvent( synthUnit, noteOnCommand, noteNum, 0, 0);
EndC
end fn
void local fn InitializeSynth
BeginCCode
AUNode synthNode, limiterNode, outNode;
AudioComponentDescription cd;
graph = 0;
synthUnit = 0;
cd.componentManufacturer = kAudioUnitManufacturer_Apple;
cd.componentFlags = 0;
cd.componentFlagsMask = 0;
NewAUGraph (&graph);
cd.componentType = kAudioUnitType_MusicDevice;
cd.componentSubType = kAudioUnitSubType_DLSSynth;
AUGraphAddNode (graph, &cd, &synthNode);
cd.componentType = kAudioUnitType_Effect;
cd.componentSubType = kAudioUnitSubType_PeakLimiter;
AUGraphAddNode (graph, &cd, &limiterNode);
cd.componentType = kAudioUnitType_Output;
cd.componentSubType = kAudioUnitSubType_DefaultOutput;
AUGraphAddNode (graph, &cd, &outNode);
AUGraphOpen (graph);
AUGraphConnectNodeInput (graph, synthNode, 0, limiterNode, 0);
AUGraphConnectNodeInput (graph, limiterNode, 0, outNode, 0);
AUGraphNodeInfo ( graph, synthNode, 0, &synthUnit );
AUGraphInitialize (graph);
EndC
end fn
local fn CreateKeyImage
CGRect r = {0,0,28,162}
ImageRef image = fn ImageWithSize( fn CGSizeMake( 28.0, 162.0 ) )
ImageLockFocus( image )
BezierPathFillRect( r, fn ColorBlack )
ImageUnlockFocus( image )
ImageSetName( image, @"KeyImage" )
end fn
void local fn BuildWindow
NSInteger i, count
NSInteger wndStyleMask = NSWindowStyleMaskTitled
wndStyleMask += NSWindowStyleMaskClosable
wndStyleMask += NSWindowStyleMaskMiniaturizable
CGRect r = {0,0,850,340}
window _window, @"FB Piano Keyboard", r, wndStyleMask
WindowSetBackgroundColor( _window, fn ColorWithRGB( 0.400, 0.400, 0.400, 1.0 ) )
// White keys
r = fn CGRectMake( 30, 30, 38, 250 )
for i = _whiteKey01 to _whiteKey22
button i,,,@"", r, NSButtonTypeMomentaryLight, NSBezelStyleTexturedSquare, _window
CALayerRef layer = fn CALayerInit
CALayerSetBackgroundColor( layer, fn ColorWithRGB( 0.800, 0.800, 0.800, 1.0 ) )
ViewSetWantsLayer( i, YES )
ViewSetLayer( i, layer )
r = fn CGRectOffset( r, 36, 0 )
next
// Black keys
r = fn CGRectMake( 52, 110, 28, 169 )
for i = _blackKey23 to _blackKey37
button i,,,@"", r, NSButtonTypeMomentaryLight, NSBezelStyleShadowlessSquare, _window
ButtonSetImageNamed( i, @"KeyImage" )
if ( i == 24 ) or ( i == 27 ) or ( i == 29 ) or ( i == 32 ) or ( i == 34 )
r = fn CGRectOffset( r, 72, 0 )
else
r = fn CGRectOffset( r, 36, 0 )
end if
next
r = fn CGRectMake( 30, 290, 240, 24 )
textfield _infoField,,,r, _window
TextFieldSetEditable( _infoField, NO )
TextFieldSetSelectable( _infoField, NO )
TextFieldSetDrawsBackground( _infoField, NO )
TextFieldSetBordered( _infoField, NO )
CFStringRef s = @"C,D,E,F,G,A,B,C,D,E,F,G,A,B,C,D,E,F,G,A,B,C"
CFArrayRef a = fn StringComponentsSeparatedByString( s, @"," )
r = fn CGRectMake( 30, 10, 38, 19 )
count = 0
for i = _note01 to _note22
textfield i,, fn ArrayObjectAtIndex( a, count ), r, _window
TextFieldSetDrawsBackground( i, NO )
TextFieldSetBordered( i, NO )
TextFieldSetEditable( i, NO )
TextFieldSetSelectable( i, NO )
TextSetAlignment( i, NSTextAlignmentCenter )
TextSetFontWithName( i, @"Menlo", 14.0 )
r = fn CGRectOffset( r, 36, 0 )
count++
next
end fn
local fn DoDialog( ev as NSUInteger, tag as NSUInteger, wnd as NSUInteger )
select (ev)
case _btnClick
select (tag)
case 1 : fn PlayNote( 53 ) : ControlSetStringValue( _infoField, @"C, Note 53, White key No. 1" )
case 2 : fn PlayNote( 55 ) : ControlSetStringValue( _infoField, @"D, Note 55, White key No. 2" )
case 3 : fn PlayNote( 57 ) : ControlSetStringValue( _infoField, @"E, Note 57, White key No. 3" )
case 4 : fn PlayNote( 58 ) : ControlSetStringValue( _infoField, @"F, Note 58, White key No. 4" )
case 5 : fn PlayNote( 60 ) : ControlSetStringValue( _infoField, @"G, Note 60, White key No. 5" )
case 6 : fn PlayNote( 62 ) : ControlSetStringValue( _infoField, @"A, Note 62, White key No. 6" )
case 7 : fn PlayNote( 64 ) : ControlSetStringValue( _infoField, @"B, Note 64, White key No. 7" )
case 8 : fn PlayNote( 65 ) : ControlSetStringValue( _infoField, @"C, Note 65, White key No. 8" )
case 9 : fn PlayNote( 67 ) : ControlSetStringValue( _infoField, @"D, Note 67, White key No. 9" )
case 10 : fn PlayNote( 69 ) : ControlSetStringValue( _infoField, @"E, Note 69, White key No. 10" )
case 11 : fn PlayNote( 70 ) : ControlSetStringValue( _infoField, @"F, Note 70, White key No. 11" )
case 12 : fn PlayNote( 72 ) : ControlSetStringValue( _infoField, @"G, Note 72, White key No. 12" )
case 13 : fn PlayNote( 74 ) : ControlSetStringValue( _infoField, @"A, Note 74, White key No. 13" )
case 14 : fn PlayNote( 76 ) : ControlSetStringValue( _infoField, @"B, Note 76, White key No. 14" )
case 15 : fn PlayNote( 77 ) : ControlSetStringValue( _infoField, @"C, Note 77, White key No. 15" )
case 16 : fn PlayNote( 79 ) : ControlSetStringValue( _infoField, @"D, Note 79, White key No. 16" )
case 17 : fn PlayNote( 81 ) : ControlSetStringValue( _infoField, @"E, Note 81, White key No. 17" )
case 18 : fn PlayNote( 82 ) : ControlSetStringValue( _infoField, @"F, Note 82, White key No. 18" )
case 19 : fn PlayNote( 84 ) : ControlSetStringValue( _infoField, @"G, Note 84, White key No. 19" )
case 20 : fn PlayNote( 86 ) : ControlSetStringValue( _infoField, @"A, Note 86, White key No. 20" )
case 21 : fn PlayNote( 88 ) : ControlSetStringValue( _infoField, @"B, Note 88, White key No. 21" )
case 22 : fn PlayNote( 89 ) : ControlSetStringValue( _infoField, @"C, Note 88, White key No. 22" )
case 23 : fn PlayNote( 54 ) : ControlSetStringValue( _infoField, @"C#/D\u266D, Note 54, Black key No. 23" )
case 24 : fn PlayNote( 56 ) : ControlSetStringValue( _infoField, @"D#/E\u266D, Note 56, Black key No. 24" )
case 25 : fn PlayNote( 59 ) : ControlSetStringValue( _infoField, @"F#/G\u266D, Note 59, Black key No. 25" )
case 26 : fn PlayNote( 61 ) : ControlSetStringValue( _infoField, @"G#/A\u266D, Note 61, Black key No. 26" )
case 27 : fn PlayNote( 63 ) : ControlSetStringValue( _infoField, @"A#/B\u266D, Note 63, Black key No. 27" )
case 28 : fn PlayNote( 66 ) : ControlSetStringValue( _infoField, @"C#/D\u266D, Note 66, Black key No. 28" )
case 29 : fn PlayNote( 68 ) : ControlSetStringValue( _infoField, @"D#/E\u266D, Note 68, Black key No. 29" )
case 30 : fn PlayNote( 71 ) : ControlSetStringValue( _infoField, @"F#/G\u266D, Note 71, Black key No. 30" )
case 31 : fn PlayNote( 73 ) : ControlSetStringValue( _infoField, @"G#/A\u266D, Note 73, Black key No. 31" )
case 32 : fn PlayNote( 75 ) : ControlSetStringValue( _infoField, @"A#/B\u266D, Note 75, Black key No. 32" )
case 33 : fn PlayNote( 78 ) : ControlSetStringValue( _infoField, @"C#/C\u266D, Note 78, Black key No. 33" )
case 34 : fn PlayNote( 80 ) : ControlSetStringValue( _infoField, @"D#/E\u266D, Note 80, Black key No. 34" )
case 35 : fn PlayNote( 83 ) : ControlSetStringValue( _infoField, @"F#/G\u266D, Note 83, Black key No. 35" )
case 36 : fn PlayNote( 85 ) : ControlSetStringValue( _infoField, @"G#/A\u266D, Note 85, Black key No. 36" )
case 37 : fn PlayNote( 87 ) : ControlSetStringValue( _infoField, @"A#/B\u266D, Note 87, Black key No. 37" )
end select
case _windowWillClose : end
end select
end fn
void local fn DoAppEvent( ev as long )
select (ev)
case _appWillFinishLaunching
fn InitializeSynth
fn CreateKeyImage
fn BuildWindow
end select
end fn
on appevent fn DoAppEvent
on dialog fn DoDialog
HandleEvents
</syntaxhighlight>
{{output}}
[[File:FB Piano Keyboard.png]]
=={{header|Go}}==
Line 620 ⟶ 973:
0.25 is the duration of each note (in seconds).
=={{header|Java}}==
Java can play sounds without external libraries.
<syntaxhighlight lang="java">
import java.util.List;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
public final class MusicalScale {
public static void main(String[] aArgs) {
List<Double> frequencies = List.of( 261.63, 293.66, 329.63, 349.23, 392.00, 440.00, 493.88, 523.25 );
final int duration = 500;
final int volume = 1;
for ( int i = 0; i < 3; i++ ) {
for ( double frequency : frequencies ) {
musicalTone(frequency, duration, volume);
}
}
}
private static void musicalTone(double aFrequency, int aDuration, int aVolume) {
byte[] buffer = new byte[1];
AudioFormat audioFormat = getAudioFormat();
try ( SourceDataLine sourceDataLine = AudioSystem.getSourceDataLine(audioFormat) ) {
sourceDataLine.open(audioFormat);
sourceDataLine.start();
for ( int i = 0; i < aDuration * 8; i++ ) {
double angle = i / ( SAMPLE_RATE / aFrequency ) * 2 * Math.PI;
buffer[0] = (byte) ( Math.sin(angle) * 127 * aVolume );
sourceDataLine.write(buffer, BYTE_OFFSET, buffer.length);
}
sourceDataLine.drain();
sourceDataLine.stop();
sourceDataLine.close();
} catch (LineUnavailableException exception) {
exception.printStackTrace();
}
}
private static AudioFormat getAudioFormat() {
final int sampleSizeInBits = 8;
final int numberChannels = 1;
final boolean signedData = true;
final boolean isBigEndian = false;
return new AudioFormat(SAMPLE_RATE, sampleSizeInBits, numberChannels, signedData, isBigEndian);
}
private static float SAMPLE_RATE = 8_000.0F;
private static final int BYTE_OFFSET = 0;
}
</syntaxhighlight>
=={{header|JavaScript}}==
Line 641 ⟶ 1,054:
oscillator.connect(gainNode);
gainNode.connect(audioCtx.destination);
// set frequencies to play
duration = 0.5 // seconds
Line 647 ⟶ 1,060:
oscillator.frequency.setValueAtTime(freq, audioCtx.currentTime + i * duration);
});
// start playing!
oscillator.start();
Line 703 ⟶ 1,116:
}</syntaxhighlight>
=={{header|
The
<syntaxhighlight lang="lilypond">% Start at middle C
\relative c' {
Line 710 ⟶ 1,123:
g a b c
}</syntaxhighlight>
=={{header|Lambdatalk}}==
<syntaxhighlight lang="Scheme">
Using the musicalScale() javascript function found in this wiki page, we build a lambdatalk interface to output the 8 notes of the C major diatonic scale, and more.
{def note
{lambda {:i}
{round {* 261.63 {pow 2 {/ :i 12}}}}}}
{def scale
{lambda {:notes}
[{S.map {lambda {:i} {note :i},} :notes}]}}
{def play
{lambda {:n}
{input {@ type="button"
value="Play :n"
onclick="musicalScale({scale :n});"}}}}
1) diatonic up
{play 0 2 4 5 7 9 11 12}
2) diatonic down
{play 12 11 9 7 5 4 2 0}
3) twelve notes of the octave plus one
{play {S.serie 0 12}}
4) one more ... from Fantasia (Disney Studios, 1940)
{play 0 2 3 5 7 3 7 7 6 2 6 6 7 3 7 7 0 2 3 5 7 3 7 12 10 7 3 7 10 10 10 10}
->
</syntaxhighlight>
=={{header|Locomotive Basic}}==
Line 1,072 ⟶ 1,518:
winsound.Beep(int(note+.5), 500)
>>> </syntaxhighlight>
'''Library:''' SDL2 (pip install PySDL2)
<syntaxhighlight lang="python">
import sys
import ctypes
import math
import time
import struct
import sdl2
import sdl2.sdlmixer as mixer
def create_sound(frequency, duration):
"""Create a buffer with sound at given frequency and duration"""
num_samples = int(48000 * duration)
wave = struct.pack(
f"<{num_samples}i",
*[
int(2**30 * math.sin(2 * math.pi * frequency / 48000 * t))
for t in range(num_samples)
]
)
length = num_samples * 4
sound_buffer = (ctypes.c_ubyte * length).from_buffer_copy(wave)
sound = mixer.Mix_QuickLoad_RAW(
ctypes.cast(sound_buffer, ctypes.POINTER(ctypes.c_ubyte)), length
)
return sound
def main():
"""Play sine wave"""
mixer.Mix_Init(0)
mixer.Mix_OpenAudioDevice(48000, sdl2.AUDIO_S32, 1, 2048, None, 0)
note = 261.63
semitone = math.pow(2, 1 / 12)
duration = 0.5 # seconds
for step in [0, 2, 2, 1, 2, 2, 2, 1]:
note *= semitone**step
sound = create_sound(note, duration)
mixer.Mix_PlayChannel(0, sound, 1)
time.sleep(duration)
return 0
if __name__ == "__main__":
sys.exit(main())
</syntaxhighlight>
=={{header|R}}==
Line 1,182 ⟶ 1,682:
[https://www.dropbox.com/s/jf34s6apalw0k7c/CalmoSoftMusicalScale.avi?dl=0 Musical scale]
=={{header|RPL}}==
≪ 2 SWAP 12 / ^ 440 * ≫ '<span style="color:blue>FREQ</span>' STO
≪ { -9 -7 -5 -4 -2 0 2 3 }
1 OVER SIZE '''FOR''' j
DUP j GET <span style="color:blue>FREQ</span> .1 BEEP '''NEXT'''
DROP
≫ '<span style="color:blue>GAMME</span>' STO
=={{header|Scala}}==
Line 1,371 ⟶ 1,880:
{{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="
var sampleRate = 44100
Line 1,389 ⟶ 1,898:
It's also possible to play .wav files which (preferably) have a sample rate of 44.1 kHz using DOME:
{{libheader|DOME}}
<syntaxhighlight lang="
class Main {
|