Avoid unnecessary templates
[alure.git] / examples / alure-hrtf.cpp
blob42f000542b47834df72a62e88a71938117409473
1 /*
2 * An example showing how to enable HRTF rendering, using the ALC_SOFT_HRTF
3 * extension.
4 */
6 #include <algorithm>
7 #include <iostream>
8 #include <iomanip>
9 #include <cstring>
10 #include <thread>
11 #include <chrono>
13 #include "alure2.h"
15 int main(int argc, char *argv[])
17 alure::DeviceManager devMgr = alure::DeviceManager::getInstance();
19 int fileidx = 1;
20 alure::Device dev;
21 if(argc > 3 && strcmp(argv[1], "-device") == 0)
23 fileidx = 3;
24 dev = devMgr.openPlayback(argv[2], std::nothrow);
25 if(!dev)
26 std::cerr<< "Failed to open \""<<argv[2]<<"\" - trying default" <<std::endl;
28 if(!dev)
29 dev = devMgr.openPlayback();
30 std::cout<< "Opened \""<<dev.getName()<<"\"" <<std::endl;
32 // Enumerate (and display) the available HRTFs
33 alure::Vector<alure::String> hrtf_names = dev.enumerateHRTFNames();
34 if(hrtf_names.empty())
35 std::cout<< "No HRTFs found!\n";
36 else
38 std::cout<< "Available HRTFs:\n";
39 for(const alure::String &name : hrtf_names)
40 std::cout<< " "<<name <<'\n';
42 std::cout.flush();
44 alure::Vector<alure::AttributePair> attrs;
45 attrs.push_back({ALC_HRTF_SOFT, ALC_TRUE});
46 if(argc-fileidx > 1 && alure::StringView("-hrtf") == argv[fileidx])
48 // Find the given HRTF and add it to the attributes list
49 alure::StringView hrtf_name = argv[fileidx+1];
50 fileidx += 2;
52 size_t idx = std::distance(
53 hrtf_names.begin(), std::find(hrtf_names.begin(), hrtf_names.end(), hrtf_name)
55 if(idx == hrtf_names.size())
56 std::cerr<< "HRTF \""<<hrtf_name<<"\" not found" <<std::endl;
57 else
58 attrs.push_back({ALC_HRTF_ID_SOFT, static_cast<ALint>(idx)});
60 attrs.push_back(alure::AttributesEnd());
61 alure::Context ctx = dev.createContext(attrs);
62 alure::Context::MakeCurrent(ctx);
64 if(dev.isHRTFEnabled())
65 std::cout<< "Using HRTF \""<<dev.getCurrentHRTF()<<"\"" <<std::endl;
66 else
67 std::cout<< "HRTF not enabled!" <<std::endl;
69 for(int i = fileidx;i < argc;i++)
71 if(argc-i > 1 && alure::StringView("-hrtf") == argv[i])
73 // Find the given HRTF and reset the device using it
74 alure::StringView hrtf_name = argv[i+1];
75 size_t idx = std::distance(
76 hrtf_names.begin(), std::find(hrtf_names.begin(), hrtf_names.end(), hrtf_name)
78 if(idx == hrtf_names.size())
79 std::cerr<< "HRTF \""<<hrtf_name<<"\" not found" <<std::endl;
80 else
82 alure::Array<alure::AttributePair,3> attrs{{
83 {ALC_HRTF_SOFT, ALC_TRUE},
84 {ALC_HRTF_ID_SOFT, static_cast<ALint>(idx)},
85 alure::AttributesEnd()
86 }};
87 dev.reset(attrs);
88 if(dev.isHRTFEnabled())
89 std::cout<< "Using HRTF \""<<dev.getCurrentHRTF()<<"\"" <<std::endl;
90 else
91 std::cout<< "HRTF not enabled!" <<std::endl;
94 ++i;
95 continue;
98 alure::SharedPtr<alure::Decoder> decoder(ctx.createDecoder(argv[i]));
99 alure::Source source = ctx.createSource();
101 source.play(decoder, 12000, 4);
102 std::cout<< "Playing "<<argv[i]<<" ("<<alure::GetSampleTypeName(decoder->getSampleType())<<", "
103 <<alure::GetChannelConfigName(decoder->getChannelConfig())<<", "
104 <<decoder->getFrequency()<<"hz)" <<std::endl;
106 float invfreq = 1.0f / decoder->getFrequency();
107 while(source.isPlaying())
109 std::cout<< "\r "<<std::fixed<<std::setprecision(2)<<
110 source.getSecOffset().count()<<" / "<<(decoder->getLength()*invfreq);
111 std::cout.flush();
112 std::this_thread::sleep_for(std::chrono::milliseconds(25));
113 ctx.update();
115 std::cout<<std::endl;
117 source.release();
120 alure::Context::MakeCurrent(nullptr);
121 ctx.destroy();
122 dev.close();
124 return 0;