forked from hughpyle/inguz-DSPUtil
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Mixer.cs
102 lines (93 loc) · 2.85 KB
/
Mixer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
using System;
using System.Collections.Generic;
using System.Text;
// Copyright (c) 2006 by Hugh Pyle, inguzaudio.com
namespace DSPUtil
{
[Serializable]
public class Mixer : SoundObj
{
List<ISoundObj> _inputs = new List<ISoundObj>();
List<double> _gains = new List<double>();
public Mixer()
{
}
// Add another source. Note: gain is units, not db
public void Add(ISoundObj input, double gainUnits)
{
if (_inputs.Count == 0)
{
// Treat this as 'Input'...
Input = input;
}
if (_inputs.Count > 0)
{
if (input.NumChannels != NumChannels)
{
throw new Exception("Mixer inputs must have the same number of channels.");
}
}
_inputs.Add(input);
_gains.Add(gainUnits);
}
public override int Iterations
{
get
{
int i = 0;
foreach (ISoundObj input in _inputs)
{
i = Math.Max(i, input.Iterations);
}
return i;
}
}
/// <summary>
/// Get an iterator for samples
/// </summary>
public override IEnumerator<ISample> Samples
{
get
{
// Get enumerators for each input
List<IEnumerator<ISample>> enums = new List<IEnumerator<ISample>>();
List<bool> mores = new List<bool>();
foreach (ISoundObj input in _inputs)
{
enums.Add(input.Samples);
mores.Add(true);
}
bool anymore = true;
while (anymore)
{
Sample sample = new Sample(NumChannels);
int e = 0;
anymore = false;
foreach (IEnumerator<ISample> src in enums)
{
ISample s;
if (mores[e])
{
mores[e] = src.MoveNext();
}
if (mores[e])
{
s = src.Current;
}
else
{
s = new Sample(_inputs[e].NumChannels);
}
anymore |= mores[e];
for (int k = 0; k < s.NumChannels; k++)
{
sample[k] += (s[k] * _gains[e]);
}
e++;
}
yield return sample;
}
}
}
}
}