How to resolve the algorithm Musical scale step by step in the Forth programming language
Published on 12 May 2024 09:40 PM
How to resolve the algorithm Musical scale step by step in the Forth programming language
Table of Contents
Problem Statement
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.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Musical scale step by step in the Forth programming language
Source code in the forth programming language
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 ;
You may also check:How to resolve the algorithm Rot-13 step by step in the Kotlin programming language
You may also check:How to resolve the algorithm Empty directory step by step in the F# programming language
You may also check:How to resolve the algorithm Pi step by step in the Ada programming language
You may also check:How to resolve the algorithm Subleq step by step in the Kotlin programming language
You may also check:How to resolve the algorithm Determine if a string has all unique characters step by step in the Clojure programming language