I don't think the memblock header info matches the wave file header info.
I might have a working demo somewhere. I'll see if I can dig it out.
Edit Here's one demo. I'm afraid I haven't time to simplify it now. If you run the demo and click the notes you'll hear the notes as they are clicked. The individual notes are saved to the project's directory.
set display mode desktop width(), desktop height(), 32
autocam off
position camera 0, -50, -600
point camera 0, 0, 0
position light 0, 0, 50, -500
point light 0, 0, 0, 0
a# = 0.057762265 ` = (ln 2)/12
b# = 4.1588831 ` = (ln 256) - 24*(ln 2)/12
color backdrop rgb(5,5,5)
type note
name as string
sound
endtype
dim rawNotes(11,5,5) as note
` this array points to basic notes stored as DBP sounds
` the first index represents one of the 12 notes
` C, C#, D, D#, E, F, F#, G, G#, A, A#, B
` the second represents the octave, e.g.
` 2 represents the octave starting with middle C (256 Hz in this program)
` the third represents the duration in seconds:
` 0.25, 0.5, 1.0, 2.0, 4.0, 8.0
`
` the notes are created as they are needed - a value of zero in this
` array indicates the note has not been created yet, otherwise the value
` represents the stored sound number
` initialise
for note=0 to 11
read s$
data "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"
for octave=0 to 5
for duration=0 to 5
rawNotes(note,octave,duration).name = s$+str$(octave)
rawNotes(note,octave,duration).sound = 0
next duration
next octave
next note
dim whiteNotes(72)
` a value of 1 indicates a white note on a standard piano keyboard
` 2 indicates a black note
` initialise whiteNotes array
data 1,2,1,2,1,1,2,1,2,1,2,1
data 1,2,1,2,1,1,2,1,2,1,2,1
data 1,2,1,2,1,1,2,1,2,1,2,1
data 1,2,1,2,1,1,2,1,2,1,2,1
data 1,2,1,2,1,1,2,1,2,1,2,1
data 1,2,1,2,1,1,2,1,2,1,2,1
for w=1 to 72
read v
whiteNotes(w)=v
next w
` make keyboard
k=1
for octave=0 to 5
xpos = -86
for note=0 to 11
make object plain k, 30/whiteNotes(k), 80/whiteNotes(k)
colour = 255 * (2 - whiteNotes(k))
color object k, rgb(colour,colour*(k<>25),colour*(k<>25))
` picks out middle C in red
position object k, xpos, octave*90 - 225, 1 - whiteNotes(k)
inc xpos, 17 + (note=4)*17
inc k
next note
next octave
` make wave file header
dim wavHeader(39) as byte
for h=0 to 39
read v
wavHeader(h) = v
next h
data 82, 73, 70, 70, 0, 0, 0, 0 ` i.e. RIFF????# ????=file size in bytes - 8 to complete later
data 87, 65, 86, 69, 102, 109, 116, 32 ` WAVEfmt #
data 16, 0, 0, 0, 1, 0, 1, 0 ` ????**--# ????=subchunk size=16,**=audioformat,--=nChannels
data 34, 86, 0, 0, 68, 172, 0, 0 ` ????****# ????=samples per sec,****=bytes per sec
data 2, 0, 16, 0, 100, 97, 116, 97 ` ??**data# ??=bytes per block,**=bits per sample
`data 0, 0, 0, 0 ` ????# ????=no of bytes in sound data to complete later
soundNum=1
previousSound=1
repeat
noteNum = -1
text 20, 20, "FPS = "+str$(screen fps())
if mouseclick() then noteNum=pick object(mousex(), mousey(), 1, 72) - 1
if noteNum>-1
frequency# = exp(noteNum * a# + b#) ` probably not standard frequencies
text 20, 50, "noteNum "+str$(noteNum)
note = noteNum MOD 12
octave = (noteNum + 0.5)/12.0
duration = 0: duration# = 2^duration/4.0
name$ = rawNotes(note, octave, duration).name
text 20, 70, "name "+name$
text 20, 90, "octave = "+str$(octave)
text 20, 110, "duration = "+str$(duration#)+" secs"
text 20, 130, "Sound "+str$(rawNotes(note, octave, duration).sound)
text 20, 150, "Frequency = "+str$(frequency#,2)
if rawNotes(note, octave, duration).sound = 0
makeRawNote(soundNum, name$, duration#, frequency#)
rawNotes(note, octave, duration).sound = soundNum
inc soundNum
endif
soundNow = rawNotes(note, octave, duration).sound
if sound playing(previousSound) = 0
play sound soundNow
previousSound = soundNow
endif
endif
until spacekey()
end
function makeRawNote(soundNum, name$, duration#, frequency#)
outWord as word
dword1 as dword: dword2 as dword: dword3 as dword: dword4 as dword
dword5 as dword: dword6 as dword: dword7 as dword
samples = int(duration#*22050+0.5)
` samples = int(duration#*44100+0.5) ` doesn't work with U6.5
balance# = 32767.0*64.0/frequency# ` quick fix to make low notes more audible
if memblock exist(1) then delete memblock 1
make memblock 1, samples*2+28
` write 28 memblock header bytes
dword1=1 ` gg query: is this the sound format ?
dword2=1 ` gg query: is this the number of channels ?
dword3=22050 ` gg query: seems to be the number of samples per second ?
dword4=44100 ` gg query: the number of bytes per second ?
dword5=2 ` gg query: bytes per block ?
dword6=16 ` gg query: bits per sample ?
dword7=0 ` gg query: not used ?
position=0
write memblock dword 1, position, dword1 : inc position,4
write memblock dword 1, position, dword2 : inc position,4
write memblock dword 1, position, dword3 : inc position,4
write memblock dword 1, position, dword4 : inc position,4
write memblock dword 1, position, dword5 : inc position,4
write memblock dword 1, position, dword6 : inc position,4
write memblock dword 1, position, dword7 : inc position,4
` write sound info
fadeRange# = 250.0
for x=1 to samples
if x<fadeRange#
fade# = (x - 1.0)/fadeRange#
else
if x>samples-fadeRange#
fade# = (samples - x)/fadeRange#
else
fade# = 1.0
endif
endif
outInteger=(sin((x/61.25) * frequency#) * balance# * fade#)
if outInteger < -32767 then outInteger = -32767
if outInteger > 32767 then outInteger = 32767
outWord = outInteger
write memblock word 1, position, outWord : inc position,2
next x
make sound from memblock soundNum, 1
` now save the sound
fileName$=name$+str$(duration#*4,0)+".wav"
if file exist(fileName$)=1 then delete file fileName$
open to write 1,fileName$
chunk=int((samples*16)/8) `sample size in bytes (no of samples * bitrate * channels / 8)
chunk2=chunk+36 `sample bytes plus remaining header bytes
` fill in missing bytes here
for x=0 to 3
write byte 1, wavHeader(x)
next x
write long 1, chunk2
for x=8 to 39
` read byte2
write byte 1, wavHeader(x)
next x
write long 1,chunk ` this completes the header info
` write wave data
for x=1 to samples
write word 1,memblock word(1,26+x*2)
next x
close file 1
` load sound name$+".wav",soundnumber
delete memblock 1
endfunction