1+ namespace DS4AudioStreamer . Sound ;
2+
3+ public static class Downmixer
4+ {
5+ public static void DownmixToStereo ( float [ ] input , float [ ] output , int frames , int channels )
6+ {
7+ if ( channels < 2 )
8+ {
9+ throw new ArgumentException ( "Need at least 2 channels to downmix" ) ;
10+ }
11+
12+ int inIdx = 0 ;
13+ int outIdx = 0 ;
14+
15+ for ( int i = 0 ; i < frames ; i ++ )
16+ {
17+ float left = input [ inIdx ] ; // Front Left
18+ float right = input [ inIdx + 1 ] ; // Front Right
19+
20+ if ( channels > 2 )
21+ {
22+ // Center
23+ if ( channels > 2 )
24+ {
25+ left += input [ inIdx + 2 ] * 0.7f ;
26+ right += input [ inIdx + 2 ] * 0.7f ;
27+ }
28+
29+ // LFE
30+ if ( channels > 3 )
31+ {
32+ left += input [ inIdx + 3 ] * 0.5f ;
33+ right += input [ inIdx + 3 ] * 0.5f ;
34+ }
35+
36+ // SL/SR
37+ if ( channels > 4 )
38+ {
39+ left += input [ inIdx + 4 ] * 0.7f ;
40+ }
41+
42+ if ( channels > 5 )
43+ {
44+ right += input [ inIdx + 5 ] * 0.7f ;
45+ }
46+
47+ // SBL/SBR (7.1)
48+ if ( channels > 6 )
49+ {
50+ left += input [ inIdx + 6 ] * 0.7f ;
51+ }
52+
53+ if ( channels > 7 )
54+ {
55+ right += input [ inIdx + 7 ] * 0.7f ;
56+ }
57+ }
58+
59+ // Prevent clipping by scaling down
60+ output [ outIdx ] = left * 0.5f ;
61+ output [ outIdx + 1 ] = right * 0.5f ;
62+
63+ inIdx += channels ;
64+ outIdx += 2 ;
65+ }
66+ }
67+
68+ public static unsafe void Downmix6To2 ( Span < float > input , Span < float > output , int frames )
69+ {
70+ int inIdx = 0 ;
71+ int outIdx = 0 ;
72+
73+ for ( int i = 0 ; i < frames ; i ++ )
74+ {
75+ // Load 6 floats (L, R, C, LFE, SL, SR)
76+ // We can’t load all 6 at once with Vector<float> (needs multiple of Vector<float>.Count),
77+ // so SIMD wins mostly for bulk copy/scale. For mixing, plain scalar math is fine.
78+
79+ float l = input [ inIdx ] ;
80+ float r = input [ inIdx + 1 ] ;
81+ float c = input [ inIdx + 2 ] ;
82+ float lfe = input [ inIdx + 3 ] ;
83+ float sl = input [ inIdx + 4 ] ;
84+ float sr = input [ inIdx + 5 ] ;
85+
86+ float left = l + ( c * 0.7f ) + ( lfe * 0.5f ) + ( sl * 0.7f ) ;
87+ float right = r + ( c * 0.7f ) + ( lfe * 0.5f ) + ( sr * 0.7f ) ;
88+
89+ output [ outIdx ] = left * 0.5f ;
90+ output [ outIdx + 1 ] = right * 0.5f ;
91+
92+ inIdx += 6 ;
93+ outIdx += 2 ;
94+ }
95+ }
96+ }
0 commit comments