Update some comment docs about thread-local contexts
[alure.git] / examples / alure-hrtf.cpp
blobf19ffc1b82cf5e5d6fbd480706a4f63e4f55d791
1 #ifdef _WIN32
2 #define WIN32_LEAN_AND_MEAN
3 #include <windows.h>
4 #else
5 #include <errno.h>
6 #include <time.h>
7 #include <stdint.h>
8 inline void Sleep(uint32_t ms)
10 struct timespec ts, rem;
11 ts.tv_sec = ms / 1000;
12 ts.tv_nsec = (ms % 1000) * 1000000;
13 while(nanosleep(&ts, &rem) == -1 && errno == EINTR)
14 ts = rem;
16 #endif
18 #include <algorithm>
19 #include <iostream>
20 #include <sstream>
21 #include <iomanip>
22 #include <cstring>
24 #include "alure2.h"
25 #include "alext.h"
27 int main(int argc, char *argv[])
29 alure::DeviceManager *devMgr = alure::DeviceManager::get();
31 alure::Device *dev = devMgr->openPlayback();
32 std::cout<< "Opened \""<<dev->getName(alure::PlaybackDevType_Basic)<<"\"" <<std::endl;
34 if(!dev->queryExtension("ALC_SOFT_HRTF"))
36 std::cerr<< "ALC_SOFT_HRTF not supported!" <<std::endl;
37 return 1;
40 // Enumerate (and display) the available HRTFs
41 std::cout<< "Available HRTFs:" <<std::endl;
42 std::vector<std::string> hrtf_names = dev->enumerateHRTFNames();
43 for(const std::string &name : hrtf_names)
44 std::cout<< " "<<name <<std::endl;
46 int i = 1;
47 std::vector<ALCint> attrs;
48 attrs.push_back(ALC_HRTF_SOFT);
49 attrs.push_back(ALC_TRUE);
50 if(argc-i > 1 && strcasecmp(argv[i], "-hrtf") == 0)
52 // Find the given HRTF and add it to the attributes list
53 auto iter = std::find_if(hrtf_names.begin(), hrtf_names.end(),
54 [argv, i](const std::string &name) -> bool
55 { return name == argv[i+1]; }
57 if(iter == hrtf_names.end())
58 std::cerr<< "HRTF \""<<argv[i+1]<<"\" not found" <<std::endl;
59 else
61 attrs.push_back(ALC_HRTF_ID_SOFT);
62 attrs.push_back(std::distance(hrtf_names.begin(), iter));
64 i += 2;
66 attrs.push_back(0);
67 alure::Context *ctx = dev->createContext(attrs.data());
68 alure::Context::MakeCurrent(ctx);
70 std::cout<< "Using HRTF \""<<dev->getCurrentHRTF()<<"\"" <<std::endl;
72 for(;i < argc;i++)
74 if(argc-i > 1 && strcasecmp(argv[i], "-hrtf") == 0)
76 // Find the given HRTF and reset the device using it
77 auto iter = std::find_if(hrtf_names.begin(), hrtf_names.end(),
78 [argv, i](const std::string &name) -> bool
79 { return name == argv[i+1]; }
81 if(iter == hrtf_names.end())
82 std::cerr<< "HRTF \""<<argv[i+1]<<"\" not found" <<std::endl;
83 else
85 attrs.clear();
86 attrs.push_back(ALC_HRTF_SOFT);
87 attrs.push_back(ALC_TRUE);
88 attrs.push_back(ALC_HRTF_ID_SOFT);
89 attrs.push_back(std::distance(hrtf_names.begin(), iter));
90 dev->reset(attrs.data());
92 std::cout<< "Using HRTF \""<<dev->getCurrentHRTF()<<"\"" <<std::endl;
95 ++i;
96 continue;
99 alure::SharedPtr<alure::Decoder> decoder(ctx->createDecoder(argv[i]));
100 alure::Source *source = ctx->getSource();
102 source->play(decoder, 32768, 4);
103 std::cout<< "Playing "<<argv[i]<<" ("<<alure::GetSampleTypeName(decoder->getSampleType())<<", "
104 <<alure::GetChannelConfigName(decoder->getChannelConfig())<<", "
105 <<decoder->getFrequency()<<"hz)" <<std::endl;
107 float invfreq = 1.0f / decoder->getFrequency();
108 while(source->isPlaying())
110 std::cout<< "\r "<<std::setiosflags(std::ios::fixed)<<std::setprecision(2)<<
111 (source->getOffset()*invfreq)<<" / "<<(decoder->getLength()*invfreq);
112 std::cout.flush();
113 Sleep(25);
114 ctx->update();
116 std::cout<<std::endl;
118 source->release();
119 source = 0;
122 alure::Context::MakeCurrent(0);
123 ctx->destroy();
124 ctx = 0;
125 dev->close();
126 dev = 0;
128 return 0;