[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