Item Of the Day. Playing .net io.stream using FMOD

So lets say you want to connect to a website to stream their music through your app, but the problem is they dont give you a direct link only a connectstream from system.net.connectstream. How do you play this with fmod? well after much trial and error and understanding the concept i have found the solution.

Im assuming you already know how to setup FMOD so i wont go through that.

1) you will get your stream and you must know the length. You will have to rely on the content length send over the http stream since you cant get the length of a io.stream when using http.

2) This is the fun part. You will need to take that stream and load it into a byte array. If you want your data in real time and dont want to load the entire buffer(dowload the entire file) you will need to load the data in a thread. Then you will need to trigger for the orginal thread to continue once the initial buffer length of the data has been loaded into the new byte array.

3) once theĀ initialĀ data has been loaded into the byte array just pass that byte data to FMOD createStream function then OPENMEMORY Flag and also create a CREATESOUNDEXINFO and pass those items in and then play your sound. The thread will still be loading the data in the background while the app is playing the sound or music.

There is some extra code in SaveMemTask that gets the pointer to the mem but it is not needed since that approach didnt work too good for me.

Check out the code below.

 Sub PlaySong(ByRef songStream As System.IO.Stream, ByVal streamLength As UInt32, ByVal stitle As String)

        Dim result As FMOD.RESULT
        If channel IsNot Nothing Then channel.stop()
        If sound IsNot Nothing Then sound.release()

        Dim sinfo As New FMOD.CREATESOUNDEXINFO
        sinfo.cbsize = Runtime.InteropServices.Marshal.SizeOf(sinfo)
        sinfo.length = streamLength
        sinfo.format = FMOD.SOUND_FORMAT.MPEG

        Dim streamptr As IntPtr = StreamToByteArray(songStream, streamLength)

        result = sys.createStream(rawData, (FMOD.MODE._2D Or FMOD.MODE.HARDWARE Or FMOD.MODE.CREATESTREAM Or FMOD.MODE.OPENMEMORY), sinfo, sound)

        result = sys.playSound(FMOD.CHANNELINDEX.FREE, sound, False, channel)
End Sub
Protected Function StreamToByteArray(ByRef songstream As IO.Stream, ByVal streamLength As UInt32) As IntPtr
        WaitForThread = True
        Me.streamLength = streamLength
        AddHandler InitDataRecived, AddressOf InitDataReceivedHandler

        trd = New System.Threading.Thread(AddressOf SaveMemTask)
        trd.IsBackground = True
        Me.songstream = songstream
        Me.saveTo = saveTo
        trd.Start()

        While WaitForThread = True
            Threading.Thread.Sleep(100)
        End While

        Return MyStreamPtr
    End Function
 'Global Variables     Protected rawData() As Byte
    Dim streamLength As UInt32
    Private Sub SaveMemTask()

        ReDim rawData(streamLength)
        Dim ran As Boolean = False
        Dim sLength As Integer = 1024
        Dim buffer(sLength) As Byte
        Dim bytesRead As Integer = songstream.Read(Buffer, 0, sLength)
        Dim bpos As Integer = 0

        While (bytesRead > 0)

            For i As Integer = 0 To bytesRead - 1
                rawData(i + bpos) = buffer(i)
            Next

            bpos += bytesRead
            If ran = False Then
                ran = True
                rawDataHandle = GCHandle.Alloc(rawData, GCHandleType.Pinned)
                address = rawDataHandle.AddrOfPinnedObject()
                RaiseEvent InitDataRecived(address)
            Else

            End If

            bytesRead = songstream.Read(Buffer, 0, sLength)
        End While

    End Sub
    Private Sub InitDataReceivedHandler(ByVal ptr As IntPtr)
        MyStreamPtr = ptr
        WaitForThread = False
    End Sub
    Private songstream As IO.Stream
    Private saveTo As String
    Private WaitForThread As Boolean = True
    Private MyStreamPtr As IntPtr
    Protected Event InitDataRecived(ByVal ptr As IntPtr)
This entry was posted in Uncategorized and tagged , , , , , , . Bookmark the permalink.

16 Responses to Item Of the Day. Playing .net io.stream using FMOD

Leave a Reply

Your email address will not be published.