CSL 5.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

SimplePanner2.cpp
Go to the documentation of this file.
1 //
2 // SimplePanner.cpp -- Basic panner using a filter.
3 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 //
5
6 #include "SimplePanner.h"
7
8 namespace csl {
9
10 // Default constructor
11
12 SimplePanner::SimplePanner() :
13 mDryMix(2), // set up mixers
14 mRevMix(2),
15 mFiltMix(2),
16 mFiltSplit(mFiltMix), // splitter for filters
17 mRLPF(mFiltSplit, BW_LOW_PASS, 500.0f), // filters
18 mLLPF(mFiltSplit, BW_LOW_PASS, 500.0f),
19 mFiltJoin(mLLPF, mRLPF), // joiner for filters
20 mReverb(mRevMix), // stereoverb
21 mOutMix(2) { // grand out mix
22 mOutMix.addInput(mReverb); // add processing paths to out mixer
23 mOutMix.addInput(mDryMix);
24 mOutMix.addInput(mFiltJoin);
25
26 mOutMix.scaleInput(mDryMix, 0.4f); // scale out mix levels
27 mOutMix.scaleInput(mReverb, 0.4f);
28 mOutMix.scaleInput(mFiltMix, 0.4f);
29
30 mReverb.setWetLevel(1.0f); // set up reverb
31 mReverb.setDryLevel(0.0f);
32 mReverb.setRoomSize(0.988f); // long reverb time
33 }
34
35 SimplePanner::~SimplePanner() {
36 // no-op
37 }
38
39 void SimplePanner::addSource(SpatialSource &soundSource) {
40 unsigned which = mSources.size();
41 for (unsigned i = 0; i < which; i++) {
42 if (mSources[i] == NULL) {
43 which = i;
44 break;
45 }
46 }
47 mSources[which] = &soundSource;
48 Panner * inPan = new Panner(soundSource); // add a panner on the source
49 mPanners[which] = inPan; // store panner in vector
50 FanOut * inFan = new FanOut(*inPan, 3); // send the panner to 2 or 3 mixers
51 mFanOuts[which] = inFan; // store fan-out in vector
52 mDryMix.addInput(inFan); // add fan-out to mixers
53 mFiltMix.addInput(inFan);
54 mRevMix.addInput(inFan);
55 }
56
57 // delete from the list, shifting if necessary
58
59 void SimplePanner::removeSource(SpatialSource &soundSource) {
60 // find the source's panner and fanout
61 for (unsigned i = 0; i < mSources.size(); i++) {
62 if (mSources[i] == &soundSource) {
63 FanOut * inFan = (FanOut *) mFanOuts[i];
64 Panner * inPan = (Panner *) mPanners[i];
65 mDryMix.removeInput(*inFan);
66 mRevMix.removeInput(*inFan);
67 mFiltMix.removeInput(*inFan);
68 mPanners[i] = NULL;
69 mFanOuts[i] = NULL;
70 mSources[i] = NULL;
71 // delete inFan;
72 // delete inPan;
73 return;
74 }
75 }
76 }
77
78 // fill the buffer with the next buffer of values
79
80 void SimplePanner::nextBuffer(Buffer &outputBuffer /*, unsigned outBufNum */) throw (CException) {
81 float num, az, rem;
82 float half = 1.0f/2.0f;
83 // mPanners[0]->nextBuffer(outputBuffer);
84 // set all the panner values
85 for (unsigned i = 0; i < mPanners.size(); i++) {
86 if ( ! mSources[i]) continue;
87 az = ((SpatialSource *) mSources[i])->azimuth() / CSL_TWOPI; // range 0 - 1 = 0 - 2 pi
88 while (az < 0.0f) az += 1.0f;
89 rem = az;
90 if (rem > half) rem = 1.0f - rem;
91 rem *= 4.0f; // range 0 - 2
92 rem -= 1.0f; // range -1 - +1
93 ((Panner *) mPanners[i])->setPosition(rem); // set stereo position
94 // set reverb feed from distance
95 float distScale = 1.0f / sqrt(((SpatialSource *) mSources[i])->distance());
96 // float distScale = 1.0f / mSources[i]->distance(); // this brings up the reverb closer
97 mRevMix.scaleInput(*mFanOuts[i], 1.0f - distScale);
98 // set filter/dry ratio from front/back angle
99 if (az < half) { // front half
100 mFiltMix.scaleInput(*mFanOuts[i], 0.0f);
101 mDryMix.scaleInput(*mFanOuts[i], distScale);
102 } else { // rear half
103 float ratio = fabs(0.75f - az) * 4.0f; // scale 0 - 1
104 mFiltMix.scaleInput(*mFanOuts[i], (1.0f - ratio) * distScale);
105 mDryMix.scaleInput(*mFanOuts[i], ratio * distScale);
106 }
107 }
108 mOutMix.nextBuffer(outputBuffer); // now call the out mixer to run the graph
109 }
110
111 } // namespace