Any sound (wav) experts?

BlitzPlus Forums/BlitzPlus Beginners Area/Any sound (wav) experts?

ThePict(Posted 2013) [#1]
I've been trying to make a Text-to-Morse function which I'll use in my game.
There is one in the Code Archives, but it uses the old SystemBeep() which no longer exists. I did some research into the makeup of a wav file
ccrma.stanford.edu/courses/422/projects/WaveFormat/

and I wrote this code
Graphics 800,400,16,2


myword$="Gordon"
mymorse$=MakeMorseString$(myword$)
Text 0,40,mymorse$
SaveMorseWav(myword$+".wav",mymorse$)
Delay 1000
PlayMusic(myword$+".wav")


FlushKeys
WaitKey()
End
.wavvals
;Header data for the wav
Data 82,73,70,70,0,0,0,0,87,65,86,69,102,109,116,32,16,0,0,0,1,0,2,0,34,86,0,0,68,172,0,0,4,0,16,0,100,97,116,97,0,0,0,0

Function SaveMorseWav(file$,morse$)
ds=0;number of bytes for the sample
For n=1 To Len(morse$)
If Mid$(morse$,n,1)=" " Then ds=ds+2200
If Mid$(morse$,n,1)="." Then ds=ds+2200
If Mid$(morse$,n,1)="-" Then ds=ds+6600
Next
ds=ds+44;plus the header
mybank=CreateBank(ds)
Restore wavvals
For n=0 To 43
Read byte
PokeByte(mybank,n,byte)
Next
;Now insert the sample file size back into the header
PokeByte(mybank,4,(ds-8) Mod 65536)
PokeByte(mybank,6,Int((ds-8)/65536))
PokeByte(mybank,40,(ds-44) Mod 65536)
PokeByte(mybank,42,Int((ds-44)/65536))
ang#=0:off=46
For n=1 To Len(morse$)
	If Mid$(morse$,n,1)=" " Then 
	For m=0 To 2198 Step 2
	PokeByte(mybank,off+m,0)
	PokeByte(mybank,off+m+1,0)
	
	Next
	off=off+2200
	End If	
		If Mid$(morse$,n,1)="." Then 
		For m=0 To 2198 Step 2
		PokeByte(mybank,off+m,65536*Sin(ang Mod 360))
		PokeByte(mybank,off+m+1,65536*Sin(ang Mod 360))
		ang#=ang#+2;Using 2 here as an arbitrary frequency (it'll make it approx 1400Hz I think)
		Next
		off=off+2200
		End If
			If Mid$(morse$,n,1)="-" Then 
			For m=0 To 6598 Step 2
			PokeByte(mybank,off+m,65536*Sin(ang Mod 360))
			PokeByte(mybank,off+m+1,65536*Sin(ang Mod 360))
			ang#=ang#+2;Using 2 here as an arbitrary frequency (it'll make it approx 1400Hz I think)
			Next
			off=off+6600
			End If
Next
mf=WriteFile(file$)
For n=0 To BankSize(mybank)
WriteByte(mf,PeekByte(mybank,n))
Next
CloseFile mf
End Function


Function MakeMorseString$(word$)
dots$=" "
For n=1 To Len(word$)
Select Upper(Mid$(word$,n,1))
Case "A": dots$=dots$+".- "
Case "B": dots$=dots$+"-... "
Case "C": dots$=dots$+"-.-. "
Case "D": dots$=dots$+"-.. "
Case "E": dots$=dots$+". "
Case "F": dots$=dots$+"..-. "
Case "G": dots$=dots$+"--. "
Case "H": dots$=dots$+".... "
Case "I": dots$=dots$+".. "
Case "J": dots$=dots$+".--- "
Case "K": dots$=dots$+"-.- "
Case "L": dots$=dots$+".-.. "
Case "M": dots$=dots$+"-- "
Case "N": dots$=dots$+"-. "
Case "O": dots$=dots$+"--- "
Case "P": dots$=dots$+".--. "
Case "Q": dots$=dots$+"--.- "
Case "R": dots$=dots$+".-. "
Case "S": dots$=dots$+"... "
Case "T": dots$=dots$+"- "
Case "U": dots$=dots$+"..- "
Case "V": dots$=dots$+"...- "
Case "W": dots$=dots$+".-- "
Case "X": dots$=dots$+"-..- "
Case "Y": dots$=dots$+"-.-- "
Case "Z": dots$=dots$+"--.. "
End Select
Next
Return dots$
End Function


But it doesn't quite seem to work...
0530 in the morning and I'm all out of neurons.


Midimaster(Posted 2013) [#2]
I would work with two single sound for all characters: a long one and a short one.

You can create both with my GS-TO-AUDIO tool. Select one of the sythy sounds (f.e. "Synth Lead"), select "Start Note" of 50 and a "End Note" of 80 to have a selection of frequencies. Adjust a length (Sample Länge) of 450msec. Now "Save" the result. The tool will produce *.ogg files of these instrument. In a folder you will later find 30 sound of different frequency.

Tool:
http://www.blitzmax.com/toolbox/toolbox.php?tool=264

Choose the frequency you like and copy this sound to your game folder. Now repeat the tool, but with a length (Sample Länge) of 150msec

In your game you load this two sounds. You need a function to differ long from short signal:

Scan the character. If "long" is necessary: Play sound 1 and wait 600msec, if "short" play sound 2 and wait 300 msec. If the signals for one character are done add another 450msec to the waiting . If a word ends wait another 600msec.

this is more a symbolic code:
Global SignalTimer%

Dots$=".-- - .-.- .- .-. .... -- -- .-.- "

Repeat
	If NextSignal(Signal)=True
			Signal= Left(Dots,1)
			Dots=Mid(Dots,2,99)
	EndIf 
Until KeyHit(1)



Function NextSignal%(Sign$)
	; function waits until previous sound has finished, then send a new sound

	If SignalTimer>MilliSecs() Return False   ; still have to wait

	Select Sign
		Case "-"
			PlaySound Signal1
			SignalTimer=MilliSecs()+600
		Case "."
			PlaySound Signal2
			SignalTimer=MilliSecs()+300
		Case " "
			SignalTimer=MilliSecs()+450 ; pause between characters 	

	End Select
	Return True  ; next character please
End Function 



ThePict(Posted 2013) [#3]
Nice!
Will try this out later. Many thanks.


ThePict(Posted 2013) [#4]
Got it working eventually, but couldn't get Midimaster's tool to work on my old computer. Found a website that produces continuous tone at a given freq for 10 secs and lets you download the wav. My research into the make up fo wavs allowed me to trim them down to 150ms and 300ms as required.
Midimaster's code was useful for the function I ended up using in my code. Thanks again.