@@ -10,15 +10,15 @@ Public Class AdlibAdapter ' Based on fake86's implementation
10
10
11
11
Private mCPU As X8086
12
12
13
- Private waveForm()() As Byte = {
14
- New Byte () { 1 , 8 , 13 , 20 , 25 , 32 , 36 , 42 , 46 , 50 , 54 , 57 , 60 , 61 , 62 , 64 , 63 , 65 , 61 , 61 , 58 , 55 , 51 , 49 , 44 , 38 , 34 , 28 , 23 , 16 , 11 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
15
- New Byte () { 1 , 8 , 13 , 21 , 25 , 31 , 36 , 43 , 45 , 50 , 54 , 57 , 59 , 62 , 63 , 63 , 63 , 64 , 63 , 59 , 59 , 55 , 52 , 48 , 44 , 38 , 34 , 28 , 23 , 16 , 10 , 4 , 2 , 7 , 14 , 20 , 26 , 31 , 36 , 42 , 45 , 51 , 54 , 56 , 60 , 62 , 62 , 63 , 65 , 63 , 62 , 60 , 58 , 55 , 52 , 48 , 44 , 38 , 34 , 28 , 23 , 17 , 10 , 3 },
16
- New Byte () { 1 , 8 , 13 , 20 , 26 , 31 , 36 , 42 , 46 , 51 , 53 , 57 , 60 , 62 , 61 , 66 , 16 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 7 , 13 , 21 , 25 , 32 , 36 , 41 , 47 , 50 , 54 , 56 , 60 , 62 , 61 , 67 , 15 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
17
- New Byte () { 1 , 8 , 13 , 20 , 26 , 31 , 37 , 41 , 47 , 49 , 54 , 58 , 58 , 62 , 63 , 63 , 64 , 63 , 62 , 61 , 58 , 55 , 52 , 47 , 45 , 38 , 34 , 27 , 23 , 17 , 10 , 4 , - 2 , - 8 , - 15 , - 21 , - 26 , - 34 , - 36 , - 42 , - 48 , - 51 , - 54 , - 59 , - 60 , - 62 , - 64 , - 65 , - 65 , - 63 , - 64 , - 61 , - 59 , - 56 , - 53 , - 48 , - 46 , - 39 , - 36 , - 28 , - 24 , - 17 , - 11 , - 6 }
13
+ Private waveForm()() As Short = {
14
+ New Short () { 1 , 8 , 13 , 20 , 25 , 32 , 36 , 42 , 46 , 50 , 54 , 57 , 60 , 61 , 62 , 64 , 63 , 65 , 61 , 61 , 58 , 55 , 51 , 49 , 44 , 38 , 34 , 28 , 23 , 16 , 11 , 3 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
15
+ New Short () { 1 , 8 , 13 , 21 , 25 , 31 , 36 , 43 , 45 , 50 , 54 , 57 , 59 , 62 , 63 , 63 , 63 , 64 , 63 , 59 , 59 , 55 , 52 , 48 , 44 , 38 , 34 , 28 , 23 , 16 , 10 , 4 , 2 , 7 , 14 , 20 , 26 , 31 , 36 , 42 , 45 , 51 , 54 , 56 , 60 , 62 , 62 , 63 , 65 , 63 , 62 , 60 , 58 , 55 , 52 , 48 , 44 , 38 , 34 , 28 , 23 , 17 , 10 , 3 },
16
+ New Short () { 1 , 8 , 13 , 20 , 26 , 31 , 36 , 42 , 46 , 51 , 53 , 57 , 60 , 62 , 61 , 66 , 16 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 7 , 13 , 21 , 25 , 32 , 36 , 41 , 47 , 50 , 54 , 56 , 60 , 62 , 61 , 67 , 15 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 },
17
+ New Short () { 1 , 8 , 13 , 20 , 26 , 31 , 37 , 41 , 47 , 49 , 54 , 58 , 58 , 62 , 63 , 63 , 64 , 63 , 62 , 61 , 58 , 55 , 52 , 47 , 45 , 38 , 34 , 27 , 23 , 17 , 10 , 4 , - 2 , - 8 , - 15 , - 21 , - 26 , - 34 , - 36 , - 42 , - 48 , - 51 , - 54 , - 59 , - 60 , - 62 , - 64 , - 65 , - 65 , - 63 , - 64 , - 61 , - 59 , - 56 , - 53 , - 48 , - 46 , - 39 , - 36 , - 28 , - 24 , - 17 , - 11 , - 6 }
18
18
}
19
19
20
- Private oplWave()() As Byte = {
21
- New Byte () {
20
+ Private oplWave()() As Short = {
21
+ New Short () {
22
22
0 , 1 , 3 , 4 , 6 , 7 , 9 , 11 , 12 , 14 , 15 , 17 , 18 , 20 , 22 , 23 , 24 , 26 , 27 , 29 , 30 , 31 , 33 , 34 , 36 , 37 , 38 , 40 , 40 , 42 , 43 , 44 , 46 , 46 , 48 , 49 , 50 , 51 , 51 , 53 ,
23
23
53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 59 , 60 , 61 , 61 , 62 , 62 , 63 , 63 , 63 , 64 , 64 , 64 , 116 , 116 , 116 , 116 , 116 , 116 , 116 , 116 , 116 , 64 , 64 , 64 , 63 , 63 , 63 , 62 , 62 , 61 , 61 , 60 ,
24
24
59 , 59 , 58 , 57 , 57 , 56 , 55 , 54 , 53 , 53 , 51 , 51 , 50 , 49 , 48 , 46 , 46 , 44 , 43 , 42 , 40 , 40 , 38 , 37 , 36 , 34 , 33 , 31 , 30 , 29 , 27 , 26 , 24 , 23 , 22 , 20 , 18 , 17 , 15 , 14 ,
@@ -27,7 +27,7 @@ Public Class AdlibAdapter ' Based on fake86's implementation
27
27
- 63 , - 63 , - 63 , - 62 , - 62 , - 61 , - 61 , - 60 , - 59 , - 59 , - 58 , - 57 , - 57 , - 56 , - 55 , - 54 , - 53 , - 53 , - 51 , - 51 , - 50 , - 49 , - 48 , - 46 , - 46 , - 44 , - 43 , - 42 , - 40 , - 40 , - 38 , - 37 , - 36 , - 34 , - 33 , - 31 , - 30 , - 29 , - 27 , - 26 ,
28
28
- 24 , - 23 , - 22 , - 20 , - 18 , - 17 , - 15 , - 14 , - 12 , - 11 , - 9 , - 7 , - 6 , - 4 , - 3 , - 1
29
29
},
30
- New Byte () {
30
+ New Short () {
31
31
0 , 1 , 3 , 4 , 6 , 7 , 9 , 11 , 12 , 14 , 15 , 17 , 18 , 20 , 22 , 23 , 24 , 26 , 27 , 29 , 30 , 31 , 33 , 34 , 36 , 37 , 38 , 40 , 40 , 42 , 43 , 44 , 46 , 46 , 48 , 49 , 50 , 51 , 51 , 53 ,
32
32
53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 59 , 60 , 61 , 61 , 62 , 62 , 63 , 63 , 63 , 64 , 64 , 64 , 116 , 116 , 116 , 116 , 116 , 116 , 116 , 116 , 116 , 64 , 64 , 64 , 63 , 63 , 63 , 62 , 62 , 61 , 61 , 60 ,
33
33
59 , 59 , 58 , 57 , 57 , 56 , 55 , 54 , 53 , 53 , 51 , 51 , 50 , 49 , 48 , 46 , 46 , 44 , 43 , 42 , 40 , 40 , 38 , 37 , 36 , 34 , 33 , 31 , 30 , 29 , 27 , 26 , 24 , 23 , 22 , 20 , 18 , 17 , 15 , 14 ,
@@ -36,7 +36,7 @@ Public Class AdlibAdapter ' Based on fake86's implementation
36
36
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
37
37
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0
38
38
},
39
- New Byte () {
39
+ New Short () {
40
40
0 , 1 , 3 , 4 , 6 , 7 , 9 , 11 , 12 , 14 , 15 , 17 , 18 , 20 , 22 , 23 , 24 , 26 , 27 , 29 , 30 , 31 , 33 , 34 , 36 , 37 , 38 , 40 , 40 , 42 , 43 , 44 , 46 , 46 , 48 , 49 , 50 , 51 , 51 , 53 ,
41
41
53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 59 , 60 , 61 , 61 , 62 , 62 , 63 , 63 , 63 , 64 , 64 , 64 , 116 , 116 , 116 , 116 , 116 , 116 , 116 , 116 , 116 , 64 , 64 , 64 , 63 , 63 , 63 , 62 , 62 , 61 , 61 , 60 ,
42
42
59 , 59 , 58 , 57 , 57 , 56 , 55 , 54 , 53 , 53 , 51 , 51 , 50 , 49 , 48 , 46 , 46 , 44 , 43 , 42 , 40 , 40 , 38 , 37 , 36 , 34 , 33 , 31 , 30 , 29 , 27 , 26 , 24 , 23 , 22 , 20 , 18 , 17 , 15 , 14 ,
@@ -45,7 +45,7 @@ Public Class AdlibAdapter ' Based on fake86's implementation
45
45
63 , 63 , 63 , 62 , 62 , 61 , 61 , 60 , 59 , 59 , 58 , 57 , 57 , 56 , 55 , 54 , 53 , 53 , 51 , 51 , 50 , 49 , 48 , 46 , 46 , 44 , 43 , 42 , 40 , 40 , 38 , 37 , 36 , 34 , 33 , 31 , 30 , 29 , 27 , 26 ,
46
46
24 , 23 , 22 , 20 , 18 , 17 , 15 , 14 , 12 , 11 , 9 , 7 , 6 , 4 , 3 , 1
47
47
},
48
- New Byte () {
48
+ New Short () {
49
49
0 , 1 , 3 , 4 , 6 , 7 , 9 , 11 , 12 , 14 , 15 , 17 , 18 , 20 , 22 , 23 , 24 , 26 , 27 , 29 , 30 , 31 , 33 , 34 , 36 , 37 , 38 , 40 , 40 , 42 , 43 , 44 , 46 , 46 , 48 , 49 , 50 , 51 , 51 , 53 ,
50
50
53 , 54 , 55 , 56 , 57 , 57 , 58 , 59 , 59 , 60 , 61 , 61 , 62 , 62 , 63 , 63 , 63 , 64 , 64 , 64 , 116 , 116 , 116 , 116 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
51
51
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
@@ -56,41 +56,40 @@ Public Class AdlibAdapter ' Based on fake86's implementation
56
56
}
57
57
}
58
58
59
- Private oplStep() As Byte = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
59
+ Private oplStep() As UShort = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
60
60
61
61
Private Structure AdlibOpStruct
62
- Public wave As Byte
62
+ Public wave As UShort
63
63
End Structure
64
64
Private adlibOp( 9 - 1 )() As AdlibOpStruct
65
65
66
66
Private Structure AdlibChanStruct
67
67
Public Frequency As UShort
68
68
Public ConvFreq As Double
69
- Public KeyOn As Byte
69
+ Public KeyOn As Boolean
70
70
Public Octave As UShort
71
- Public WaveformSelect As Byte
71
+ Public WaveformSelect As UShort
72
72
End Structure
73
73
Private adlibChan( 9 - 1 ) As AdlibChanStruct
74
74
75
- Private attackTable() As Double = { 1.0003 , 1 . 00025 , 1 . 0002 , 1 . 00015 , 1 . 0001 , 1 . 00009 , 1 . 00008 , 1 . 00007 , 1 . 00006 , 1 . 00005 , 1 . 00004 , 1 . 00003 , 1 . 00002 , 1 . 00001 , 1 . 000005 } ' 1.003, 1.05, 1.01, 1.015, 1.02, 1.025, 1.03, 1.035, 1.04, 1.045, 1.05, 1.055, 1.06, 1.065, 1.07, 1.075 }
75
+ Private attackTable() As Double = { 1.0003 , 1 . 00025 , 1 . 0002 , 1 . 00015 , 1 . 0001 , 1 . 00009 , 1 . 00008 , 1 . 00007 , 1 . 00006 , 1 . 00005 , 1 . 00004 , 1 . 00003 , 1 . 00002 , 1 . 00001 , 1 . 000005 }
76
76
Private decayTable() As Double = { 0.99999 , 0 . 999985 , 0 . 99998 , 0 . 999975 , 0 . 99997 , 0 . 999965 , 0 . 99996 , 0 . 999955 , 0 . 99995 , 0 . 999945 , 0 . 99994 , 0 . 999935 , 0 . 99994 , 0 . 999925 , 0 . 99992 , 0 . 99991 }
77
- Private opTable() As Byte = { 0 , 0 , 0 , 1 , 1 , 1 , 255 , 255 , 0 , 0 , 0 , 1 , 1 , 1 , 255 , 255 , 0 , 0 , 0 , 1 , 1 , 1 }
77
+ Private opTable() As UShort = { 0 , 0 , 0 , 1 , 1 , 1 , 255 , 255 , 0 , 0 , 0 , 1 , 1 , 1 , 255 , 255 , 0 , 0 , 0 , 1 , 1 , 1 }
78
78
79
79
Private adlibEnv( 9 - 1 ) As Double
80
80
Private adlibDecay( 9 - 1 ) As Double
81
81
Private adlibAttack( 9 - 1 ) As Double
82
82
83
- Private sampleRateAdjust As Double = 1.0
84
- Private Const SampleRate As UInteger = 48000
83
+ Private Const SampleRate As UInteger = 44100
85
84
86
85
Private adlibRegMem( &HFF - 1 ) As UShort
87
86
Private adlibAddr As UShort = 0
88
87
Private adlibPrecussion As Boolean = False
89
88
Private adlibStatus As Byte = 0
90
- Private adlibStep( 9 - 1 ) As ULong
89
+ Private adlibStep( 9 - 1 ) As Long
91
90
92
- Private adlibTicks As ULong = X8086.GHz / SampleRate
93
- Private lastAdlibTicks As ULong
91
+ Private adlibTicks As Long
92
+ Private lastAdlibTicks As Long
94
93
95
94
Public Sub New (cpu As X8086)
96
95
mCPU = cpu
@@ -106,16 +105,6 @@ Public Class AdlibAdapter ' Based on fake86's implementation
106
105
ReDim Preserve attackTable( 16 - 1 )
107
106
ReDim Preserve decayTable( 16 - 1 )
108
107
ReDim Preserve opTable( 16 - 1 )
109
-
110
- mCPU.TryAttachHook( 8 , New X8086.IntHandler( Function ()
111
- Dim t As Long = mCPU.Sched.CurrentTime
112
- If t >= (lastAdlibTicks - adlibTicks) Then
113
- AdlibTick()
114
- lastAdlibTicks = t - (t - (lastAdlibTicks + adlibTicks))
115
- End If
116
-
117
- Return False
118
- End Function ))
119
108
End Sub
120
109
121
110
Public Property Volume As Double
@@ -146,18 +135,35 @@ Public Class AdlibAdapter ' Based on fake86's implementation
146
135
147
136
Public Overrides Sub InitiAdapter()
148
137
waveOut = New WaveOut() With {
149
- .NumberOfBuffers = 32 ,
138
+ .NumberOfBuffers = 8 ,
150
139
.DesiredLatency = 200
151
140
}
152
- audioProvider = New CustomBufferProvider( AddressOf FillAudioBuffer, SampleRate)
141
+ audioProvider = New CustomBufferProvider( AddressOf FillAudioBuffer, SampleRate, 16 , 1 )
153
142
waveOut.Init(audioProvider)
143
+
144
+ adlibTicks = (Scheduler.CLOCKRATE / SampleRate) '* waveOut.NumberOfBuffers ' FIXME: I don't this is 100% correct
145
+ lastAdlibTicks = Now.Ticks
146
+
154
147
waveOut.Play()
155
148
End Sub
156
149
150
+ Dim n As Integer = 0
157
151
Public Sub FillAudioBuffer(buffer() As Byte )
158
- For i As Integer = 0 To buffer.Length - 1
159
- buffer(i) = Math.Min( 255 , (AdlibGenerateSample() << 8 ) * mVolume)
160
- Next
152
+ Dim t As Long = Now.Ticks
153
+ If t >= (lastAdlibTicks + adlibTicks) Then
154
+ Dim v As Integer
155
+ For i As Integer = 0 To buffer.Length - 1 Step 2
156
+ v = AdlibGenerateSample()
157
+ buffer(i) = (v >> 8 ) And &HFF
158
+ buffer(i + 1 ) = v And &HFF
159
+ Next
160
+
161
+ n += 1
162
+ n = n Mod waveOut.NumberOfBuffers
163
+ If n = 0 Then AdlibTick()
164
+
165
+ lastAdlibTicks = t - (t - (lastAdlibTicks + adlibTicks))
166
+ End If
161
167
End Sub
162
168
163
169
Public Overrides Function [In](port As UInteger) As UInteger
@@ -197,14 +203,14 @@ Public Class AdlibAdapter ' Based on fake86's implementation
197
203
End If
198
204
ElseIf port >= &HA0 AndAlso port <= &HB8 Then ' Octave / Frequency / Key On
199
205
port = port And 15
200
- If adlibChan(port).KeyOn = 0 AndAlso ((adlibRegMem( &HB0 + port) >> 5 ) And 1 ) Then
206
+ If Not adlibChan(port).KeyOn AndAlso ((adlibRegMem( &HB0 + port) >> 5 ) And 1 ) = 1 Then
201
207
adlibAttack(port) = 0
202
208
adlibEnv(port) = 0.0025
203
209
End If
204
210
205
211
adlibChan(port).Frequency = adlibRegMem( &HA0 + port) Or ((adlibRegMem( &HB0 + port) And 3 ) << 8 )
206
212
adlibChan(port).ConvFreq = adlibChan(port).Frequency * 0.7626459
207
- adlibChan(port).KeyOn = (adlibRegMem( &HB0 + port) >> 5 ) And 1
213
+ adlibChan(port).KeyOn = (( adlibRegMem( &HB0 + port) >> 5 ) And 1 ) = 1
208
214
adlibChan(port).Octave = (adlibRegMem( &HB0 + port) >> 2 ) And 7
209
215
ElseIf port >= &HE0 And port <= &HF5 Then ' Waveform select
210
216
port = port And 15
@@ -215,7 +221,7 @@ Public Class AdlibAdapter ' Based on fake86's implementation
215
221
Private Function AdlibFrequency(channel As Byte ) As UShort
216
222
Dim tmpFrequency As UShort
217
223
218
- If adlibChan(channel).KeyOn = 0 Then Return 0
224
+ If Not adlibChan(channel).KeyOn Then Return 0
219
225
tmpFrequency = adlibChan(channel).ConvFreq
220
226
221
227
Select Case adlibChan(channel).Octave
@@ -231,29 +237,25 @@ Public Class AdlibAdapter ' Based on fake86's implementation
231
237
Return tmpFrequency
232
238
End Function
233
239
234
- Private Function AdlibSample(currentChannel As Byte ) As UInteger
235
- Dim tmpSample As UInteger
236
- Dim tmpStep As Double
237
- Dim fullStep As ULong
238
-
239
- If adlibPrecussion AndAlso currentChannel >= 6 AndAlso currentChannel <= 8 Then Return 0
240
+ Private Function AdlibSample(channel As Byte ) As Integer
241
+ If adlibPrecussion AndAlso channel >= 6 AndAlso channel <= 8 Then Return 0
240
242
241
- fullStep = SampleRate / AdlibFrequency(currentChannel)
243
+ Dim fullStep As Double = SampleRate / AdlibFrequency(channel)
244
+ Dim tmpSample As Integer = Int(oplWave(adlibChan(channel).WaveformSelect)(Int(adlibStep(channel) / (fullStep / 256.0 ) Mod 256 )))
242
245
243
- tmpSample = oplWave(adlibChan(currentChannel).WaveformSelect)(( CDbl (adlibStep(currentChannel)) / ( CDbl (fullStep) / 256.0 )) Mod 255 )
244
- tmpStep = adlibEnv(currentChannel)
245
- If tmpStep > 1 Then tmpStep = 1
246
- tmpSample = CDbl (tmpSample) * tmpStep * 2.0
246
+ Dim tmpStep As Double = adlibEnv(channel)
247
+ If tmpStep > 1.0 Then tmpStep = 1 . 0
248
+ tmpSample = Int(tmpSample * tmpStep * 2.0 )
247
249
248
- adlibStep(currentChannel ) += 1
249
- If adlibStep(currentChannel ) > fullStep Then adlibStep(currentChannel ) = 0
250
+ adlibStep(channel ) += 1
251
+ If adlibStep(channel ) > fullStep Then adlibStep(channel ) = 0
250
252
Return tmpSample
251
253
End Function
252
254
253
- Private Function AdlibGenerateSample() As UShort
254
- Dim adlibAccumulator As UShort = 0
255
+ Private Function AdlibGenerateSample() As Integer
256
+ Dim adlibAccumulator As Integer = 0
255
257
For currentChannel As Byte = 0 To 9 - 1
256
- If AdlibFrequency(currentChannel) <> 0 Then adlibAccumulator += AdlibSample(currentChannel)
258
+ If AdlibFrequency(currentChannel) <> 0 Then adlibAccumulator += Int( AdlibSample(currentChannel) )
257
259
Next
258
260
Return adlibAccumulator
259
261
End Function
0 commit comments