CSL 5.2

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

- File List
- File Members

SpatialAudio.cpp
Go to the documentation of this file.
1 //
2 // SpatialAudio.cpp -- Spatializer
3 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 // Created by Jorge Castellanos on 7/23/06. Hacked 8/09 by STP.
5 //
6 /// @todo Observe the layout for changes, just in case it's deleted, to grab the default, avoiding dangling pointers.
7
8 #include "SpatialAudio.h"
9 #include "SimplePanner.h"
10
11 #ifdef USE_VBAP
12 #include "VBAP.h"
13 #endif
14 #ifdef USE_AMBISONIC
15 #include "AmbisonicPanner.h"
16 #endif
17 #ifdef USE_HRTF
18 #include "Binaural.h"
19 #endif
20 #ifdef USE_WFS
21 #include "WFS.h"
22 #endif
23
24 using namespace csl;
25
26 Spatializer::Spatializer(PannerType panMode, SpeakerLayout *speakerLayout)
27 : UnitGenerator(), mPanner(NULL), mSpeakerLayout(speakerLayout) {
28 setCopyPolicy(kIgnore); // This is needed so the default kCopy doesn't overide
29 // the multiple channel panning done here.
30 setNumChannels(2);
31 setPanningMode(panMode);
32 }
33
34 Spatializer::~Spatializer() {
35 delete mPanner;
36 }
37
38 void Spatializer::addSource(SpatialSource &soundSource) {
39 // logMsg("Spatializer::addSource");
40 if (mType == kSimple) {
41 mPanner->addSource(soundSource); // Add the source to the panner.
42 } else { // create a new distance simulator passing it the source.
43 DistanceSimulator *distanceProcessor = new DistanceSimulator(soundSource);
44 mPanner->addSource(*distanceProcessor); // Add the source to the panner.
45 mInputsHashMap[&soundSource] = distanceProcessor; // Add the pointers to the map.
46 }
47 }
48
49 // delete from the list, shifting if necessary
50
51 void Spatializer::removeSource(SpatialSource &soundSource) {
52 #ifdef CSL_DEBUG
53 logMsg("Panner::removeSource");
54 #endif
55 SpatialSource *tempSourcePtr = mInputsHashMap[&soundSource];
56 if (tempSourcePtr) { // If not null then remove it form the panner.
57 mPanner->removeSource(*tempSourcePtr);
58 // now remove it from the map.
59 mInputsHashMap.erase(&soundSource);
60 } else {
61 mPanner->removeSource(soundSource);
62 }
63 }
64
65 void Spatializer::update(void * arg) {
66
67 }
68
69 void Spatializer::setPanningMode(PannerType panType) {
70 SpatialPanner *tempPanner; // Placeholder for the panner until everything is setup.
71 mType = panType;
72 if (mType == kAutomatic) {
73 // Call the panner expert system, so that it decides which panner to instantiate.
74 mType = kVBAP;
75 } else {
76 switch(mType) {
77 case kSimple:
78 tempPanner = new SimplePanner();
79 break;
80 #ifdef USE_HRTF
81 case kBinaural:
82 tempPanner = new BinauralPanner();
83 break;
84 #endif
85 #ifdef USE_VBAP
86 case kVBAP:
87 tempPanner = new VBAP(kPeriphonic, mSpeakerLayout);
88 break;
89 #endif
90 #ifdef USE_AMBISONIC
91 case kAmbisonic:
92 tempPanner = new AmbisonicPanner(1, mSpeakerLayout);
93 break;
94 #endif
95 #ifdef USE_WFS
96 case kWFS:
97 tempPanner = new WFSPanner(mSpeakerLayout);
98 break;
99 #endif
100 default:
101 logMsg(kLogWarning, "Unknown PannerMode Specified.");
102 setPanningMode(kAutomatic); // I call myself setting the mode to Automatic.
103 break;
104 }
105 }
106 // create an iterator to go thru all the sources.
107 map <SpatialSource *, DistanceSimulator *>::iterator idx;
108 // Add all the sources to the new panner
109 for (idx = mInputsHashMap.begin(); idx != mInputsHashMap.end(); ++idx)
110 tempPanner->addSource(*(idx->second));
111
112 // NOTE: This is not thread safe. In multithreaded apps, this could make it crash!
113 /// @todo make all spat framework thread safe.
114 // get rid of the old panner.
115 if (mPanner != NULL)
116 delete mPanner;
117 mPanner = tempPanner; // Assign the new panner.
118 }
119
120 // the method Spatializer::nextBuffer calls the panner
121
122 void Spatializer::nextBuffer(Buffer &outputBuffer /*, unsigned outBufNum */) throw(CException) {
123 #ifdef CSL_DEBUG
124 logMsg("Spatializer::nextBuffer");
125 #endif // Ask the decoder to fill the buffer with the data to be processed
126 outputBuffer.zeroBuffers();
127 mPanner->nextBuffer(outputBuffer);
128 }
129
130 PannerType SpeakerLayoutExpert::findPannerFromLayout(SpeakerLayout *layout) {
131 unsigned numSpeakers = layout->numSpeakers();
132 PannerType type = kVBAP; // Just default to something that always works.
133 switch(numSpeakers) {
134 case 0:
135 case 1:
136 logMsg("Not enough speakers to be spatialized");// throw an exception
137 break;
138 case 2:
139 // if headphones, then Binaural.
140 // otherwise for now use VBAP. At some point it could be used transaural.
141 type = kVBAP;
142 break;
143 case 3:
144 default:
145 type = kVBAP;
146 break;
147 }
148 return type;
149 }