array insert at bottom signal()
signal().fundamental = basefreq
signal().theta = 0.0
signal().delta = (signal().fundamental * 360.0) / (1.0 * sample_rate)
signal().amplitude = 6044
REM Project: siggen1
REM Created: 6/16/2007 5:05:46 PM
REM
#constant MAX_VOLUME = 32767
#constant WAVE_FORMAT_PCM = 1
#constant SIZEOF_WAVEFORMATEX = 18
#constant SIZEOF_dbWAVEFORMATEX = 28
remstart
A bit of music theory will go a long way here. I am not a musician, but I do play
a bit of piano and guitar. I made these defines so that the code can be written to
conform to the mathematical model that music presents. The code so far has been
based on the theories of periodic wave motion as best described by Charles Fourier.
His work was the basis of work done by Nyquist, Shannon, and Cooley and Tukey. The
result of that work is pretty much all the digital stuff we take for granted today.
This is based on Western music as it stands now. That is for my convenience, but in
order to make music, you need a scale first...everything is based on the intervals,
and the number of intervals. The terms octave and harmonic are functionally
equivalent in this discussion. In my scale, there are twelve equally spaced (tempered)
intervals. Those intervals represent only 7 whole notes in the scale, so there are 7
naturals, and 5 accidentals. Accidentals are sharps and flats. The piano keyboard is a
wonderful visual tool to see this in action. The notes defined below are for the lowest
audible octave, which just so happens to be the first octave on a piano. There are 88
keys on a modern full-size piano, or 7 1/3 octaves. (7 X 12 = 84 + 4 = 88).
The frequency of the lowest note on a piano is 27.5hz, and it is an A.
The term octave refers to an 8 step interval because the interval between the 7th and
8th notes does count, but it does not end at a note in that octave. The 8th note is the
first note in the next octave. The term scale is used in a few ways that might be
confusing from this point on. The scale I just referred to is not the only one in use
in Western music at all, but all scales are derived from the one I just described to
you. Furthermore, there are modes that are derived from the scale, which determine
which notes "fit" and which do not. Scales are based on two things: the number of
notes, and their interval pattern. Modes further affect the notes used to make music.
Once a scale is established, you can create diatonics (intervals, diads, et al) and
also triads, or chords. Chords can contain more than three notes, but if there are
only two notes, that is most correctly termed an interval. Chord construction in
Western music is straightforward. In the notation below, the numbers are the notes
in the scale, and 'b' means flatted, '#' means sharp. The chord's base name is the
scale's name. In the chart below, I will use C.
Scale = C / D / E / F / G / A / B No accidentals.
Chord Construction Notes
Major 1 - 3 - 5 C E G
Major 6th 1 - 3 - 5 - 6 C E G A
Maj6add9 1 - 3 - 5 - 6 - 9 C E G A [D]
Major 7th 1 - 3 - 5 - 7 C E G B
Major 9th 1 - 3 - 5 - 7 - 9 C E G B [D]
Minor 1 - 3b- 5 C Eb G
Minor 6th 1 - 3b- 5 - 6 C Eb G A
Minor 7th 1 - 3b- 5 - 7b C Eb G Bb
Minor 7 flat 5 1 - 3b- 5b- 7b C Eb Gb Bb
Minor 9th 1 - 3b- 5 - 7 - 9b C Eb G Bb [D]
Dominant 7th 1 - 3 - 5 - 7b C E G Bb
Dom7Flat5 1 - 3 - 5b- 7b C E Gb Bb
Dom7Flat9 1 - 3 - 5 - 7b - 9b C E G Bb [Db]
Dom7Sharp9 1 - 3 - 5 - 7b - 9# C E G Bb [D#]
Dom7Suspended 1 - 3#- 5 - 7b C F G Bb
Dominant 9th 1 - 3 - 5 - 7b - 9 C E G Bb [D]
Dominant 13th 1 - 3 - 5 - 7b - 9 - 13 C E G Bb [D] [A]
Diminished 7th 1 - 3b- 5b- 7bb (sic) C Eb Gb A
Augmented 1 - 3 - 5# C E G#
Augmented 7th 1 - 3 - 5#- 7b C E G# Bb
Augmented 9th 1 - 3 - 5#- 7b - 9 C E G# Bb [D]
Augmented 11th 1 - 3 - 5 - 7b - 9 - 11 C E G Bb [D] [F]
remend
rem http://en.wikipedia.org/wiki/Piano_key_frequencies
#constant A_NATURAL = 27.5
#constant A_SHARP = 29.1353
#constant B_FLAT = 29.1353
#constant B_NATURAL = 30.8677
#constant C_NATURAL = 32.7032
#constant C_SHARP = 34.6479
#constant D_FLAT = 34.6479
#constant D_NATURAL = 36.7081
#constant D_SHARP = 38.8909
#constant E_FLAT = 38.8909
#constant E_NATURAL = 41.2035
#constant F_NATURAL = 43.6536
#constant F_SHARP = 46.2493
#constant G_FLAT = 46.2493
#constant G_NATURAL = 48.9995
#constant G_SHARP = 51.9130
type SINUSOIDAL_WAVE
fundamental as float rem Frequency
theta as float rem Instantaneous angle
delta as float rem Incremental rotation
amplitude as float rem Peak amplitude
endtype
dim signal() as SINUSOIDAL_WAVE
dim harmonics(14) as float rem 13 harmonics, plus fundamental.
global sound_block as integer
global offset as integer
global sample_rate as integer
global sample_size as integer
global num_channels as integer
global data_rate as integer
global i as integer
sound_block = 1
sample_rate = 24576
sample_size = 16
num_channels = 1
data_rate = ((sample_size * num_channels) / 8) * sample_rate
make memblock sound_block, 49152 + SIZEOF_dbWAVEFORMATEX
waveptr = get memblock ptr(sound_block)
inc waveptr, SIZEOF_dbWAVEFORMATEX
offset = 0
write memblock dword sound_block, offset, WAVE_FORMAT_PCM
inc offset, 4
write memblock dword sound_block, offset, num_channels
inc offset, 4
write memblock dword sound_block, offset, sample_rate
inc offset, 4
write memblock dword sound_block, offset, data_rate
inc offset, 4
write memblock dword sound_block, offset, 2
inc offset, 4
write memblock dword sound_block, offset, 16
inc offset, 4
write memblock dword sound_block, offset, 0
inc offset, 4
empty array signal()
SetVoice(1)
MakeNote(C_NATURAL * 5)
MakeNote(E_NATURAL * 5)
MakeNote(G_NATURAL * 5)
GenerateSignal16(waveptr, sample_rate)
if sound exist(1)
delete sound 1
endif
make sound from memblock 1, sound_block
delete memblock sound_block
loop sound 1
wait key
end
function SetVoice(voice as integer)
remstart
This is an unwritten function at this time. Once I have the necessary harmonic
profiles identified, this can be written, and the code would change somewhat at that
point. Volume ratios would be established, which would allow me to keep the wave
from clipping and also then this code would be able to have the overall volume
controlled elsewhere, which will be nice.
remend
harmonics(0) = 128.0
harmonics(1) = 1024.0
harmonics(2) = 512.0
harmonics(3) = 512.0
harmonics(4) = 256.0
harmonics(5) = 64.0
harmonics(6) = 64.0
harmonics(7) = 56.0
harmonics(8) = 48.0
harmonics(9) = 64.0
harmonics(10) = 64.0
harmonics(11) = 32.0
harmonics(12) = 0.0
harmonics(13) = 0.0
endfunction
function MakeNote(frequency as float)
local j as integer
for j = 0 to 13
if harmonics(j) > 1.0
array insert at bottom signal()
select j
case 0
signal().fundamental = frequency / 2
endcase
case 1
signal().fundamental = frequency
endcase
case default
signal().fundamental = frequency * j
endcase
endselect
signal().theta = 0.0
signal().delta = (signal().fundamental * 360.0) / (1.0 * sample_rate)
signal().amplitude = harmonics(j)
endif
next j
endfunction
function GenerateSignal16(ptr as dword, numsamples as integer)
local integrator as integer = 0
local i as integer
local j as integer
local wtemp as word
for i = 0 to numsamples - 1
integrator = 0
for j = 0 to array count(signal())
inc integrator, int(sin(wrapvalue(signal(j).theta)) * ...
signal(j).amplitude)
inc signal(j).theta, signal(j).delta
next j
wtemp = integrator
*ptr = wtemp
inc ptr, 2
next i
endfunction
REM Project: siggen1
REM Created: 6/16/2007 5:05:46 PM
REM
#constant MAX_VOLUME = 32767
#constant WAVE_FORMAT_PCM = 1
#constant SIZEOF_WAVEFORMATEX = 18
#constant SIZEOF_dbWAVEFORMATEX = 28
remstart
A bit of music theory will go a long way here. I am not a musician, but I do play
a bit of piano and guitar. I made these defines so that the code can be written to
conform to the mathematical model that music presents. The code so far has been
based on the theories of periodic wave motion as best described by Charles Fourier.
His work was the basis of work done by Nyquist, Shannon, and Cooley and Tukey. The
result of that work is pretty much all the digital stuff we take for granted today.
This is based on Western music as it stands now. That is for my convenience, but in
order to make music, you need a scale first...everything is based on the intervals,
and the number of intervals. The terms octave and harmonic are functionally
equivalent in this discussion. In my scale, there are twelve equally spaced (tempered)
intervals. Those intervals represent only 7 whole notes in the scale, so there are 7
naturals, and 5 accidentals. Accidentals are sharps and flats. The piano keyboard is a
wonderful visual tool to see this in action. The notes defined below are for the lowest
audible octave, which just so happens to be the first octave on a piano. There are 88
keys on a modern full-size piano, or 7 1/3 octaves. (7 X 12 = 84 + 4 = 88).
The frequency of the lowest note on a piano is 27.5hz, and it is an A.
The term octave refers to an 8 step interval because the interval between the 7th and
8th notes does count, but it does not end at a note in that octave. The 8th note is the
first note in the next octave. The term scale is used in a few ways that might be
confusing from this point on. The scale I just referred to is not the only one in use
in Western music at all, but all scales are derived from the one I just described to
you. Furthermore, there are modes that are derived from the scale, which determine
which notes "fit" and which do not. Scales are based on two things: the number of
notes, and their interval pattern. Modes further affect the notes used to make music.
Once a scale is established, you can create diatonics (intervals, diads, et al) and
also triads, or chords. Chords can contain more than three notes, but if there are
only two notes, that is most correctly termed an interval. Chord construction in
Western music is straightforward. In the notation below, the numbers are the notes
in the scale, and 'b' means flatted, '#' means sharp. The chord's base name is the
scale's name. In the chart below, I will use C.
The following scale is of the type diatonic, and is called a Major Scale. It is the
scale that the following chart is derived from. The pattern is:
step/step/half step/step/step/step/[half step]
Notes = C / D / E / F / G / A / B No accidentals.
Chord Construction Notes
Major 1 - 3 - 5 C E G
Major 6th 1 - 3 - 5 - 6 C E G A
Maj6add9 1 - 3 - 5 - 6 - 9 C E G A [D]
Major 7th 1 - 3 - 5 - 7 C E G B
Major 9th 1 - 3 - 5 - 7 - 9 C E G B [D]
Minor 1 - 3b- 5 C Eb G
Minor 6th 1 - 3b- 5 - 6 C Eb G A
Minor 7th 1 - 3b- 5 - 7b C Eb G Bb
Minor 7 flat 5 1 - 3b- 5b- 7b C Eb Gb Bb
Minor 9th 1 - 3b- 5 - 7 - 9b C Eb G Bb [D]
Dominant 7th 1 - 3 - 5 - 7b C E G Bb
Dom7Flat5 1 - 3 - 5b- 7b C E Gb Bb
Dom7Flat9 1 - 3 - 5 - 7b - 9b C E G Bb [Db]
Dom7Sharp9 1 - 3 - 5 - 7b - 9# C E G Bb [D#]
Dom7Suspended 1 - 3#- 5 - 7b C F G Bb
Dominant 9th 1 - 3 - 5 - 7b - 9 C E G Bb [D]
Dominant 13th 1 - 3 - 5 - 7b - 9 - 13 C E G Bb [D] [A]
Diminished 7th 1 - 3b- 5b- 7bb (sic) C Eb Gb A
Augmented 1 - 3 - 5# C E G#
Augmented 7th 1 - 3 - 5#- 7b C E G# Bb
Augmented 9th 1 - 3 - 5#- 7b - 9 C E G# Bb [D]
Augmented 11th 1 - 3 - 5 - 7b - 9 - 11 C E G Bb [D] [F]
remend
rem http://en.wikipedia.org/wiki/Physics_of_music
rem http://en.wikipedia.org/wiki/Musical_tuning
rem http://en.wikipedia.org/wiki/Diatonic_scale
rem http://en.wikipedia.org/wiki/Piano_key_frequencies
rem DIATONIC MAJOR SCALE RATIOS : 1 | 9/8 | 5/4 | 4/3 | 3/2 | 5/3 | 15/8
#constant A_NATURAL = 27.5
#constant A_SHARP = 29.1353
#constant B_FLAT = 29.1353
#constant B_NATURAL = 30.8677
#constant C_NATURAL = 32.7032
#constant C_SHARP = 34.6479
#constant D_FLAT = 34.6479
#constant D_NATURAL = 36.7081
#constant D_SHARP = 38.8909
#constant E_FLAT = 38.8909
#constant E_NATURAL = 41.2035
#constant F_NATURAL = 43.6536
#constant F_SHARP = 46.2493
#constant G_FLAT = 46.2493
#constant G_NATURAL = 48.9995
#constant G_SHARP = 51.9130
remstart
Now that an octave of notes are available to choose from, we can make our scale in
any key we want. Before we do that, here are the names of the notes in our scale:
1 - tonic
2 - supertonic, or second
3 - mediant, or major third
4 - subdominant, or fourth
5 - dominant, or fifth
6 - submediant, or major sixth
7 - leading tone, or major seventh
Modes are based on the use, or non-use of theses tones, and there is a lot of music
theory which makes heavy use of this terminology.
Using the note terminology, the major diatonic scale is constructed as follows:
tonic
supertonic Tonic to supertonic is a whole step.
mediant supertonic to mediant is a whole step.
subdominant mediant to subdominant is a half step.
dominant subdominant to dominant is a whole step.
submediant dominant to submediant is a whole step.
leading tone submediant to leading tone is a whole step.
[tonic] leading tone to next tonic is a half step.
Key Scale
C C - D - E - F - G - A - B
G G - A - B - C - D - E - F#
D D - E - F#- G - A - B - C#
A A - B - C#- D - E - F#- G#
E E - F#- G#- A - B - C#- D#
B B - C#- D#- E - F#- G#- A#
F F - G - A - A#- C - D - E
remend
type SINUSOIDAL_WAVE
fundamental as float rem Frequency
theta as float rem Instantaneous angle
delta as float rem Incremental rotation
amplitude as float rem Peak amplitude
endtype
dim signal() as SINUSOIDAL_WAVE
dim harmonics(14) as float rem 13 harmonics, plus fundamental.
global sound_block as integer
global offset as integer
global sample_rate as integer
global sample_size as integer
global num_channels as integer
global data_rate as integer
global i as integer
sound_block = 1
sample_rate = 24576
sample_size = 16
num_channels = 1
data_rate = ((sample_size * num_channels) / 8) * sample_rate
make memblock sound_block, 49152 + SIZEOF_dbWAVEFORMATEX
waveptr = get memblock ptr(sound_block)
inc waveptr, SIZEOF_dbWAVEFORMATEX
offset = 0
write memblock dword sound_block, offset, WAVE_FORMAT_PCM
inc offset, 4
write memblock dword sound_block, offset, num_channels
inc offset, 4
write memblock dword sound_block, offset, sample_rate
inc offset, 4
write memblock dword sound_block, offset, data_rate
inc offset, 4
write memblock dword sound_block, offset, 2
inc offset, 4
write memblock dword sound_block, offset, 16
inc offset, 4
write memblock dword sound_block, offset, 0
inc offset, 4
empty array signal()
remstart
Em9 1 - 3b- 5 - 7 - 9b E - G - B- D#- [Fb]
This is simulating a guitar chord, so the notes are in different octaves. This
particular chord is the very first chord in Pink Floyd's "Breathe" from
"Dark Side Of The Moon". That chord and its close relatives are all over that album,
and the variations that David Gilmour makes to the basic Em chord are typical of his
style. When the piece called "Speak To Me" ends, there is a swelling of keyboards
and the opening guitar chord is a reverse-raked Em9.
remend
SetVoice(1)
MakeNote(E_NATURAL * 2)
MakeNote(G_NATURAL * 3)
MakeNote(B_NATURAL * 4)
MakeNote(D_SHARP * 5)
MakeNote(F_FLAT * 6)
GenerateSignal16(waveptr, sample_rate)
if sound exist(1)
delete sound 1
endif
make sound from memblock 1, sound_block
delete memblock sound_block
loop sound 1
do
loop
end
function SetVoice(voice as integer)
select voice
case default
harmonics(0) = 64.0
harmonics(1) = 1024.0
harmonics(2) = 512.0
harmonics(3) = 256.0
harmonics(4) = 256.0
harmonics(5) = 128.0
harmonics(6) = 128.0
harmonics(7) = 64.0
harmonics(8) = 64.0
harmonics(9) = 128.0
harmonics(10) = 32.0
harmonics(11) = 16.0
harmonics(12) = 128.0
harmonics(13) = 128.0
endcase
endselect
endfunction
function MakeNote(frequency as float)
local j as integer
for j = 0 to 13
if harmonics(j) > 1.0
array insert at bottom signal()
select j
case 0
signal().fundamental = frequency / 2
endcase
case 1
signal().fundamental = frequency
endcase
case default
signal().fundamental = frequency * j
endcase
endselect
signal().theta = 0.0
signal().delta = (signal().fundamental * 360.0) / (1.0 * sample_rate)
signal().amplitude = harmonics(j)
endif
next j
endfunction
function GenerateSignal16(ptr as dword, numsamples as integer)
local integrator as integer = 0
local i as integer
local j as integer
local wtemp as word
for i = 0 to numsamples - 1
integrator = 0
for j = 0 to array count(signal())
inc integrator, int(sin(wrapvalue(signal(j).theta)) * ...
signal(j).amplitude)
inc signal(j).theta, signal(j).delta
next j
wtemp = integrator
*ptr = wtemp
inc ptr, 2
next i
endfunction
Load DLL "Kernel32",3
length=200
Do
Call DLL 3,"Beep",frequency,length
inc frequency,50
Loop