[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework.interop

DX8 SetNotificationPositions, Error 32811

celoftis

9/10/2007 11:50:00 PM

Using DX8,
I am developing a VS2005, VB.NET program to record audio from with
the
mic or phone line in.

As a starting point, I found a tutorial and examples on DirectSound
written is VB6. When I try to convert that program to VB.NET I get
run
time errors on the following code (frmDX_Record.vb, Initialize sub):


Buff.SetNotificationPositions(EventsNotify.Length,
EventsNotify)


The error is:
Error: 32811
Desription: Element not found. (Exception from HRESULT:
0x8002802B (TYPE_E_ELEMENTNOTFOUND))
Source: Interop.DxVBLibA"


I don't see where the code is wrong but I'm new to DirectX
development
-- anyone have an idea what I am doing wrong?


Any input or pointers to DirectX info or examples would appreciated.
Thanks
celoftis


Full code below (watch for line wraps)...
---------------------------------------------------------------------------­­------------------------
frmDX_Record.vb:
---------------------------------------------------------------------------­­------------------------
Option Strict Off
Option Explicit On
Friend Class frmDX_Record
Inherits System.Windows.Forms.Form
Implements DxVBLibA.DirectXEvent8
' Made by Michael Ciurescu
'
' DirectSound Tutorial:
' http://www.vbforums.com/showthread.ph...


' Direct Sound objects
Private DX As New DxVBLibA.DirectX8
Private SEnum As DxVBLibA.DirectSoundEnum8
Private DISCap As DxVBLibA.DirectSoundCapture8


' buffer, and buffer description
Private Buff As DxVBLibA.DirectSoundCaptureBuffer8
Private BuffDesc As DxVBLibA.DSCBUFFERDESC


' For the events
Private EventsNotify() As DxVBLibA.DSBPOSITIONNOTIFY
Private MidEvent, EndEvent, StartEvent As Integer


' to know the buffer size
Private BuffLen, HalfBuffLen As Integer


Public Event GotWaveData(ByRef Buffer As System.Array, ByRef
BitsPerSample As Short, ByRef Channels As Short)


Private Sub DirectXEvent8_DXCallback(ByVal eventid As Integer)
Implements DxVBLibA.DirectXEvent8.DXCallback
Dim WaveBuffer() As Byte


' make sure that Buff object is actually initialized to a
buffer instance
If Not (Buff Is Nothing) Then
ReDim WaveBuffer(HalfBuffLen - 1)


Select Case eventid
Case StartEvent
' we got the event that the write cursor is at
the
beginning of the buffer
' therefore read from the middle of the buffer to
the end
Buff.ReadBuffer(HalfBuffLen, HalfBuffLen,
WaveBuffer(0), DxVBLibA.CONST_DSCBLOCKFLAGS.DSCBLOCK_DEFAULT)
Case MidEvent
' we got an event that the write cursor is at the
middle of the buffer
' threfore read from the beginning of the buffer
to the middle
Buff.ReadBuffer(0, HalfBuffLen, WaveBuffer(0),
DxVBLibA.CONST_DSCBLOCKFLAGS.DSCBLOCK_DEFAULT)
Case EndEvent
' not used right now
End Select


If eventid = StartEvent Or eventid = MidEvent Then
RaiseEvent GotWaveData(WaveBuffer,
(BuffDesc.fxFormat.nBitsPerSample), (BuffDesc.fxFormat.nChannels))
End If
End If
End Sub


Public Function Initialize(Optional ByVal SamplesPerSec As
Integer =
44100, Optional ByVal BitsPerSample As Short = 16, Optional ByVal
Channels As Short = 2, Optional ByVal HalfBufferLen As Integer = 0,
Optional ByVal GUID As String = "") As String


' if there is any error go to ReturnError
On Error GoTo ReturnError


SEnum = DX.GetDSCaptureEnum ' get the device
enumeration object


' if GUID is empty, then assign the first sound
device
If Len(GUID) = 0 Then GUID = SEnum.GetGuid(1)


' choose the sound device, and create the Direct
Sound
object
DISCap = DX.DirectSoundCaptureCreate(GUID)


' set the format to use for recording
With BuffDesc.fxFormat
.nFormatTag =
DxVBLibA.CONST_DSOUND.WAVE_FORMAT_PCM
.nChannels = Channels
.nBitsPerSample = BitsPerSample
.lSamplesPerSec = SamplesPerSec


.nBlockAlign = (.nBitsPerSample * .nChannels)
\ 8
.lAvgBytesPerSec = .lSamplesPerSec
* .nBlockAlign


If HalfBufferLen <= 0 Then
' make half of the buffer to be 100
ms
HalfBuffLen = .lAvgBytesPerSec / 10
Else
' using a "custom" size buffer
HalfBuffLen = HalfBufferLen
End If


' make sure the buffer is aligned
HalfBuffLen = HalfBuffLen - (HalfBuffLen
Mod .nBlockAlign)
End With


' calculate the total size of the buffer
BuffLen = HalfBuffLen * 2


BuffDesc.lBufferBytes = BuffLen
BuffDesc.lFlags =
DxVBLibA.CONST_DSCBCAPSFLAGS.DSCBCAPS_DEFAULT


' create the buffer object
Buff = DISCap.CreateCaptureBuffer(BuffDesc)


' Create 3 event notifications
ReDim EventsNotify(2)


' create event to signal that DirectSound write
cursor
' is at the beginning of the buffer
StartEvent = DX.CreateEvent(Me)
EventsNotify(0).hEventNotify = StartEvent
EventsNotify(0).lOffset = 1


' create event to signal that DirectSound write
cursor
' is at half of the buffer
MidEvent = DX.CreateEvent(Me)
EventsNotify(1).hEventNotify = MidEvent
EventsNotify(1).lOffset = HalfBuffLen


' create the event to signal the sound has stopped
EndEvent = DX.CreateEvent(Me)
EventsNotify(2).hEventNotify = EndEvent
EventsNotify(2).lOffset =
DxVBLibA.CONST_DSOUND.DSBPN_OFFSETSTOP


' Assign the notification points to the buffer
'Error on next line. I see the upgrade warnings above, but it appears
that passing Me as the argument to CreateEvent is correct...
Buff.SetNotificationPositions(EventsNotify.Length,
EventsNotify)


Initialize = ""
Exit Function
ReturnError:
' return error number, description and source
Initialize = "Error: " & Err.Number & vbNewLine &
"Desription: " &
Err.Description & vbNewLine & "Source: " & Err.Source


Err.Clear()
UninitializeSound()
Exit Function
End Function


Public Sub UninitializeSound()
On Error Resume Next
If UBound(EventsNotify) > 0 Then
If Err.Number = 0 Then
' distroy all events


DX.DestroyEvent(EventsNotify(0).hEventNotify)


DX.DestroyEvent(EventsNotify(1).hEventNotify)


DX.DestroyEvent(EventsNotify(2).hEventNotify)


Erase EventsNotify
End If
End If


'UPGRADE_NOTE: Object Buff may not be destroyed until it is
garbage collected. Click for more: 'ms-help://MS.VSCC.v80/
dv_commoner/
local/redirect.htm?keyword="6E35BFF6-CD74-4B09-9689-3E1A43DF8969"'
Buff = Nothing
'UPGRADE_NOTE: Object DISCap may not be destroyed until it is
garbage collected. Click for more: 'ms-help://MS.VSCC.v80/
dv_commoner/
local/redirect.htm?keyword="6E35BFF6-CD74-4B09-9689-3E1A43DF8969"'
DISCap = Nothing
'UPGRADE_NOTE: Object SEnum may not be destroyed
until
it is garbage
collected. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/
redirect.htm?keyword="6E35BFF6-CD74-4B09-9689-3E1A43DF8969"'
SEnum = Nothing
End Sub


Public Function SoundPlay() As Boolean
On Error GoTo ReturnError


If Not Buff Is Nothing Then
Buff.Start(DxVBLibA.CONST_DSCBSTARTFLAGS.DSCBSTART_LOOPING)


SoundPlay = True
Exit Function
ReturnError:
SoundPlay = False
Err.Clear()
End Function


Public Function SoundStop() As Boolean
On Error GoTo ReturnError


If Not Buff Is Nothing Then Buff.Stop()


SoundStop = True
Exit Function
ReturnError:
SoundStop = False
Err.Clear()
End Function


Private Sub frmDX_Record_FormClosing(ByVal eventSender As
System.Object, ByVal eventArgs As
System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Dim Cancel As Boolean = eventArgs.Cancel
Dim UnloadMode As System.Windows.Forms.CloseReason =
eventArgs.CloseReason
UninitializeSound()
eventArgs.Cancel = Cancel
End Sub


End Class


---------------------------------------------------------------------------­­------------------------
frmDX_Record.Designer.vb:
---------------------------------------------------------------------------­­------------------------
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Class frmDX_Record
#Region "Windows Form Designer generated code "
<System.Diagnostics.DebuggerNonUserCode()> Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
End Sub
'Form overrides dispose to clean up the component list.
<System.Diagnostics.DebuggerNonUserCode()> Protected
Overloads
Overrides Sub Dispose(ByVal Disposing As Boolean)
If Disposing Then
If Not components Is Nothing Then
components.Dispose()
End If
End If
MyBase.Dispose(Disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
Public ToolTip1 As System.Windows.Forms.ToolTip
'NOTE: The following procedure is required by the Windows
Form
Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub
InitializeComponent()
Me.components = New System.ComponentModel.Container
Me.ToolTip1 = New System.Windows.Forms.ToolTip(Me.components)
Me.SuspendLayout()
'
'frmDX_Record
'
Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!,
14.0!)
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.BackColor = System.Drawing.SystemColors.Control
Me.ClientSize = New System.Drawing.Size(207, 127)
Me.Cursor = System.Windows.Forms.Cursors.Default
Me.Font = New System.Drawing.Font("Arial", 8.0!,
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point,
CType(0, Byte))
Me.FormBorderStyle =
System.Windows.Forms.FormBorderStyle.None
Me.Name = "frmDX_Record"
Me.RightToLeft = System.Windows.Forms.RightToLeft.No
Me.ShowInTaskbar = False
Me.Text = "Form2"
Me.ResumeLayout(False)


End Sub
#End Region
End Class

3 Answers

celoftis

9/10/2007 11:54:00 PM

0

Here's a couple of replies this post from
"microsoft.public.dotnet.languages.vb" - per a suggestion from the
poster I have posted this thread and the responses here...


On Aug 19, 7:07 am, "Armin Zingler" <az.nos...@freenet.de> wrote:
> Unfortunatelly I don't have an answer to your question. Since there is
> "managed DirectX", most peoply don't use the old COM interop interfaces
> anymore. Install the DirectX SDK (if not done already) and set a reference
> to the required "Microsoft.DicrectX[.*]" assemblies (on the ".NET" tab, not
> "COM"). There's also a group for MDX:
> microsoft.public.win32.programmer.directx.managed. But be aware that MDX is
> or will be discontinued in the latest or next release, so download the
> latest SDK that supports it.
>
> Armin


On Aug 19, 7:23 am, "Armin Zingler" <az.nos...@freenet.de> wrote:
> Try to manually import the library using tlbimp. If the upgrade wizard does
> it automatically, it is like specifying the "/sysarray" param for tlbimp.
> Omit this option if you do it manually. The declaration of the 2nd arg of
> SetNotificationPositions will then change from "ByRef psa As System.Array"
> to "ByRef psa() As DSBPOSITIONNOTIFY". Maybe this resolves the error. Just
> an attempt.
>
> Armin

celoftis

9/10/2007 11:55:00 PM

0

On Sep 6, 12:48 pm, celoftis wrote:
> I tried the tlbimp (and I see that the second parm of
> SetNotificationPositions changed...) but when I run the code I still
> get the exact same error...
>
> Upon further investigation, I noticed that the this statement
> SEnum.GetGuid(1)
>
> Is returing the string:
> {00000000-0000-0000-0000-000000000000}
>
> Also, SEnum.GetName(1) returns "" and SEnum.GetDescription(1) returns
> "Primary Sound Capture Driver"
> Shouldn't the GUID have some other data in it? Could this be the
> source of the problem?
>
> If this doesn't work, any suggestions on using the managed DX - I mean
> will the objects in the API be named the same?

celoftis

9/10/2007 11:57:00 PM

0

On Sep 7, 10:53 am, "Armin Zingler" <az.nos...@freenet.de> wrote:
>>
> I don't see an error in the code using SetNotificationPositions. Using
> managed DX, you can use
> Microsoft.DirectX.DirectSound.Notify.SetNotificationPositions. Maybe you can
> migrate to MDX.
>
> ....... I did some debugging with your code. Using unmanaged debugging, it
> turns out to be an interop marshalling problem, as the callstack shows:
>
> > mscorlib.dll!System.Runtime.InteropServices.SafeArrayTypeMismatchException.­SafeArrayTypeMismatchException()
>
> mscorwks.dll!_CallDescrWorker@16()
> mscorwks.dll!MethodDesc::CallDescr()
> mscorwks.dll!MethodDesc::Call()
> mscorwks.dll!CallDefaultConstructor()
> mscorwks.dll!CreateMethodExceptionObject()
> mscorwks.dll!RealCOMPlusThrow()
> mscorwks.dll!OleVariant::CreateSafeArrayForArrayRef()
> mscorwks.dll!SafeArrayMarshaler::ConvertSpaceComToNative()
> mscorwks.dll!SafeArrayMarshaler::MarshalComToNativeByref()
> mscorwks.dll!RunML()
> WindowsApplication28.exe!WindowsApplication28.Form1.Initialize(...) Basic
>
> So, it's actually a "SafeArrayTypeMismatchException". Unfortunatelly, I have
> no clue, why. But maybe somebody else can use this information to help
> (Mattias? :-) ) Or you can try the interop group
> (microsoft.public.dotnet.framework.interop).
>
> After manually importing the tlb, enabling "load dll exports" and changing
> the IDE's exception handling to jump into the debugger when the exception is
> raised for all types of exceptions, the call stack is:
>
> kernel32.dll!_RaiseException@16()
> mscorwks.dll!RaiseTheException()
> mscorwks.dll!RealCOMPlusThrow()
> mscorwks.dll!RealCOMPlusThrow()
> mscorwks.dll!CreateMethodExceptionObject()
> mscorwks.dll!RealCOMPlusThrowHRWorker()
> mscorwks.dll!RealCOMPlusThrowHRWorker()
> mscorwks.dll!RealCOMPlusThrowHR()
> mscorwks.dll!RealCOMPlusThrowHR()
> mscorwks.dll!OleVariant::CreateSafeArrayDescriptorForArrayRef()
> mscorwks.dll!OleVariant::CreateSafeArrayForArrayRef()
> mscorwks.dll!SafeArrayMarshaler::ConvertSpaceComToNative()
> mscorwks.dll!SafeArrayMarshaler::MarshalComToNativeByref()
> mscorwks.dll!RunML()
>
> > WindowsApplication28.exe!WindowsApplication28.Form1.Initialize(...) Basic
>
> Hmmm...