CSL 5.2

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

- File List
- File Members

DistanceSimulator.cpp
Go to the documentation of this file.
1 //
2 // DistanceSimulator.cpp -- Specification of the DistanceSimulators
3 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 // Created by Jorge Castellanos on 6/21/06. Hacked 8/09 by STP.
5 //
6
7 #include "DistanceSimulator.h"
8
9 using namespace csl;
10
11 // DistanceSimulator
12
13 DistanceSimulator::DistanceSimulator(UnitGenerator &source) : SpatialSource(source) {
14 this->addInput(CSL_INPUT, source);
15 mPosition = new CPoint(1.0, 0.0, 0.0); // If my parent is a simple UGen then I own my Position.
16 mIntensityCue = new IntensityAttenuationCue;
17 mAirAbsorptionCue = new AirAbsorptionCue;
18 }
19
20 DistanceSimulator::DistanceSimulator(SpatialSource &source) : SpatialSource(source) {
21 this->addInput(CSL_INPUT, source);
22 mPosition = source.position(); // If my parent is a SpatialSource, then just point to it.
23 mIntensityCue = new IntensityAttenuationCue;
24 mAirAbsorptionCue = new AirAbsorptionCue;
25 }
26
27 DistanceSimulator::~DistanceSimulator() {
28 delete mIntensityCue;
29 delete mAirAbsorptionCue;
30 }
31
32 /// Returns whether the sound source position changed since last block call.
33
34 bool DistanceSimulator::positionChanged() {
35 return ((SpatialSource *) mInputs[CSL_INPUT]->mUGen)->positionChanged();
36 }
37
38 // work-horse method
39
40 void DistanceSimulator::nextBuffer(Buffer & outputBuffer, unsigned outBufNum) throw (CException) {
41 float distance = this->distance(); // I call distance of myself, which in turn points to the source distance.
42 // coded this way, in order to allow UnitGenerators passed to a distance simulator.
43 Port *inPort = mInputs[CSL_INPUT];
44 UnitGenerator *inputSound = inPort->mUGen;
45
46 inputSound->nextBuffer(outputBuffer); // get its UGen
47
48 // UnitGenerator *soundSource = ((UGenPort *)mInputs[CSL_INPUT])->mUGen;
49 // soundSource->nextBuffer(outputBuffer);
50
51 mIntensityCue->compute(distance);
52 mIntensityCue->process(outputBuffer);
53 // Air damping at short distances (< than 10, 15 meters) can be ignored
54 if (distance > 10) {
55 mAirAbsorptionCue->compute(distance);
56 mAirAbsorptionCue->process(outputBuffer);
57 }
58 mPositionChanged = ((SpatialSource *) inputSound)->positionChanged();
59 }
60
61 // IntensityAttenuationCue
62
63 void IntensityAttenuationCue::compute(float distance) {
64 mGain = 1 / distance; //(distance * distance);
65 }
66
67 void IntensityAttenuationCue::process(Buffer &aBuffer) {
68 SampleBuffer outputPtr = aBuffer.buffer(0);
69 unsigned numFrames = aBuffer.mNumFrames;
70
71 for (unsigned k = 0; k < numFrames; k++) // k loops through sample buffers
72 *outputPtr++ *= mGain;
73 }
74
75 // AirAbsorptionCue
76
77 AirAbsorptionCue::AirAbsorptionCue() {
78 mPrevOutput = 0;
79 mPrevInput = 0;
80 }
81
82 AirAbsorptionCue::~AirAbsorptionCue() {
83
84 }
85
86 void AirAbsorptionCue::compute(float distance) {
87 unsigned frameRate = CGestalt::frameRate();
88 float cutoffFreq = 22000 * 9/distance;
89 float w = 2.0 * frameRate;
90 float Norm;
91
92 cutoffFreq *= 2.0F * CSL_PI;
93 Norm = 1.0 / (cutoffFreq + w);
94 mBCoeff = (w - cutoffFreq) * Norm;
95 mACoeff[0] = mACoeff[1] = cutoffFreq * Norm;
96 }
97
98
99 void AirAbsorptionCue::process(Buffer &aBuffer) {
100 SampleBuffer outputPtr = aBuffer.buffer(0);
101 unsigned numFrames = aBuffer.mNumFrames;
102
103 for (unsigned i = 0; i < numFrames; i++) {
104 mPrevOutput = (*outputPtr) * mACoeff[0] + mPrevInput * mACoeff[1] + mPrevOutput * mBCoeff;
105 mPrevInput = (*outputPtr);
106 *outputPtr++ = mPrevOutput;
107 }
108 }
109
110 // mBCoeff[0] = 1.0 - exp((-CSL_PI) * 2 * cutoffFreq/frameRate);
111 // mACoeff[0] = 1.0 - mBCoeff[0];
112 //
113
114 // prevOuts[0] = mBCoeff[0] * (*outputPtr) - mACoeff[0] * prevOuts[0]; // put current output sample in the output buffer and increment
115 // *outputPtr++ = prevOuts[0];
116
117
118 //AirAbsorptionCue::AirAbsorptionCue() {
119 //
120 //}
121 //
122 //AirAbsorptionCue::~AirAbsorptionCue() {
123 //
124 //}
125 //
126 //void AirAbsorptionCue::compute(float distance) {
127 // unsigned cutoffFreq = 10000;
128 // unsigned frameRate = CGestalt::frameRate();
129 // float C = 1 / (tan (CSL_PI * (cutoffFreq/frameRate)) );
130 //
131 // mBCoeff[0] = 1 / (1 + (CSL_SQRT_TWO * C) + (C * C) );
132 // mBCoeff[1] = 2 * mBCoeff[0];
133 // mBCoeff[2] = mBCoeff[0];
134 // mACoeff[0] = 0.f;
135 // mACoeff[1] = 2 * mBCoeff[0] * (1 - (C * C));
136 // mACoeff[2] = mBCoeff[0] * (1 - (CSL_SQRT_TWO * C) + (C * C) );
137 //}
138 //
139 //
140 //void AirAbsorptionCue::process(Buffer &aBuffer) {
141 // SampleBuffer outputPtr = aBuffer.buffer(0];
142 // unsigned numFrames = aBuffer.mNumFrames;
143 // float *prevOuts = mPrevOutputs;
144 // float *prevIns = mPrevInputs;
145 //
146 // for (unsigned i = 0; i < numFrames; i++) {
147 //
148 // prevOuts[0] = 0.f;
149 // prevIns[0] = *outputPtr; // get next input sample
150 // for (unsigned j = 2; j > 0; j--) {
151 // prevOuts[0] += mBCoeff[j] * prevIns[j];
152 // prevIns[j] = prevIns[j-1];
153 // }
154 // prevOuts[0] += mBCoeff[0] * prevIns[0];
155 // for (unsigned k = 2; k > 0; k--) {
156 // prevOuts[0] += -mACoeff[k] * prevOuts[k];
157 // prevOuts[k] = prevOuts[k-1];
158 // }
159 // *outputPtr++ = prevOuts[0]; // put current output sample in the output buffer and increment
160 // }
161 //
162 //}