11#region usings
22using System ;
33using System . Collections . Generic ;
4+ using System . Collections . Immutable ;
45using System . Linq ;
56using System . Runtime . InteropServices ;
67
@@ -23,6 +24,8 @@ public void SetBuffer(float[] buffer)
2324 }
2425
2526 float [ ] FBuffer ;
27+
28+ internal float [ ] Buffer => FBuffer ;
2629
2730 protected override void FillBuffer ( float [ ] buffer , int offset , int count )
2831 {
@@ -45,55 +48,62 @@ public override void Dispose()
4548 /// </summary>
4649 public class MultiChannelSignal : AudioSignal
4750 {
48- protected int FOutputCount ;
51+ private ImmutableArray < SingleSignal > FOutputs = ImmutableArray < SingleSignal > . Empty ;
52+
4953 public MultiChannelSignal ( )
5054 {
51- Outputs = new List < AudioSignal > ( ) ;
5255 SetOutputCount ( 2 ) ;
5356 }
5457
5558 public void SetOutputCount ( int newCount )
5659 {
57- //recreate output signals?
58- if ( FOutputCount != newCount )
60+ if ( newCount != FOutputs . Length )
5961 {
60- FOutputCount = newCount ;
61-
62- Outputs . ResizeAndDispose ( newCount , ( ) => new SingleSignal ( Read ) ) ;
62+ foreach ( var s in FOutputs )
63+ s . Dispose ( ) ;
6364
64- FReadBuffers = new float [ FOutputCount ] [ ] ;
65- }
66-
67- //make sure new buffers get assigned by the manage buffers method
68- if ( FOutputCount > 0 )
69- {
70- FReadBuffers = new float [ FOutputCount ] [ ] ;
65+ var outputs = ImmutableArray . CreateBuilder < SingleSignal > ( newCount ) ;
66+ for ( int i = 0 ; i < newCount ; i ++ )
67+ outputs . Add ( new SingleSignal ( Read ) ) ;
68+ FOutputs = outputs . MoveToImmutable ( ) ;
69+ FNeedsRead = true ;
7170 }
7271 }
73-
74- public List < AudioSignal > Outputs
75- {
76- get ;
77- protected set ;
78- }
79-
72+
73+ public IReadOnlyList < AudioSignal > Outputs => FOutputs ;
74+ public int OutputCount => FOutputs . Length ;
75+
8076 protected float [ ] [ ] FReadBuffers ;
8177 protected void ManageBuffers ( int count )
8278 {
83- if ( FReadBuffers [ 0 ] is null || FReadBuffers [ 0 ] . Length < count )
79+ var outputs = FOutputs ;
80+ if ( ! BuffersAreLargeEnough ( outputs , count ) )
8481 {
85- FReadBuffers = new float [ FOutputCount ] [ ] ;
86- for ( int i = 0 ; i < FOutputCount ; i ++ )
82+ FReadBuffers = new float [ outputs . Length ] [ ] ;
83+ for ( int i = 0 ; i < FReadBuffers . Length ; i ++ )
8784 {
8885 FReadBuffers [ i ] = GC . AllocateArray < float > ( count , pinned : true ) ;
89- ( Outputs [ i ] as SingleSignal ) . SetBuffer ( FReadBuffers [ i ] ) ;
86+ outputs [ i ] . SetBuffer ( FReadBuffers [ i ] ) ;
9087 }
9188 }
89+
90+ static bool BuffersAreLargeEnough ( ImmutableArray < SingleSignal > outputs , int count )
91+ {
92+ foreach ( var o in outputs )
93+ if ( ! BufferIsLargeEnough ( o . Buffer , count ) )
94+ return false ;
95+ return true ;
96+ }
97+
98+ static bool BufferIsLargeEnough ( float [ ] buffer , int count )
99+ {
100+ return buffer != null && buffer . Length >= count ;
101+ }
92102 }
93103
94104 protected void Read ( int offset , int count )
95105 {
96- if ( FNeedsRead && FOutputCount > 0 )
106+ if ( FNeedsRead && FOutputs . Length > 0 )
97107 {
98108 ManageBuffers ( count ) ;
99109 FillBuffers ( FReadBuffers , offset , count ) ;
@@ -122,36 +132,6 @@ public override void Dispose()
122132 base . Dispose ( ) ;
123133 }
124134 }
125-
126- public static class ListExtra
127- {
128- public static void ResizeAndDispose < T > ( this List < T > list , int newSize , Func < T > create )
129- {
130- int count = list . Count ;
131- if ( newSize < count )
132- {
133- var itemCount = count - newSize ;
134- var toRemove = list . GetRange ( newSize , itemCount ) ;
135- toRemove . Reverse ( ) ;
136- foreach ( var item in toRemove )
137- {
138- list . Remove ( item ) ;
139- var disposable = item as IDisposable ;
140- if ( item != null )
141- disposable . Dispose ( ) ;
142- }
143- }
144- else if ( newSize > count )
145- {
146- var itemCount = newSize - count ;
147-
148- for ( int i = 0 ; i < itemCount ; i ++ )
149- {
150- list . Add ( create ( ) ) ;
151- }
152- }
153- }
154- }
155135}
156136
157137
0 commit comments