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