|
Post by Rod on Apr 8, 2018 19:34:43 GMT
When I asked for contributions to the Compendium thread I was really impressed by the sounds that were created on the fly with Blokola.
So I thought why not challenge folks to make more noise. A synthesiser would be fantastic, a beep would be fine.
I have in my mind .wav creation but .mid can produce great sounds too. BBC Basic had a sound envelope/tone generator or how about an on screen envelope shaper, attack, decay, sustain etc.
Participation makes this forum, don't matter how small how lame the fact you had a go is all we need to see. Of course the gurus like AltBas and UncleBen and Bplus have this challenge beat hands down. he he he he.......
|
|
|
Post by Rod on Apr 10, 2018 10:56:51 GMT
Just to show a little of what I mean, here is a tone generator, it creates a .wav file then plays it. It can only merger two frequencies to create differing tones and only shows a tiny part of the .wav file. What the make a noise project is all about is adding volume envelopes and frequency envelopes and mixing white noise and tones together. So what is the first part to tackle? White noise? Volume envelope? It would need an array of sliders to shape the envelope would it not? Or is there a better way to graphically shape an envelope?
Lets assume we stick with 0-255 as the volume limits.
'This program lets you create little sound samples
'It uses 11025 samples per second, 8 bits per sample
'and mono sound.
'One second of sound will use 11025 bytes, each
'byte represents the volume of the sound at any
'point in time. (0-255) The changing volume creates
'the frequency of the sound you hear.
'The sound can be left pure or modulated by another
'tone
'program variables
true=1
false=0
dim hz$(12)
dim mhz$(12)
hz$(0)="55.000(A)"
hz$(1)="58.270(A#)"
hz$(2)="61.735(B)"
hz$(3)="65.406(C)"
hz$(4)="69.296(C#)"
hz$(5)="73.416(D)"
hz$(6)="77.782(D#)"
hz$(7)="82.407(E)"
hz$(8)="87.307(F)"
hz$(9)="92.499(F#)"
hz$(10)="97.999(G)"
hz$(11)="103.826(G#)"
hz$(12)="110.000(A)"
mhz$(0)="130.813(C)"
mhz$(1)="261.626(C)"
mhz$(2)="523.251(C)"
mhz$(3)="1046.502(C)"
wv$(0)="Sine"
wv$(1)="Square"
wv$(2)="Saw Tooth"
wv$(3)="Triangular"
mwv$(0)="Sine"
mwv$(4)="None"
vo$(0)="10%"
vo$(1)="20%"
vo$(2)="30%"
vo$(3)="40%"
vo$(4)="50%"
vo$(5)="60%"
vo$(6)="70%"
vo$(7)="80%"
vo$(8)="90%"
vo$(9)="100%"
mvo$(0)="10%"
mvo$(1)="20%"
mvo$(2)="30%"
mvo$(3)="40%"
mvo$(4)="50%"
mvo$(5)="60%"
mvo$(6)="70%"
mvo$(7)="80%"
mvo$(8)="90%"
mvo$(9)="100%"
du$(0)="100ms"
du$(1)="500ms"
du$(2)="1000ms"
du$(3)="5000ms"
'open our window
nomainwin
WindowWidth = 600
WindowHeight = 500
UpperLeftX = int((DisplayWidth-WindowWidth)/2)
UpperLeftY = int((DisplayHeight-WindowHeight)/2)
graphicbox #scope.graph, 50, 20, 500, 300
statictext #scope.hz, "Hertz" ,125, 360,80,20
combobox #scope.hz, hz$(),[hertz],125,380,80,20
combobox #scope.mhz,mhz$(),[mhertz],125,420,80,20
statictext #scope.wv, "Wave Form" ,225, 360,80,20
combobox #scope.wv, wv$(),[wave],225,380,80,20
combobox #scope.mwv,mwv$(),[mwave],225,420,80,20
statictext #scope.vo, "Volume" ,325, 360,80,20
combobox #scope.vo, vo$(),[volume],325,380,80,20
combobox #scope.mvo,mvo$(),[modvol],325,420,80,20
statictext #scope.du, "Duration" ,420, 360,80,20
combobox #scope.du, du$(),[duration],420,380,80,20
button #scope.save, "Save",[save],UL,125,325
button #scope.play, "Play",[play],UL,225,325
button #scope.loop, "Loop",[repeat],UL,325,325
button #scope.stop, "Stop",[stop],UL,425,325
open "Tone Generator" for window_nf as #scope
'draw the scope background and flush it
print #scope, "trapclose [quit]"
print #scope.graph, "down"
for y= 300 to 0 step -2
print #scope.graph, "color ";y/2+100;" ";y/2+100;" ";y/2+100
print #scope.graph, "line 0 ";y;" ";"500 ";y
print #scope.graph, "line 0 ";y-1;" ";"500 ";y-1
next y
print #scope.graph, "color yellow"
print #scope.graph, "line 0 150 500 150"
print #scope.graph, "flush"
'set the initial combobox data
print #scope.hz, "select 55.000(A)"
hertz=55
print #scope.wv, "select Sine"
wave$="Sine"
print #scope.vo, "select 100%"
volume=1
print #scope.du, "select 1000ms"
duration=1
print #scope.mhz, "select 261.626(C)"
mhertz=261.626
print #scope.mwv, "select Sine"
mwave$="Sine"
print #scope.mvo, "select 10%"
modvol=.1
gosub [chart]
'now wait for user input
wait
' button and combobox handlers
[hertz]
print #scope.hz, "contents? text$"
hertz=val(text$)
gosub [chart]
wait
[mhertz]
print #scope.mhz, "contents? text$"
mhertz=val(text$)
gosub [chart]
wait
[wave]
print #scope.wv, "contents? wave$"
gosub [chart]
wait
[mwave]
print #scope.mwv, "contents? mwave$"
gosub [chart]
wait
[volume]
print #scope.vo, "contents? text$"
volume=val(text$)/100
gosub [chart]
wait
[modvol]
print #scope.mvo, "contents? text$"
modvol=val(text$)/100
gosub [chart]
wait
[duration]
print #scope.du, "contents? text$"
duration=val(text$)/1000
gosub [chart]
wait
[stop]
playwave ""
repeat=false
wait
[save]
filedialog "Save As...", "*.wav", fileName$
open fileName$ for output as #t
print #t, header$
print #t, tone$
close #t
wait
[repeat]
repeat=true
' now drop down to [play]
[play]
'create the .wav file header
samplesPerSecond=11025
channels=1 'mono
bitsPerSample=8
blockAlign=(bitsPerSample*channels)/8
bytesPerSecond=blockAlign*samplesPerSecond
'this is the only element that changes in the header
'normally dataSize=bytesPerSecond*duration
dataSize=len(tone$)
waveSize=dataSize+36
header$=""
header$=header$+"RIFF"
number=waveSize
byte4=int(number/16777216)
number=number-(byte4*16777216)
byte3=int(number/65536)
number=number-(byte3*65536)
byte2=int(number/256)
byte1=number-(byte2*256)
header$=header$+chr$(byte1)+chr$(byte2)+chr$(byte3)+chr$(byte4) ' lof -8
header$=header$+"WAVE"
header$=header$+"fmt "
header$=header$+chr$(16)+chr$(0)+chr$(0)+chr$(0) ' fmt chunk length 16 bytes
header$=header$+chr$(1)+chr$(0) ' pcm
header$=header$+chr$(channels)+chr$(0) ' 1 = mono
number=samplesPerSecond
byte4=int(number/16777216)
number=number-(byte4*16777216)
byte3=int(number/65536)
number=number-(byte3*65536)
byte2=int(number/256)
byte1=number-(byte2*256)
header$=header$+chr$(byte1)+chr$(byte2)+chr$(byte3)+chr$(byte4) ' samples per second
number=bytesPerSecond
byte4=int(number/16777216)
number=number-(byte4*16777216)
byte3=int(number/65536)
number=number-(byte3*65536)
byte2=int(number/256)
byte1=number-(byte2*256)
header$=header$+chr$(byte1)+chr$(byte2)+chr$(byte3)+chr$(byte4) ' bytes per second
number=blockAlign
byte2=int(number/256)
byte1=number-(byte2*256)
header$=header$+chr$(byte1)+chr$(byte2) ' block align
number=bitsPerSample
byte2=int(number/256)
byte1=number-(byte2*256)
header$=header$+chr$(byte1)+chr$(byte2) ' bits per sample
header$=header$+"data"
number=dataSize
byte4=int(number/16777216)
number=number-(byte4*16777216)
byte3=int(number/65536)
number=number-(byte3*65536)
byte2=int(number/256)
byte1=number-(byte2*256)
header$=header$+chr$(byte1)+chr$(byte2)+chr$(byte3)+chr$(byte4) ' number of data bytes
open "tone.wav" for output as #tone
print #tone, header$
print #tone, tone$
close #tone
if repeat then
playwave "tone.wav", loop
else
playwave "tone.wav"
end if
wait
[chart]
samplesPerSecond=11025
channels=1 'mono
bitsPerSample=8
blockAlign=(bitsPerSample*channels)/8
bytesPerSecond=blockAlign*samplesPerSecond
dataSize=bytesPerSecond*duration
[createwavedata]
tone$=""
select case wave$
case "Sine"
tone$=""
degree=0
increment=360/(samplesPerSecond/hertz)
for byte = 1 to dataSize
degree=degree+increment
if degree>359 then degree=0
ypos=(sin(degree/57.29577951)*128*volume)+128
t=int(ypos)
tone$=tone$+chr$(t)
next
case "Square"
period=samplesPerSecond/hertz/2
counter=0
high=true
for byte= 1 to dataSize
if high then
ypos=128+(128*volume)
counter=counter+1
if counter>=period then
high=false
counter=0
end if
else
ypos=128-(128*volume)
counter=counter+1
if counter>=period then
high=true
counter=0
end if
end if
t=int(ypos)
if t<0 then t=0
if t>255 then t=255
tone$=tone$+chr$(t)
next
case "Saw Tooth"
period=samplesPerSecond/hertz
increment=(256*volume)/period
counter=0
ypos=128+128*volume
for byte= 1 to dataSize
if counter>=period then
ypos=128+128*volume
counter=0
end if
ypos=ypos-increment
counter = counter +1
t=int(ypos)
if t<0 then t=0
if t>255 then t=255
tone$=tone$+chr$(t)
next
case "Triangular"
period=samplesPerSecond/hertz/2
increment=(256*volume)/period
counter=0
ypos=128+128*volume
high=true
for byte= 1 to dataSize
if high then
ypos=ypos-increment
counter=counter+1
if counter>=period then
high=false
counter=0
end if
else
ypos=ypos+increment
counter=counter+1
if counter>=period then
high=true
counter=0
end if
end if
t=int(ypos)
if t<0 then t=0
if t>255 then t=255
tone$=tone$+chr$(t)
next
end select
[modulatewavedata]
temp$=tone$
tone$=""
select case mwave$
case "Sine"
degree=0
increment=360/(samplesPerSecond/mhertz)
for byte = 1 to dataSize
degree=degree+increment
if degree>359 then degree=0
ypos=(sin(degree/57.29577951)*128*modvol)+128
t=int(ypos)
t=t+asc(mid$(temp$,byte,1))-128
if t<0 then t=0
if t>255 then t=255
tone$=tone$+chr$(t)
next
case "None"
tone$=temp$
temp$=""
end select
'graph the first 500 values from the file
xpos=0
ypos=150
print #scope.graph, "discard ; redraw ; place 0 150"
for byte = 1 to 500
ypos=asc(mid$(tone$,byte,1))+22
print #scope.graph, "color red ;goto ";xpos;" ";ypos
xpos=xpos+1
next
wait
[quit]
close #scope
end
' frequency chart of the musical scale
'0 A 55.000 110.000 220.000 440.000 880.000 1,760.000
'1 A#/Bb 58.270 116.541 233.082 466.164 932.328 1,864.655
'2 B 61.735 123.471 246.942 493.883 987.767 1,975.533
'3 C 65.406 130.813 261.626 523.251 1,046.502 2,093.005
'4 C#/Db 69.296 138.591 277.183 554.365 1,108.731 2,217.461
'5 D 73.416 146.832 293.665 587.330 1,174.659 2,349.318
'6 D#/Eb 77.782 155.563 311.127 622.254 1,244.508 2,489.016
'7 E 82.407 164.814 329.628 659.255 1,318.510 2,637.020
'8 F 87.307 174.614 349.228 698.456 1,396.913 2,793.826
'9 F#/Gb 92.499 184.997 369.994 739.989 1,479.978 2,959.955
'10 G 97.999 195.998 391.995 783.991 1,567.982 3,135.963
'11 G#/Ab 103.826 207.652 415.305 830.609 1,661.219 3,322.438
'12 A 110.000 220.000 440.000 880.000 1,760.000 3,520.000
|
|
|
Post by B+ on Apr 10, 2018 14:28:55 GMT
Hi Rod, First I'd like to set record straight, I am no guru when it comes to sound. Second, I have played with this app either at old JB site or (probably) in another BASIC version because I remember creating a file for a sound effect. I think it was for an air pump for an aquarium scene. Another big thumbs up for reposting this but I suggest redo it under the "BBCode" tab (below in the editor window, instead of the Preview tab next to it) to get rid of the double spacing. Append: I added a screen shot to my tip for avoiding Double Spacing in a Code Block: justbasiccom.proboards.com/thread/10/tip-posting-code-proboards-forum
|
|
code
Member in Training
Posts: 74
|
Post by code on Apr 10, 2018 14:40:08 GMT
Great program... it works well when copied totally !
|
|
|
Post by Rod on Apr 10, 2018 18:55:20 GMT
Learning, learning, we just got the code box fixed to preserve the indentation so remembering to click out of preview is a fantastic tip. Thanks B+ BPlus . Mark
|
|