Skip to content

Commit 7b09591

Browse files
committed
Switched from SlimDX to NAudio
1 parent ca02609 commit 7b09591

File tree

12 files changed

+1062
-130
lines changed

12 files changed

+1062
-130
lines changed
Lines changed: 354 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,354 @@
1+
'#If Win32 Then
2+
'Imports SlimDX.DirectSound
3+
'Imports SlimDX.Multimedia
4+
'Imports System.Runtime.InteropServices
5+
'Imports System.Threading
6+
7+
'Public Class SpeakerAdpater
8+
' Inherits Adapter
9+
10+
' <DllImport("user32.dll", CharSet:=CharSet.Auto, ExactSpelling:=True)>
11+
' Private Shared Function GetDesktopWindow() As IntPtr
12+
' End Function
13+
14+
' Private Enum WaveForms
15+
' Squared
16+
' Sinusoidal
17+
' End Enum
18+
19+
' Private waveForm As WaveForms = WaveForms.Squared
20+
21+
' Private Const ToRad As Double = Math.PI / 180
22+
23+
' Private audioDev As DirectSound
24+
' Private bufPlayDesc As SoundBufferDescription
25+
' Private playBuf As SecondarySoundBuffer
26+
' Private notifySize As Integer
27+
' Private numberPlaybackNotifications As Integer = 8 ' 4
28+
' Private nextPlaybackOffset As Integer
29+
30+
' Private mAudioBuffer() As Byte
31+
' Private audioWriteBufferPosition As Integer
32+
' Private Const sampleRate As Integer = 44100
33+
34+
' Private mCPU As x8086
35+
' Private mEnabled As Boolean
36+
' Private playbackThread As Thread
37+
' Private cancelAllThreads As Boolean
38+
39+
' Private mFrequency As Double
40+
' Private waveLength As Integer
41+
' Private halfWaveLength As Integer
42+
' Private bufferWritePosition As Integer
43+
' Private bufferReadPosition As Integer
44+
' Private currentStep As Integer
45+
46+
' Private mVolume As Double
47+
48+
' Public Sub New(cpu As x8086)
49+
' mCPU = cpu
50+
' If mCPU.PIT IsNot Nothing Then mCPU.PIT.Speaker = Me
51+
' mVolume = 0.05
52+
' End Sub
53+
54+
' Public Property Frequency As Double
55+
' Get
56+
' Return mFrequency
57+
' End Get
58+
' Set(value As Double)
59+
' mFrequency = value
60+
' UpdateWaveformParameters()
61+
' End Set
62+
' End Property
63+
64+
' Public Property Enabled As Boolean
65+
' Get
66+
' Return mEnabled
67+
' End Get
68+
' Set(value As Boolean)
69+
' mEnabled = value
70+
' UpdateWaveformParameters()
71+
' End Set
72+
' End Property
73+
74+
' Public Property Volume As Double
75+
' Get
76+
' Return mVolume
77+
' End Get
78+
' Set(value As Double)
79+
' mVolume = value
80+
' End Set
81+
' End Property
82+
83+
' Public ReadOnly Property AudioBuffer As Byte()
84+
' Get
85+
' Return mAudioBuffer
86+
' End Get
87+
' End Property
88+
89+
' Private Sub UpdateWaveformParameters()
90+
' If mFrequency > 0 Then
91+
' waveLength = sampleRate / mFrequency
92+
' Else
93+
' waveLength = 0
94+
' End If
95+
96+
' halfWaveLength = waveLength / 2
97+
' End Sub
98+
99+
' Private Sub FillAudioBuffer()
100+
' Dim v As Double
101+
' Do
102+
' Select Case waveForm
103+
' Case WaveForms.Squared
104+
' If mEnabled Then
105+
' If currentStep <= halfWaveLength Then
106+
' v = -128
107+
' Else
108+
' v = 127
109+
' End If
110+
' Else
111+
' v = 0
112+
' End If
113+
' Case WaveForms.Sinusoidal
114+
' If mEnabled AndAlso waveLength > 0 Then
115+
' v = Math.Floor(Math.Sin((currentStep / waveLength) * (mFrequency / 2) * ToRad) * 128)
116+
' Else
117+
' v = 0
118+
' End If
119+
' End Select
120+
121+
' v *= mVolume
122+
' If v <= 0 Then
123+
' v = 128 + v
124+
' Else
125+
' v += 127
126+
' End If
127+
' mAudioBuffer(bufferWritePosition) = v
128+
129+
' currentStep += 1
130+
' If currentStep >= waveLength Then currentStep = 0
131+
132+
' bufferWritePosition += 1
133+
' bufferWritePosition = bufferWritePosition Mod mAudioBuffer.Length
134+
' Loop Until cancelAllThreads OrElse bufferWritePosition = 0
135+
' End Sub
136+
137+
' Private Sub MainLoop()
138+
' Do
139+
' waiter.WaitOne()
140+
141+
' FillAudioBuffer()
142+
' Write()
143+
' Loop Until cancelAllThreads
144+
' End Sub
145+
146+
' Public Overrides Sub CloseAdapter()
147+
' cancelAllThreads = True
148+
149+
' Do
150+
' Thread.Sleep(10)
151+
' Loop While playbackThread.ThreadState <> ThreadState.Stopped
152+
153+
' playBuf.Stop()
154+
' waiter.Set()
155+
156+
' playBuf.Dispose()
157+
' audioDev.Dispose()
158+
' End Sub
159+
160+
' Public Overrides ReadOnly Property Description As String
161+
' Get
162+
' Return "PC Speaker"
163+
' End Get
164+
' End Property
165+
166+
' Public Overrides Function [In](port As Integer) As Integer
167+
' Return &HFF
168+
' End Function
169+
170+
' Public Overrides Sub InitiAdapter()
171+
' ReDim mAudioBuffer(sampleRate / 100 - 1)
172+
173+
' ' Define the capture format
174+
' Dim format As WaveFormat = New WaveFormat()
175+
' With format
176+
' .BitsPerSample = 8
177+
' .Channels = 1
178+
' .FormatTag = WaveFormatTag.Pcm
179+
' .SamplesPerSecond = sampleRate
180+
' .BlockAlignment = CShort(.Channels * .BitsPerSample / 8)
181+
' .AverageBytesPerSecond = .SamplesPerSecond * .BlockAlignment
182+
' End With
183+
184+
' ' Define the size of the notification chunks
185+
' notifySize = mAudioBuffer.Length
186+
' notifySize -= notifySize Mod format.BlockAlignment
187+
188+
' ' Create a buffer description object
189+
' bufPlayDesc = New SoundBufferDescription()
190+
' With bufPlayDesc
191+
' .Format = format
192+
' .Flags = BufferFlags.ControlPositionNotify Or
193+
' BufferFlags.GetCurrentPosition2 Or
194+
' BufferFlags.GlobalFocus Or
195+
' BufferFlags.Static Or
196+
' BufferFlags.ControlVolume Or
197+
' BufferFlags.ControlPan Or
198+
' BufferFlags.ControlFrequency
199+
' .SizeInBytes = notifySize * numberPlaybackNotifications
200+
' End With
201+
202+
' audioDev = New DirectSound()
203+
' Dim windowHandle As IntPtr = GetDesktopWindow()
204+
' audioDev.SetCooperativeLevel(windowHandle, CooperativeLevel.Priority)
205+
' playBuf = New SecondarySoundBuffer(audioDev, bufPlayDesc)
206+
207+
' ' Define the notification events
208+
' Dim np(numberPlaybackNotifications - 1) As NotificationPosition
209+
210+
' For i As Integer = 0 To numberPlaybackNotifications - 1
211+
' np(i) = New NotificationPosition()
212+
' np(i).Offset = (notifySize * i) + notifySize - 1
213+
' np(i).Event = waiter
214+
' Next
215+
' playBuf.SetNotificationPositions(np)
216+
217+
' nextPlaybackOffset = 0
218+
' playBuf.Play(0, PlayFlags.Looping)
219+
220+
' playbackThread = New Thread(AddressOf MainLoop)
221+
' playbackThread.Start()
222+
' End Sub
223+
224+
' Public Sub Write()
225+
' Dim lockSize As Integer
226+
227+
' lockSize = playBuf.CurrentWritePosition - nextPlaybackOffset
228+
' If lockSize < 0 Then lockSize += bufPlayDesc.SizeInBytes
229+
230+
' ' Block align lock size so that we always read on a boundary
231+
' lockSize -= lockSize Mod notifySize
232+
' If lockSize = 0 Then Exit Sub
233+
234+
' playBuf.Write(Of Byte)(mAudioBuffer, nextPlaybackOffset, LockFlags.None)
235+
236+
' nextPlaybackOffset += mAudioBuffer.Length
237+
' nextPlaybackOffset = nextPlaybackOffset Mod bufPlayDesc.SizeInBytes ' Circular buffer
238+
' End Sub
239+
240+
' Public Overrides ReadOnly Property Name As String
241+
' Get
242+
' Return "Speaker"
243+
' End Get
244+
' End Property
245+
246+
' Public Overrides Sub Out(port As Integer, value As Integer)
247+
248+
' End Sub
249+
250+
' Public Overrides Sub Run()
251+
' x8086.Notify("Speaker Running", x8086.NotificationReasons.Info)
252+
' End Sub
253+
254+
' Public Overrides ReadOnly Property Type As Adapter.AdapterType
255+
' Get
256+
' Return AdapterType.Speaker
257+
' End Get
258+
' End Property
259+
260+
' Public Overrides ReadOnly Property Vendor As String
261+
' Get
262+
' Return "xFX JumpStart"
263+
' End Get
264+
' End Property
265+
266+
' Public Overrides ReadOnly Property VersionMajor As Integer
267+
' Get
268+
' Return 0
269+
' End Get
270+
' End Property
271+
272+
' Public Overrides ReadOnly Property VersionMinor As Integer
273+
' Get
274+
' Return 0
275+
' End Get
276+
' End Property
277+
278+
' Public Overrides ReadOnly Property VersionRevision As Integer
279+
' Get
280+
' Return 23
281+
' End Get
282+
' End Property
283+
'End Class
284+
'#Else
285+
'Public Class SpeakerAdpater
286+
' Inherits Adapter
287+
288+
' Public Sub New(cpu As x8086)
289+
290+
' End Sub
291+
292+
' Public Overrides Sub CloseAdapter()
293+
294+
' End Sub
295+
296+
' Public Overrides ReadOnly Property Description As String
297+
' Get
298+
' Return "Null PC Speaker"
299+
' End Get
300+
' End Property
301+
302+
' Public Overloads Overrides Function [In](port As Integer) As Integer
303+
' Return 0
304+
' End Function
305+
306+
' Public Overloads Overrides Sub Out(port As Integer, value As Integer)
307+
308+
' End Sub
309+
310+
' Public Overrides Sub InitiAdapter()
311+
312+
' End Sub
313+
314+
' Public Overrides ReadOnly Property Name As String
315+
' Get
316+
' Return "Null Speaker"
317+
' End Get
318+
' End Property
319+
320+
' Public Overrides Sub Run()
321+
322+
' End Sub
323+
324+
' Public Overrides ReadOnly Property Type As Adapter.AdapterType
325+
' Get
326+
' Return AdapterType.Speaker
327+
' End Get
328+
' End Property
329+
330+
' Public Overrides ReadOnly Property Vendor As String
331+
' Get
332+
' Return "xFX JumpStart"
333+
' End Get
334+
' End Property
335+
336+
' Public Overrides ReadOnly Property VersionMajor As Integer
337+
' Get
338+
' Return 0
339+
' End Get
340+
' End Property
341+
342+
' Public Overrides ReadOnly Property VersionMinor As Integer
343+
' Get
344+
' Return 0
345+
' End Get
346+
' End Property
347+
348+
' Public Overrides ReadOnly Property VersionRevision As Integer
349+
' Get
350+
' Return 1
351+
' End Get
352+
' End Property
353+
'End Class
354+
'#End If

0 commit comments

Comments
 (0)