20
20
21
21
using System ;
22
22
using System . Collections . Generic ;
23
+ using System . IO ;
23
24
using System . Linq ;
24
25
using System . Runtime . InteropServices ;
25
26
using NLog ;
@@ -33,7 +34,7 @@ namespace VisualPinball.Engine.PinMAME
33
34
{
34
35
[ Serializable ]
35
36
[ DisallowMultipleComponent ]
36
- // [RequireComponent(typeof(AudioSource))]
37
+ [ RequireComponent ( typeof ( AudioSource ) ) ]
37
38
[ AddComponentMenu ( "Visual Pinball/Game Logic Engine/PinMAME" ) ]
38
39
public class PinMameGamelogicEngine : MonoBehaviour , IGamelogicEngine
39
40
{
@@ -107,6 +108,9 @@ private void Awake()
107
108
private void Start ( )
108
109
{
109
110
UpdateCaches ( ) ;
111
+
112
+ _lastAudioFrame = new float [ 0 ] ;
113
+ _lastAudioFrameOffset = 0 ;
110
114
}
111
115
112
116
public void OnInit ( Player player , TableApi tableApi , BallManager ballManager )
@@ -259,16 +263,11 @@ private int OnAudioAvailable(PinMameAudioInfo audioInfo)
259
263
private int OnAudioUpdated ( IntPtr framePtr , int frameSize )
260
264
{
261
265
var frame = new float [ frameSize * 2 ] ;
262
- var min = 0f ;
263
- var max = 0f ;
264
-
265
266
unsafe {
266
267
var src = ( short * ) framePtr ;
267
268
for ( var i = 0 ; i < frameSize ; i ++ ) {
268
269
frame [ i * 2 ] = src [ i ] / 32768f ;
269
270
frame [ i * 2 + 1 ] = frame [ i * 2 ] ; // duplicate - assuming input channels = 1, and output channels = 2.
270
- min = System . Math . Min ( min , frame [ i * 2 ] ) ;
271
- max = System . Math . Max ( max , frame [ i * 2 ] ) ;
272
271
}
273
272
}
274
273
@@ -280,32 +279,35 @@ private int OnAudioUpdated(IntPtr framePtr, int frameSize)
280
279
_audioQueue . Enqueue ( frame ) ;
281
280
}
282
281
283
- if ( min < - 0.1f || max > 0.1f ) {
284
- Logger . Info ( $ "Queueing audio sample ({ frameSize } ). [{ System . Math . Round ( min , 4 ) } { System . Math . Round ( max , 4 ) } ]") ;
285
- }
286
-
287
282
return _audioInfo . SamplesPerFrame ;
288
283
}
289
284
290
285
private void OnAudioFilterRead ( float [ ] data , int channels )
291
286
{
287
+ if ( channels != 2 ) {
288
+ Logger . Error ( $ "Got { channels } channels, expecting 2.") ;
289
+ return ;
290
+ }
291
+ const int size = sizeof ( float ) ;
292
292
var dataOffset = 0 ;
293
293
var lastFrameSize = _lastAudioFrame . Length - _lastAudioFrameOffset ;
294
294
if ( data . Length >= lastFrameSize ) {
295
- Buffer . BlockCopy ( _lastAudioFrame , _lastAudioFrameOffset , data , dataOffset , lastFrameSize ) ;
296
- dataOffset += lastFrameSize ;
295
+ if ( lastFrameSize > 0 ) {
296
+ Buffer . BlockCopy ( _lastAudioFrame , _lastAudioFrameOffset * size , data , 0 , lastFrameSize * size ) ;
297
+ dataOffset += lastFrameSize ;
298
+ }
297
299
_lastAudioFrame = new float [ 0 ] ;
298
300
_lastAudioFrameOffset = 0 ;
299
301
300
302
lock ( _audioQueue ) {
301
303
while ( dataOffset < data . Length && _audioQueue . Count > 0 ) {
302
304
var frame = _audioQueue . Dequeue ( ) ;
303
305
if ( frame . Length <= data . Length - dataOffset ) {
304
- Buffer . BlockCopy ( frame , 0 , data , dataOffset , frame . Length ) ;
306
+ Buffer . BlockCopy ( frame , 0 , data , dataOffset * size , frame . Length * size ) ;
305
307
dataOffset += frame . Length ;
306
308
307
309
} else {
308
- Buffer . BlockCopy ( frame , 0 , data , dataOffset , data . Length - dataOffset ) ;
310
+ Buffer . BlockCopy ( frame , 0 , data , dataOffset * size , ( data . Length - dataOffset ) * size ) ;
309
311
_lastAudioFrame = frame ;
310
312
_lastAudioFrameOffset = data . Length - dataOffset ;
311
313
dataOffset = data . Length ;
@@ -314,7 +316,7 @@ private void OnAudioFilterRead(float[] data, int channels)
314
316
}
315
317
316
318
} else {
317
- Buffer . BlockCopy ( _lastAudioFrame , _lastAudioFrameOffset , data , 0 , data . Length ) ;
319
+ Buffer . BlockCopy ( _lastAudioFrame , _lastAudioFrameOffset * size , data , 0 , data . Length * size ) ;
318
320
_lastAudioFrameOffset += data . Length ;
319
321
}
320
322
}
0 commit comments