Use a more sane streaming buffer length
[alure.git] / examples / alure-hrtf.cpp
blob18240688e2f9108b09a17bdb0fe52a6ab15e028f
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 <sstream>
9 #include <iomanip>
10 #include <cstring>
11 #include <thread>
12 #include <chrono>
14 #include "alure2.h"
15 #include "alext.h"
17 int main(int argc, char *argv[])
19 alure::DeviceManager &devMgr = alure::DeviceManager::get();
21 int fileidx = 1;
22 alure::Device dev = [argc,argv,&devMgr,&fileidx]() -> alure::Device
24 if(argc > 3 && strcmp(argv[1], "-device") == 0)
26 fileidx = 3;
27 try {
28 return devMgr.openPlayback(argv[2]);
30 catch(...) {
31 std::cerr<< "Failed to open \""<<argv[2]<<"\" - trying default" <<std::endl;
34 return devMgr.openPlayback();
35 }();
36 std::cout<< "Opened \""<<dev.getName()<<"\"" <<std::endl;
38 if(!dev.queryExtension("ALC_SOFT_HRTF"))
40 std::cerr<< "ALC_SOFT_HRTF not supported!" <<std::endl;
41 return 1;
44 // Enumerate (and display) the available HRTFs
45 std::cout<< "Available HRTFs:\n";
46 alure::Vector<alure::String> hrtf_names = dev.enumerateHRTFNames();
47 for(const alure::String &name : hrtf_names)
48 std::cout<< " "<<name <<'\n';
49 std::cout.flush();
51 int i = fileidx;
52 alure::Vector<alure::AttributePair> attrs;
53 attrs.push_back({ALC_HRTF_SOFT, ALC_TRUE});
54 if(argc-i > 1 && strcasecmp(argv[i], "-hrtf") == 0)
56 // Find the given HRTF and add it to the attributes list
57 auto iter = std::find(hrtf_names.begin(), hrtf_names.end(), argv[i+1]);
58 if(iter == hrtf_names.end())
59 std::cerr<< "HRTF \""<<argv[i+1]<<"\" not found" <<std::endl;
60 else
61 attrs.push_back({ALC_HRTF_ID_SOFT, std::distance(hrtf_names.begin(), iter)});
62 i += 2;
64 attrs.push_back({0,0});
65 alure::Context ctx = dev.createContext(attrs);
66 alure::Context::MakeCurrent(ctx);
68 std::cout<< "Using HRTF \""<<dev.getCurrentHRTF()<<"\"" <<std::endl;
70 for(;i < argc;i++)
72 if(argc-i > 1 && strcasecmp(argv[i], "-hrtf") == 0)
74 // Find the given HRTF and reset the device using it
75 auto iter = std::find(hrtf_names.begin(), hrtf_names.end(), argv[i+1]);
76 if(iter == hrtf_names.end())
77 std::cerr<< "HRTF \""<<argv[i+1]<<"\" not found" <<std::endl;
78 else
80 std::array<alure::AttributePair,3> attrs{{
81 {ALC_HRTF_SOFT, ALC_TRUE},
82 {ALC_HRTF_ID_SOFT, std::distance(hrtf_names.begin(), iter)},
83 {0, 0}
84 }};
85 dev.reset(attrs);
86 std::cout<< "Using HRTF \""<<dev.getCurrentHRTF()<<"\"" <<std::endl;
89 ++i;
90 continue;
93 alure::SharedPtr<alure::Decoder> decoder(ctx.createDecoder(argv[i]));
94 alure::Source source = ctx.createSource();
96 source.play(decoder, 12000, 4);
97 std::cout<< "Playing "<<argv[i]<<" ("<<alure::GetSampleTypeName(decoder->getSampleType())<<", "
98 <<alure::GetChannelConfigName(decoder->getChannelConfig())<<", "
99 <<decoder->getFrequency()<<"hz)" <<std::endl;
101 float invfreq = 1.0f / decoder->getFrequency();
102 while(source.isPlaying())
104 std::cout<< "\r "<<std::setiosflags(std::ios::fixed)<<std::setprecision(2)<<
105 (source.getOffset()*invfreq)<<" / "<<(decoder->getLength()*invfreq);
106 std::cout.flush();
107 std::this_thread::sleep_for(std::chrono::milliseconds(25));
108 ctx.update();
110 std::cout<<std::endl;
112 source.release();
115 alure::Context::MakeCurrent(nullptr);
116 ctx.destroy();
117 dev.close();
119 return 0;