<html>
<head>
<style>
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
FONT-SIZE: 10pt;
FONT-FAMILY:Tahoma
}
</style>
</head>
<body class='hmmessage'><DIV><FONT face=Arial size=2>Hi there,</FONT></DIV>
<DIV><FONT face=Arial size=2>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.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>I therefore decided I could just use </FONT><FONT face=Arial size=2><FONT face="" size=2>DllImport within VB .NET and create my own unmanaged links to libspeex.dll.</FONT></FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>With the help of this partial c# code (<A title="http://lists.xiph.org/pipermail/speex-dev/2007-February/005307.html CTRL + Click to follow link" href="wlmailhtml:{C1E70AA4-6EB6-4BA6-845C-F6D340AFEDB1}mid://00000051/!x-usc:http://lists.xiph.org/pipermail/speex-dev/2007-February/005307.html"><U><FONT face="" color=#0000ff>http://lists.xiph.org/pipermail/speex-dev/2007-February/005307.html</FONT></U></A>) I created this VB.net class:</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>(I have focused on the decode side of things to start with, until I have it working).</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Imports System<BR>Imports System.Runtime.InteropServices<BR>Imports System.IO</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>Namespace Speex<BR> '''<summary><BR> '''the following class is the win32 SPEEX API that retrieve <BR> '''methods and structures from the libspeex file <BR> '''</summary> </FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2> Public Class Speex_win32</FONT></DIV>
<DIV> </DIV><FONT face=Arial size=2>
<DIV><BR>#Region "Speex Constants"</DIV>
<DIV> </DIV>
<DIV> 'global speex file that contains the api(s) </DIV>
<DIV> </DIV>
<DIV> Public Const libpath As String = "libspeex.dll"<BR> Public Const Frame_Size As Integer = 160<BR> Public Const Max_Frame_Size As Integer = 2000<BR> Public Const Speex_Get_Frame_Size As Integer = 3<BR> Public Const Speex_Set_Quality As Integer = 4<BR> Public Const Speex_nb_Mode As Integer = 3</DIV>
<DIV> </DIV>
<DIV> 'create the structure that will hold the speexbits <BR> <StructLayout(LayoutKind.Sequential)> _<BR> Public Structure SpeexBits<BR> Public chars As IntPtr<BR> ' "raw" data <BR> Public nbBits As Integer<BR> ' Total number of bits stored in thestream <BR> Public charPtr As Integer<BR> ' Position of the byte "cursor" <BR> Public bitPtr As Integer<BR> ' Position of the bit "cursor" within thecurrent char <BR> Public owner As Integer<BR> ' Does the struct "own" the "raw" buffer(member "chars") <BR> Public overflow As Integer<BR> ' Set to one if we try to read past thevalid data <BR> Public buf_size As Integer<BR> ' Allocated size for buffer <BR> Public reserved1 As Integer<BR> ' Reserved for future use <BR> Public reserved2 As IntPtr<BR> ' Reserved for future use </DIV>
<DIV> </DIV>
<DIV> End Structure<BR> Public Structure SpeexMode<BR> Public mode As IntPtr<BR> Public query As IntPtr<BR> Public modeName As String<BR> Public modeID As Integer<BR> Public bitstream_version As Integer<BR> Public enc_init As IntPtr<BR> Public enc_destroy As IntPtr<BR> Public enc As IntPtr<BR> Public dec_init As IntPtr<BR> Public dec_destroy As IntPtr<BR> Public dec As IntPtr<BR> Public enc_ctl As IntPtr<BR> Public dec_ctl As IntPtr<BR> End Structure</DIV>
<DIV>#End Region</DIV>
<DIV> </DIV>
<DIV>#Region "Exported Methods"<BR> <DllImport(libpath)> _<BR> Public Shared Sub speex_bits_init(ByRef bits As SpeexBits)<BR> End Sub<BR> <DllImport(libpath)> _<BR> Public Shared Function speex_decoder_init(ByRef mode As SpeexMode) As IntPtr<BR> End Function<BR> <DllImport(libpath)> _<BR> Public Shared Function speex_bits_remaining(ByRef bits As SpeexBits) As Integer<BR> End Function<BR> <DllImport(libpath)> _<BR> Public Shared Sub speex_bits_destroy(ByRef bits As SpeexBits)<BR> End Sub<BR> <DllImport(libpath)> _<BR> Public Shared Sub speex_bits_read_from(ByRef bits As SpeexBits, ByVal bytes() As Char, ByVal len As Integer)<BR> End Sub<BR> <DllImport(libpath)> _<BR> Public Shared Function speex_decode(ByVal state As IntPtr, ByRef bits As SpeexBits, ByVal outt As Single()) As Integer<BR> End Function</DIV>
<DIV> <DllImport(libpath)> _<BR> Public Shared Sub speex_decoder_destroy(ByRef state As IntPtr)<BR> End Sub</DIV>
<DIV> <DllImport(libpath)> _<BR> Public Shared Function speex_lib_get_mode(ByVal mode As Integer) As IntPtr<BR> End Function</DIV>
<DIV> <DllImport(libpath)> _<BR> Public Shared Function speex_decoder_ctl(ByVal state As IntPtr, ByVal request As Integer, ByRef ptr As Integer) As Integer<BR> End Function</DIV>
<DIV> <DllImport(libpath)> _<BR> Public Shared Function speex_decode_int(ByVal state As IntPtr, ByRef bits As SpeexBits, ByVal outt() As Single) As Integer<BR> End Function</DIV>
<DIV> </DIV>
<DIV>#End Region</DIV>
<DIV> </DIV>
<DIV> End Class</DIV>
<DIV> </DIV>
<DIV>End Namespace</DIV>
<DIV> </DIV>
<DIV> </DIV>
<DIV>With this code I am now able to init the decoder as follows:</DIV>
<DIV> </DIV>
<DIV><FONT size=2>
</FONT> Dim speex_decoder_state As IntPtr<BR> 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)<BR>
speex_decoder_state = Speex.Speex_win32.speex_decoder_init(mode)<FONT face="" size=2><BR></FONT></FONT></DIV>
<DIV><FONT face=Arial size=2>and then I can do the following:</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2> Dim bits As New Speex.Speex_win32.SpeexBits<BR> Speex.Speex_win32.speex_bits_init(bits)</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2> Speex.Speex_win32.speex_bits_read_from(bits, data, len)<BR> MsgBox(Speex.Speex_win32.speex_bits_remaining(bits)) 'This correctly shows that the bits have been entered correctly, as it shows a number > 0</FONT></DIV>
<DIV><FONT face=Arial size=2><BR> Dim output(160-1) As Single<BR></DIV>
<DIV> Dim tmpval As Integer = Speex.Speex_win32.speex_decode(speex_decoder_state, bits, output)</DIV>
<DIV> </DIV>
<DIV>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."</DIV>
<DIV> </DIV>
<DIV>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?</DIV>
<DIV> </DIV>
<DIV>Cheers,</DIV>
<DIV>Martin<BR></DIV></FONT><br /><hr />Get Messenger on your Mobile! <a href='http://clk.atdmt.com/UKM/go/101719964/direct/01/' target='_new'>Get it now!</a></body>
</html>