New FAAC output driver
[jpcrr.git] / streamtools / output-drv-faac.cpp
blob8893056c75862021f25a8ee6ce773c2e9059cc01
1 #include "output-drv.hpp"
2 #include <cstdio>
3 #include <stdexcept>
4 #include <string>
5 #include <sstream>
7 namespace
9 std::string expand_options(const std::string& opts)
11 bool insert = true;
12 std::ostringstream ret;
13 for(size_t i = 0; i < opts.length(); i++) {
14 if(insert)
15 ret << " -";
16 insert = false;
17 switch(opts[i]) {
18 case ',':
19 insert = true;
20 break;
21 case '=':
22 ret << " ";
23 break;
24 default:
25 ret << opts[i];
28 ret << " ";
29 return ret.str();
32 class output_driver_faac : public output_driver
34 public:
35 output_driver_faac(const std::string& _filename, const std::string& _options)
37 filename = _filename;
38 options = _options;
39 set_audio_callback<output_driver_faac>(*this, &output_driver_faac::audio_callback);
42 ~output_driver_faac()
44 pclose(out);
47 void ready()
49 const audio_settings& a = get_audio_settings();
51 std::stringstream commandline;
52 commandline << "faac -P -C 2 -R " << a.get_rate() << " ";
53 commandline << expand_options(options);
54 commandline << "-o " << filename << " -";
55 std::string s = commandline.str();
56 out = popen(s.c_str(), "w");
57 if(!out) {
58 std::stringstream str;
59 str << "Can't run faac (" << s << ")";
60 throw std::runtime_error(str.str());
64 void audio_callback(short left, short right)
66 uint8_t rawdata[4];
67 rawdata[1] = ((unsigned short)left >> 8) & 0xFF;
68 rawdata[0] = ((unsigned short)left) & 0xFF;
69 rawdata[3] = ((unsigned short)right >> 8) & 0xFF;
70 rawdata[2] = ((unsigned short)right) & 0xFF;
71 if(fwrite(rawdata, 1, 4, out) < 4)
72 throw std::runtime_error("Error writing sample to faac");
74 private:
75 FILE* out;
76 std::string filename;
77 std::string options;
80 class output_driver_faac_factory : output_driver_factory
82 public:
83 output_driver_faac_factory()
84 : output_driver_factory("faac")
88 output_driver& make(const std::string& type, const std::string& name, const std::string& parameters)
90 return *new output_driver_faac(name, parameters);
92 } factory;