Use remove_if to clean up loaded future buffers
[alure.git] / examples / alure-reverb.cpp
blob866e2bdbca83bbb0e1465a356ab4b13fe7701ad6
1 /*
2 * An example showing how to load and apply a reverb effect to a source.
3 */
5 #include <algorithm>
6 #include <iostream>
7 #include <iomanip>
8 #include <cstring>
9 #include <thread>
10 #include <chrono>
12 #include "alure2.h"
14 #include "efx-presets.h"
16 template<typename T, size_t N>
17 static inline size_t countof(const T(&)[N])
18 { return N; }
20 #define DECL(x) { #x, EFX_REVERB_PRESET_##x }
21 static const struct ReverbEntry {
22 const char name[32];
23 EFXEAXREVERBPROPERTIES props;
24 } reverblist[] = {
25 DECL(GENERIC),
26 DECL(PADDEDCELL),
27 DECL(ROOM),
28 DECL(BATHROOM),
29 DECL(LIVINGROOM),
30 DECL(STONEROOM),
31 DECL(AUDITORIUM),
32 DECL(CONCERTHALL),
33 DECL(CAVE),
34 DECL(ARENA),
35 DECL(HANGAR),
36 DECL(CARPETEDHALLWAY),
37 DECL(HALLWAY),
38 DECL(STONECORRIDOR),
39 DECL(ALLEY),
40 DECL(FOREST),
41 DECL(CITY),
42 DECL(MOUNTAINS),
43 DECL(QUARRY),
44 DECL(PLAIN),
45 DECL(PARKINGLOT),
46 DECL(SEWERPIPE),
47 DECL(UNDERWATER),
48 DECL(DRUGGED),
49 DECL(DIZZY),
50 DECL(PSYCHOTIC),
52 DECL(CASTLE_SMALLROOM),
53 DECL(CASTLE_SHORTPASSAGE),
54 DECL(CASTLE_MEDIUMROOM),
55 DECL(CASTLE_LARGEROOM),
56 DECL(CASTLE_LONGPASSAGE),
57 DECL(CASTLE_HALL),
58 DECL(CASTLE_CUPBOARD),
59 DECL(CASTLE_COURTYARD),
60 DECL(CASTLE_ALCOVE),
62 DECL(FACTORY_SMALLROOM),
63 DECL(FACTORY_SHORTPASSAGE),
64 DECL(FACTORY_MEDIUMROOM),
65 DECL(FACTORY_LARGEROOM),
66 DECL(FACTORY_LONGPASSAGE),
67 DECL(FACTORY_HALL),
68 DECL(FACTORY_CUPBOARD),
69 DECL(FACTORY_COURTYARD),
70 DECL(FACTORY_ALCOVE),
72 DECL(ICEPALACE_SMALLROOM),
73 DECL(ICEPALACE_SHORTPASSAGE),
74 DECL(ICEPALACE_MEDIUMROOM),
75 DECL(ICEPALACE_LARGEROOM),
76 DECL(ICEPALACE_LONGPASSAGE),
77 DECL(ICEPALACE_HALL),
78 DECL(ICEPALACE_CUPBOARD),
79 DECL(ICEPALACE_COURTYARD),
80 DECL(ICEPALACE_ALCOVE),
82 DECL(SPACESTATION_SMALLROOM),
83 DECL(SPACESTATION_SHORTPASSAGE),
84 DECL(SPACESTATION_MEDIUMROOM),
85 DECL(SPACESTATION_LARGEROOM),
86 DECL(SPACESTATION_LONGPASSAGE),
87 DECL(SPACESTATION_HALL),
88 DECL(SPACESTATION_CUPBOARD),
89 DECL(SPACESTATION_ALCOVE),
91 DECL(WOODEN_SMALLROOM),
92 DECL(WOODEN_SHORTPASSAGE),
93 DECL(WOODEN_MEDIUMROOM),
94 DECL(WOODEN_LARGEROOM),
95 DECL(WOODEN_LONGPASSAGE),
96 DECL(WOODEN_HALL),
97 DECL(WOODEN_CUPBOARD),
98 DECL(WOODEN_COURTYARD),
99 DECL(WOODEN_ALCOVE),
101 DECL(SPORT_EMPTYSTADIUM),
102 DECL(SPORT_SQUASHCOURT),
103 DECL(SPORT_SMALLSWIMMINGPOOL),
104 DECL(SPORT_LARGESWIMMINGPOOL),
105 DECL(SPORT_GYMNASIUM),
106 DECL(SPORT_FULLSTADIUM),
107 DECL(SPORT_STADIUMTANNOY),
109 DECL(PREFAB_WORKSHOP),
110 DECL(PREFAB_SCHOOLROOM),
111 DECL(PREFAB_PRACTISEROOM),
112 DECL(PREFAB_OUTHOUSE),
113 DECL(PREFAB_CARAVAN),
115 DECL(DOME_TOMB),
116 DECL(PIPE_SMALL),
117 DECL(DOME_SAINTPAULS),
118 DECL(PIPE_LONGTHIN),
119 DECL(PIPE_LARGE),
120 DECL(PIPE_RESONANT),
122 DECL(OUTDOORS_BACKYARD),
123 DECL(OUTDOORS_ROLLINGPLAINS),
124 DECL(OUTDOORS_DEEPCANYON),
125 DECL(OUTDOORS_CREEK),
126 DECL(OUTDOORS_VALLEY),
128 DECL(MOOD_HEAVEN),
129 DECL(MOOD_HELL),
130 DECL(MOOD_MEMORY),
132 DECL(DRIVING_COMMENTATOR),
133 DECL(DRIVING_PITGARAGE),
134 DECL(DRIVING_INCAR_RACER),
135 DECL(DRIVING_INCAR_SPORTS),
136 DECL(DRIVING_INCAR_LUXURY),
137 DECL(DRIVING_FULLGRANDSTAND),
138 DECL(DRIVING_EMPTYGRANDSTAND),
139 DECL(DRIVING_TUNNEL),
141 DECL(CITY_STREETS),
142 DECL(CITY_SUBWAY),
143 DECL(CITY_MUSEUM),
144 DECL(CITY_LIBRARY),
145 DECL(CITY_UNDERPASS),
146 DECL(CITY_ABANDONED),
148 DECL(DUSTYROOM),
149 DECL(CHAPEL),
150 DECL(SMALLWATERROOM),
152 #undef DECL
155 int main(int argc, char *argv[])
157 alure::DeviceManager devMgr = alure::DeviceManager::get();
159 int fileidx = 1;
160 alure::Device dev;
161 if(argc > 3 && strcmp(argv[1], "-device") == 0)
163 fileidx = 3;
164 dev = devMgr.openPlayback(argv[2], std::nothrow);
165 if(!dev)
166 std::cerr<< "Failed to open \""<<argv[2]<<"\" - trying default" <<std::endl;
168 if(!dev)
169 dev = devMgr.openPlayback();
170 std::cout<< "Opened \""<<dev.getName()<<"\"" <<std::endl;
172 alure::Context ctx = dev.createContext();
173 alure::Context::MakeCurrent(ctx);
175 bool gotreverb = false;
176 alure::Effect effect = ctx.createEffect();
178 if(argc-fileidx >= 2 && strcasecmp(argv[fileidx], "-preset") == 0)
180 const char *reverb_name = argv[fileidx+1];
181 fileidx += 2;
183 auto iter = std::find_if(std::begin(reverblist), std::end(reverblist),
184 [reverb_name](const ReverbEntry &entry) -> bool
185 { return strcasecmp(reverb_name, entry.name) == 0; }
187 if(iter != std::end(reverblist))
189 std::cout<< "Loading preset "<<iter->name <<std::endl;
190 effect.setReverbProperties(iter->props);
191 gotreverb = true;
194 if(!gotreverb)
196 std::cout<< "Loading generic preset" <<std::endl;
197 effect.setReverbProperties(EFX_REVERB_PRESET_GENERIC);
200 alure::AuxiliaryEffectSlot auxslot = ctx.createAuxiliaryEffectSlot();
201 auxslot.applyEffect(effect);
203 for(int i = fileidx;i < argc;i++)
205 alure::SharedPtr<alure::Decoder> decoder(ctx.createDecoder(argv[i]));
206 alure::Source source = ctx.createSource();
208 source.setAuxiliarySend(auxslot, 0);
210 source.play(decoder, 12000, 4);
211 std::cout<< "Playing "<<argv[i]<<" ("<<alure::GetSampleTypeName(decoder->getSampleType())<<", "
212 <<alure::GetChannelConfigName(decoder->getChannelConfig())<<", "
213 <<decoder->getFrequency()<<"hz)" <<std::endl;
215 float invfreq = 1.0f / decoder->getFrequency();
216 while(source.isPlaying())
218 std::cout<< "\r "<<std::setiosflags(std::ios::fixed)<<std::setprecision(2)<<
219 source.getSecOffset().count()<<" / "<<(decoder->getLength()*invfreq);
220 std::cout.flush();
221 std::this_thread::sleep_for(std::chrono::milliseconds(25));
222 ctx.update();
224 std::cout<<std::endl;
226 source.release();
227 decoder.reset();
230 auxslot.release();
231 effect.destroy();
233 alure::Context::MakeCurrent(nullptr);
234 ctx.destroy();
235 dev.close();
237 return 0;