GNet Voip
BlitzMax Forums/BlitzMax Programming/GNet Voip
| ||
Found this mic recording code from forums and i am curious how can i send sound data over gnet networking? Is it possible?
SuperStrict
' from <a href="http://code.google.com/p/Max-edit/source/browse/#svn/trunk/Mod/axe.Mod/oggsaver.mod" target="_blank">http://code.google.com/p/Max-edit/source/browse/#svn/trunk/Mod/axe.Mod/oggsaver.mod</a>
'Import axe.oggsaver '<---- this is ok!
EnableOpenALAudio()
SetAudioDriver("OpenAL")
Graphics 500,30,0
' create the openal sampler
Local Sampler:TOpenALSampler = TOpenALSampler.Create(44100,SF_STEREO16LE)
Local AudioSample:TAudioSample
Local Sound:TSound
Local Channel:TChannel
Local mode:Int
Repeat
Cls
Select mode
Case 0 ' idle, wait to start recording
DrawText("Idle... Press SPACE to start recording",10,10)
If KeyHit(KEY_SPACE)
Sampler.Start
Mode:+1
EndIf
Case 1 ' record
DrawText("Recording..."+Sampler.Size+" bytes - Press SPACE to stop",10,10)
If KeyHit(KEY_SPACE)
AudioSample = Sampler.Stop()
' if you have axe.oggsaver
'SaveOGG(AudioSample,AppDir + "/recorded.ogg")
Mode:+1
EndIf
Case 2 ' idle, wait to playback recorded sound
DrawText("Recorded "+AudioSample.length + " samples - Press SPACE to start playback",10,10)
If KeyHit(KEY_SPACE)
Sound = LoadSound(AudioSample)
Channel = PlaySound(sound)
Mode:+1
EndIf
Case 3 ' playing
DrawText("Playing... Press SPACE to stop playback",10,10)
If ChannelPlaying(Channel)=False Or KeyHit(KEY_SPACE)
StopChannel(Channel)
Mode=0
EndIf
EndSelect
Flip
Until AppTerminate() Or KeyHit(KEY_ESCAPE)
' ---------------------------------------------------------------------------------
' the sampler!
Type TOpenALSampler
Field ChunkList:TList = New TList
Field recordedsamplelength:Int
Field DefaultSpecifier:String
Field CaptureDevice:Int
Field oalFormat:Int
Field Format:Int
Field Hertz:Int
Field Timer:TTimer
Field Size:Int
' create a recorder
Function Create:TOpenALSampler(Hertz:Int=44100,Format:Int=SF_STEREO16LE)
Local This:TOpenALSampler = New TOpenALSampler
This.DefaultSpecifier = String.FromCString(alcGetString(Null, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)) ; This.OpenALError
This.Hertz = Hertz
This.Format = Format
Select format
Case SF_MONO8 ; This.oalFormat = AL_FORMAT_MONO8
Case SF_MONO16LE ; This.oalFormat = AL_FORMAT_MONO16
Case SF_MONO16BE ; This.oalFormat = AL_FORMAT_MONO16
Case SF_STEREO8 ; This.oalFormat = AL_FORMAT_STEREO8
Case SF_STEREO16LE ; This.oalFormat = AL_FORMAT_STEREO16
Case SF_STEREO16BE ; This.oalFormat = AL_FORMAT_STEREO16
EndSelect
This.CaptureDevice = alcCaptureOpenDevice(This.DefaultSpecifier,Hertz,This.oalFormat,44100*16) ; This.OpenALError
Return This
EndFunction
' start recording
Method Start()
If Timer Return
Timer = CreateTimer(60)
AddHook EmitEventHook,eventhook,Self
alcCaptureStart(CaptureDevice) ; OpenALError
EndMethod
' stop recording and return a TAudioSample
Method Stop:TAudioSample()
StopTimer Timer ; Timer = Null
RemoveHook EmitEventHook,eventhook,Self
alcCaptureStop(CaptureDevice) ; OpenALError
' REMMED OUT because captures would get to long 'CaptureAudioChunk ' flush remaining audio
Local samplesbank:TBank
Local AudioSample:TAudioSample = CreateAudioSample((size/BytesPerSample[format]),hertz,format)
Local bptr:Byte Ptr = AudioSample.samples
'ChunkList.removelast()
For samplesbank=EachIn ChunkList
MemCopy(bptr,BankBuf(samplesbank),BankSize(samplesbank))
bptr:+BankSize(samplesbank)
Next
ClearList(ChunkList)
Size=0
Return AudioSample
EndMethod
Function eventhook:Object(id:Int,data:Object,context:Object)
Local Sampler:TOpenALSampler = TOpenALSampler(context)
If Sampler
Local event:TEvent = TEvent(data)
If Event.ID=EVENT_TIMERTICK And Event.Source=Sampler.Timer
Sampler.CaptureAudioChunk
EndIf
EndIf
Return data
EndFunction
Method CaptureAudioChunk()
Local recordedsamplelength:Int
alcGetIntegerv(CaptureDevice,ALC_CAPTURE_SAMPLES,4,Varptr recordedsamplelength) ; OpenALError
If recordedsamplelength
Local samplesbank:TBank = CreateBank(recordedsamplelength*BytesPerSample[format])
alcCaptureSamples(CaptureDevice,BankBuf(samplesbank),recordedsamplelength) ; OpenALError
ListAddLast(ChunkList,samplesbank)
Size:+BankSize(samplesbank)
EndIf
EndMethod
Method OpenALError()
Local result:Int = alcGetError(CaptureDevice)
If result<>0 RuntimeError "Sampler OpenAL Error Code = "+result
EndMethod
EndType |
| ||
| Dunno if it works with "gnet" (or if you need to directly send via "enet"). Idea is the following: Save the microphone record into a databuffer (eg. X kilobytes long, then move along an "position" number). With gnet/enet/... you send portions of this databuffer to others (as soon as filled data length > your desired "packet" size). On the remote side you fill again this "record databuffer" (maybe call it remoteRecordDatabuffer). As soon as enough data is buffered you can start playing. If one of the both connection sides does not send enough data - or does receive enough data you should stop playing the sound back (to avoid garbage sound output). buffer length depends on sound quality (higher quality = less "speaking duration" in the same buffer). bye Ron |