[Speex-dev] Speex in VB .NET

Martin Wheller martinwheller at hotmail.com
Wed Jul 30 13:19:33 PDT 2008


Hi there,
I have searched what seems like everywhere and was unable to find a .NET wrapper so that I can use speex in VB. I did find a speex.NET.dll but this didn't seem to work on what I needed.
 
I therefore decided I could just use DllImport within VB .NET and create my own unmanaged links to libspeex.dll.
 
With the help of this partial c# code (http://lists.xiph.org/pipermail/speex-dev/2007-February/005307.html) I created this VB.net class:
 
(I have focused on the decode side of things to start with, until I have it working).
 
Imports SystemImports System.Runtime.InteropServicesImports System.IO
 
Namespace Speex    '''<summary>    '''the following class is the win32 SPEEX API that retrieve     '''methods and structures from the libspeex file     '''</summary> 
 
    Public Class Speex_win32
 
#Region "Speex Constants"
 
        'global speex file that contains the api(s) 
 
        Public Const libpath As String = "libspeex.dll"        Public Const Frame_Size As Integer = 160        Public Const Max_Frame_Size As Integer = 2000        Public Const Speex_Get_Frame_Size As Integer = 3        Public Const Speex_Set_Quality As Integer = 4        Public Const Speex_nb_Mode As Integer = 3
 
        'create the structure that will hold the speexbits         <StructLayout(LayoutKind.Sequential)> _        Public Structure SpeexBits            Public chars As IntPtr            ' "raw" data             Public nbBits As Integer            ' Total number of bits stored in thestream             Public charPtr As Integer            ' Position of the byte "cursor"             Public bitPtr As Integer            ' Position of the bit "cursor" within thecurrent char             Public owner As Integer            ' Does the struct "own" the "raw" buffer(member "chars")             Public overflow As Integer            ' Set to one if we try to read past thevalid data             Public buf_size As Integer            ' Allocated size for buffer             Public reserved1 As Integer            ' Reserved for future use             Public reserved2 As IntPtr            ' Reserved for future use 
 
        End Structure        Public Structure SpeexMode            Public mode As IntPtr            Public query As IntPtr            Public modeName As String            Public modeID As Integer            Public bitstream_version As Integer            Public enc_init As IntPtr            Public enc_destroy As IntPtr            Public enc As IntPtr            Public dec_init As IntPtr            Public dec_destroy As IntPtr            Public dec As IntPtr            Public enc_ctl As IntPtr            Public dec_ctl As IntPtr        End Structure
#End Region
 
#Region "Exported Methods"        <DllImport(libpath)> _        Public Shared Sub speex_bits_init(ByRef bits As SpeexBits)        End Sub        <DllImport(libpath)> _        Public Shared Function speex_decoder_init(ByRef mode As SpeexMode) As IntPtr        End Function        <DllImport(libpath)> _        Public Shared Function speex_bits_remaining(ByRef bits As SpeexBits) As Integer        End Function        <DllImport(libpath)> _        Public Shared Sub speex_bits_destroy(ByRef bits As SpeexBits)        End Sub        <DllImport(libpath)> _        Public Shared Sub speex_bits_read_from(ByRef bits As SpeexBits, ByVal bytes() As Char, ByVal len As Integer)        End Sub        <DllImport(libpath)> _        Public Shared Function speex_decode(ByVal state As IntPtr, ByRef bits As SpeexBits, ByVal outt As Single()) As Integer        End Function
        <DllImport(libpath)> _        Public Shared Sub speex_decoder_destroy(ByRef state As IntPtr)        End Sub
        <DllImport(libpath)> _        Public Shared Function speex_lib_get_mode(ByVal mode As Integer) As IntPtr        End Function
        <DllImport(libpath)> _        Public Shared Function speex_decoder_ctl(ByVal state As IntPtr, ByVal request As Integer, ByRef ptr As Integer) As Integer        End Function
        <DllImport(libpath)> _        Public Shared Function speex_decode_int(ByVal state As IntPtr, ByRef bits As SpeexBits, ByVal outt() As Single) As Integer        End Function
 
#End Region
 
    End Class
 
End Namespace
 
 
With this code I am now able to init the decoder as follows:
 

        Dim speex_decoder_state As IntPtr        Dim mode As Speex.Speex_win32.SpeexMode = DirectCast(Marshal.PtrToStructure(Speex.Speex_win32.speex_lib_get_mode(0), GetType(Speex.Speex_win32.SpeexMode)), Speex.Speex_win32.SpeexMode)
        speex_decoder_state = Speex.Speex_win32.speex_decoder_init(mode)
and then I can do the following:
 
        Dim bits As New Speex.Speex_win32.SpeexBits        Speex.Speex_win32.speex_bits_init(bits)
 
        Speex.Speex_win32.speex_bits_read_from(bits, data, len)        MsgBox(Speex.Speex_win32.speex_bits_remaining(bits)) 'This correctly shows that the bits have been entered correctly, as it shows a number > 0
        Dim output(160-1) As Single
        Dim tmpval As Integer = Speex.Speex_win32.speex_decode(speex_decoder_state, bits, output)
 
Then at this point I get a System.AccessViolationException error. "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
 
Does anybody have any ideas why this error occurs, or if there are any existing wrappers for .NET? Has anyone got speex working in .NET?
 
Cheers,
Martin
_________________________________________________________________
Play and win great prizes with Live Search and Kung Fu Panda
http://clk.atdmt.com/UKM/go/101719966/direct/01/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.xiph.org/pipermail/speex-dev/attachments/20080730/ed939cb0/attachment.htm 


More information about the Speex-dev mailing list