CSL 5.2

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

- File List
- File Members

SimplePanner.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 stereo mixers for the graph
14 mFiltMix(2),
15 mRevMix(2),
16
17 mFiltSplit(mFiltMix), // splitter for filters
18 mRLPF(mFiltSplit, BW_LOW_PASS, 800.0f), // 2 lo-pass filters
19 mLLPF(mFiltSplit, BW_LOW_PASS, 800.0f),
20 mFiltJoin(mLLPF, mRLPF), // joiner for filters
21
22 mReverb(mRevMix), // stereoverb
23 mOutMix(2) // grand output mixer
24 {
25 mOutMix.addInput(mDryMix);
26 mOutMix.addInput(mFiltJoin);
27 mOutMix.addInput(mReverb); // add processing paths to out mixer
28
29 mOutMix.scaleInput(mDryMix, 0.4f); // scale out mix levels
30 mOutMix.scaleInput(mFiltJoin, 0.4f);
31 mOutMix.scaleInput(mReverb, 0.4f);
32
33 mReverb.setWetLevel(1.0f); // set up reverb
34 mReverb.setDryLevel(0.0f);
35 // mReverb.setRoomSize(0.99f); // long reverb time
36 }
37
38 SimplePanner::~SimplePanner() {
39 // no-op
40 }
41
42 // Add a new source, creating the in-panner as a fan-out
43
44 void SimplePanner::addSource(SpatialSource &soundSource) {
45 mSources.push_back(&soundSource); // remember the source
46 Panner * inPan = new Panner(soundSource); // add a panner on the source
47 mPanners.push_back(inPan); // store panner in vector
48
49 mDryMix.addInput(inPan); // add panner to mixers
50 mFiltMix.addInput(inPan);
51 mRevMix.addInput(inPan);
52 }
53
54 // delete from the list, shifting if necessary
55
56 void SimplePanner::removeSource(SpatialSource &soundSource) {
57 // find the source's panner and fanout
58 for (unsigned i = 0; i < mSources.size(); i++) {
59 if (mSources[i] == &soundSource) {
60 Panner * inPan = (Panner *) mPanners[i];
61 mDryMix.removeInput(*inPan);
62 mFiltMix.removeInput(*inPan);
63 mRevMix.removeInput(*inPan);
64
65 mSources.erase(mSources.begin() + i);
66 mPanners.erase(mPanners.begin() + i);
67 delete inPan;
68 return;
69 }
70 }
71 }
72
73 // fill the buffer with the next buffer of values
74
75 void SimplePanner::nextBuffer(Buffer &outputBuffer) throw (CException) {
76 float az, pos;
77 float half = 1.0f/2.0f;
78 if (mSources.size() == 0)
79 return;
80 // set all the panner values
81 for (unsigned i = 0; i < mSources.size(); i++) {
82 az = ((SpatialSource *) mSources[i])->azimuth() / CSL_TWOPI; // range 0 - 1 = 0 - 2 pi
83 while (az < 0.0f) az += 1.0f; // clip to range 0 - 1
84 while (az > 1.0f) az -= 1.0f;
85 pos = az;
86 if (pos > half) pos = 1.0f - pos;
87 pos *= 4.0f; // range 0 - 2
88 pos -= 1.0f; // range -1 - +1
89 ((Panner *) mPanners[i])->setPosition(pos); // set stereo position
90
91 // set reverb feed from distance
92 float distScale = 1.0f / sqrt(((SpatialSource *) mSources[i])->distance());
93 // float distScale = 1.0f / ((SpatialSource *) mSources[i]->distance()); // this brings up the reverb closer
94 mRevMix.scaleInput(*mPanners[i], 1.0f - distScale);
95
96 // set filter/dry ratio from front/back angle
97 if (az < half) { // front half
98 mFiltMix.scaleInput(*mPanners[i], 0.0f);
99 mDryMix.scaleInput(*mPanners[i], distScale);
100 } else { // rear half
101 float ratio = fabs(0.75f - az) * 4.0f; // scale 0 - 1
102 mFiltMix.scaleInput(*mPanners[i], (1.5f - ratio) * distScale);
103 mDryMix.scaleInput(*mPanners[i], ratio * distScale);
104 }
105 }
106 mOutMix.nextBuffer(outputBuffer); // now call the out mixer to run the graph
107 }
108
109 } // namespace