Musical scale: Difference between revisions

Content deleted Content added
Line 199: Line 199:
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>\ play a scale
<lang>HEX

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 210: Line 208:
: silence ( -- ) sctrl pc@ smask and 01 or sctrl pc! ;
: silence ( -- ) sctrl pc@ smask and 01 or sctrl pc! ;


HEX
: tone ( divisor -- )
: tone ( divisor -- )
?dup \ check for non-zero input
?dup \ check for non-zero input
Line 217: Line 214:
8 rshift fctrl pc! \ load high byte
8 rshift fctrl pc! \ load high byte
sing
sing

else silence
else silence
then ;
then ;
Line 230: Line 226:
variable off_time
variable off_time
variable feel \ controls the on/off time ratio
variable feel \ controls the on/off time ratio

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


60 value tempo
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
: bpm>ms ( bpm -- ms) timebase rot um/mod nip ; \ convert beats per minute to milliseconds
: play ( divisor -- ) tone on_time @ ms silence off_time @ ms ;
: rest ( -- ) note ms ;
: 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
: expression ( ms n --) \ adjust the on:off ratio using n
Line 244: Line 241:
off_time ! on_time ! ; \ store times in variables
off_time ! on_time ! ; \ store times in variables


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


: duration! ( ms -- ) feel @ expression ;
: duration! ( ms -- ) feel @ expression ;
Line 255: Line 252:


MUSIC DEFINITIONS
MUSIC DEFINITIONS

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


: legato wholenote 3 % feel ! ;
: legato wholenote 2 feel ! ;
: staccatto wholenote 25 % feel ! ;
: staccatto wholenote 8 % feel ! ;
: Marcato wholenote 10 % feel ! ;
: Marcato wholenote 3 % feel ! ;


: 1/1 wholenote duration! ;
: 1/1 wholenote duration! ;
Line 273: Line 269:
: 1/16 1/8 note 50% duration! ;
: 1/16 1/8 note 50% duration! ;
: 1/32 1/16 note 50% duration! ;
: 1/32 1/16 note 50% duration! ;
: rest note ms ;


\ note object creator
\ note object creator
Line 292: Line 289:
: 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 ;
</lang>
</lang>
=== Test at the Console ===
<pre>music ok
120 bpm legato cmajor ok
200 bpm marcato chromatic ok
72 BPM legato c3 eb3 g3 c4 ok
</pre>


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