Update the OpenAL Soft download
[alure.git] / examples / alure-stream.cpp
blob6306cb67f7cd50c5a35bbbafa4dddbcf9eb2eedf
1 /*
2 * A simple example showing how to stream a file through a source.
3 */
5 #include <iostream>
6 #include <sstream>
7 #include <iomanip>
8 #include <cstring>
9 #include <thread>
10 #include <chrono>
12 #include "alure2.h"
15 namespace {
17 // Helper class+method to print the time with human-readable formatting.
18 struct PrettyTime {
19 alure::Seconds mTime;
21 inline std::ostream &operator<<(std::ostream &os, const PrettyTime &rhs)
23 using hours = std::chrono::hours;
24 using minutes = std::chrono::minutes;
25 using seconds = std::chrono::seconds;
26 using centiseconds = std::chrono::duration<int64_t, std::ratio<1, 100>>;
27 using std::chrono::duration_cast;
29 centiseconds t = duration_cast<centiseconds>(rhs.mTime);
30 if(t.count() < 0)
32 os << '-';
33 t *= -1;
36 // Only handle up to hour formatting
37 if(t >= hours(1))
38 os << duration_cast<hours>(t).count() << 'h' << std::setfill('0') << std::setw(2)
39 << duration_cast<minutes>(t).count() << 'm';
40 else
41 os << duration_cast<minutes>(t).count() << 'm' << std::setfill('0');
42 os << std::setw(2) << (duration_cast<seconds>(t).count() % 60) << '.' << std::setw(2)
43 << (t.count() % 100) << 's' << std::setw(0) << std::setfill(' ');
44 return os;
47 } // namespace
49 int main(int argc, char *argv[])
51 alure::ArrayView<const char*> args(argv, argc);
53 if(args.size() < 2)
55 std::cerr<< "Usage: "<<args.front()<<" [-device \"device name\"] files..." <<std::endl;
56 return 1;
58 args = args.slice(1);
60 alure::DeviceManager devMgr = alure::DeviceManager::getInstance();
62 alure::Device dev;
63 if(args.size() > 2 && args[0] == alure::StringView("-device"))
65 dev = devMgr.openPlayback(args[1], std::nothrow);
66 if(!dev) std::cerr<< "Failed to open \""<<args[1]<<"\" - trying default" <<std::endl;
67 args = args.slice(2);
69 if(!dev) dev = devMgr.openPlayback();
70 std::cout<< "Opened \""<<dev.getName()<<"\"" <<std::endl;
72 alure::Context ctx = dev.createContext();
73 alure::Context::MakeCurrent(ctx);
75 for(;!args.empty();args = args.slice(1))
77 alure::SharedPtr<alure::Decoder> decoder = ctx.createDecoder(args.front());
78 alure::Source source = ctx.createSource();
80 source.play(decoder, 12000, 4);
81 std::cout<< "Playing "<<args.front()<<" ("
82 << alure::GetSampleTypeName(decoder->getSampleType())<<", "
83 << alure::GetChannelConfigName(decoder->getChannelConfig())<<", "
84 << decoder->getFrequency()<<"hz)" <<std::endl;
86 double invfreq = 1.0 / decoder->getFrequency();
87 while(source.isPlaying())
89 std::cout<< "\r "<<PrettyTime{source.getSecOffset()}<<" / "<<
90 PrettyTime{alure::Seconds(decoder->getLength()*invfreq)};
91 std::cout.flush();
92 std::this_thread::sleep_for(std::chrono::milliseconds(25));
93 ctx.update();
95 std::cout<<std::endl;
97 source.destroy();
100 alure::Context::MakeCurrent(nullptr);
101 ctx.destroy();
102 dev.close();
104 return 0;