CSL  5.2
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 
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 {
27  mOutMix.addInput(mReverb); // add processing paths to out mixer
28 
29  mOutMix.scaleInput(mDryMix, 0.4f); // scale out mix levels
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 
39  // no-op
40 }
41 
42 // Add a new source, creating the in-panner as a fan-out
43 
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 
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