Read Audio Input from STDOUT

BlitzMax Forums/BlitzMax Programming/Read Audio Input from STDOUT

Lomat(Posted 2007) [#1]
I'm trying to find a way to read audio information from an external application via STDOUT. I'm currently using the AXE.Portaudio module but I cant seem to get it to work, all I get is a hissing noise :(

Below is a small example that I am currently trying to get working. It simply spawns a process (mov123), reads the audio data via STDOUT (44.1k 16bit) and then passes this information to the Portaudio functionality.

I would appreciate any feedback or suggestion as to how i can get the required functionality.

SuperStrict

Framework BRL.Basic

Import AXE.Portaudio
Import BRL.Map
Import PUB.FreeProcess

Type AudioProcessManager

	Global map:TMap  = New TMap
	Global init:Byte  = 0
	
	Function CreateProcess:AudioProcess(command:String)
		If init = 0 Then
			Pa_Initialize()
			init = 1
		End If
		Local ap:AudioProcess = New AudioProcess
		map.Insert(String(ap.id), ap)
		ap.command = command
		Return ap
	End Function

	Function ReleaseProcess(ap:AudioProcess)
		map.Remove(String(ap.id))
	End Function
	
	Function AudioCallback:Int( inputBuffer:Byte Ptr, outputBuffer:Byte Ptr, framesPerBuffer:Int, outTime:Double, userData:Byte Ptr)
		Local ap:AudioProcess = AudioProcess(map.ValueForKey(String(userData[0])))
		If Not ap Or Not ap.process Then
			Return 0
		End If
		If ap.process.pipe.ReadAvail() >= framesPerBuffer Then
			ap.process.pipe.Read(outputbuffer, framesPerBuffer)
		End If
		Return 0
	End Function

End Type

Type AudioProcess

	Global nextId:Int = 0

	Field id:Int
	Field command:String
	Field process:TProcess
	
	Field stream:Byte Ptr
		
	Method New()
		id = nextId
		nextId:+1
	End Method
	
	Method play()
		If process Then
			stop()
		End If
		process = TProcess.Create(command, 0)
		Pa_Initialize()
		error(Pa_OpenStream( ..
			Varptr stream, ..
			PANODEVICE, ..
			0, ..
			2, ..
			Null, ..
			Pa_GetDefaultOutputDeviceID(), ..
			2, ..
			1, ..
			Null, ..
			44100, ..
			256, ..
			0, ..
			0, ..
			AudioProcessManager.AudioCallback, ..
			Varptr id ..
		), "open stream")
		error(Pa_StartStream( stream ), "start stream")
	End Method
		
	Method stop()
		If Not process Then
			Return
		End If
		Pa_CloseStream(stream)
		process.Terminate()
		process.Close()
		process = Null
	End Method
	
	Method isPlaying:Int()
		If process And process.Status() <> 0 Then
			Return True
		End If
		Return False
	End Method
	
	Method error(e:Int,s:String)
		If e=0 Then Return
		Pa_Terminate()
		Print "error "+e+" in "+s
		Print "message "+String.FromCString(Pa_GetErrorText(e))
		End
	End Method	
		
End Type

Local cmd:String = "c:\mov123.exe ~qc:\test.mp3~q"
Local ap:AudioProcess = AudioProcessManager.CreateProcess(cmd)
Print ap.command
ap.play()
While ap.IsPlaying()
	Delay(10000)
Wend
Print "End."