44#include < iostream>
55#include < functional>
66#include < map>
7+ #include < ranges>
78#include < sstream>
9+ #include < string_view>
810
911
1012namespace Denon {
@@ -27,6 +29,7 @@ const std::map<std::string, Surround> gSurround = {
2729 {" STEREO" , Surround::Stereo},
2830 {" STANDARD" , Surround::Standard},
2931 {" DOLBY AUDIO-DD+DSUR" , Surround::DolbyDigital},
32+ {" DOLBY AUDIO-DD+ +NEURAL:X" , Surround::DolbyDigitalNeuralX},
3033 {" M CH IN+DSUR" , Surround::DtsSurround},
3134};
3235
@@ -87,6 +90,16 @@ const std::map<std::string, SoundMode> gSoundMode = {
8790};
8891
8992
93+ const std::map<std::string, DrcMode> gDynamicRangeControl = {
94+ {" AUTO" , DrcMode::Auto},
95+ {" LOW" , DrcMode::Low},
96+ {" MID" , DrcMode::Mid},
97+ {" HI" , DrcMode::Hi},
98+ {" OFF" , DrcMode::Off},
99+ };
100+
101+
102+
90103template <typename Enum>
91104std::string lu (const std::map<std::string, Enum>& lut, Enum v)
92105{
@@ -109,13 +122,12 @@ std::ostream& operator<<(std::ostream& os, Surround s)
109122}
110123
111124
112- void ParseResponse (std::string_view line , Response& response)
125+ void ParseResponse (std::string_view lines , Response& response)
113126{
114- if (line .size () < 3 )
127+ if (lines .size () < 3 )
115128 return ;
116129
117- // std::string cmd = str.substr(0,2);
118- std::string param = std::string (line.substr (2 , line.size ()-3 ));
130+ std::string param;
119131
120132 const std::map<std::string, std::function<void (void )>> handlers = {
121133 {" BT" , [&]()
@@ -133,7 +145,7 @@ void ParseResponse(std::string_view line, Response& response)
133145 {" MU" , [&](){ response.OnMute (param == " ON" ); }},
134146 {" MV" , [&]()
135147 {
136- if (!startswith (line , " MVMAX " ))
148+ if (!startswith (param , " MAX " ))
137149 {
138150 int vol = std::stoi (param);
139151 if (vol > 100 )
@@ -153,7 +165,7 @@ void ParseResponse(std::string_view line, Response& response)
153165 }},
154166 {" SS" , [&]()
155167 {
156- if (line == " SSINFAISFSV " )
168+ if (param == " INFAISFSV " )
157169 {
158170 std::string sr = param.substr (10 );
159171 if (sr == " 441" )
@@ -180,6 +192,12 @@ void ParseResponse(std::string_view line, Response& response)
180192 {
181193 response.OnCinemaEq (param == " CINEMA EQ.ON" );
182194 }
195+ else if (startswith (param, " DRC" ))
196+ {
197+ auto val = param.substr (4 );
198+ if (gDynamicRangeControl .count (val))
199+ response.OnDynamicRangeControl (gDynamicRangeControl .at (val));
200+ }
183201 if (startswith (param, " LFE" ))
184202 {
185203 int val = std::stoi (param.substr (4 ));
@@ -197,8 +215,8 @@ void ParseResponse(std::string_view line, Response& response)
197215 }
198216 else if (startswith (param, " ROOM" ))
199217 {
200- std::string_view eq = line .substr (10 );
201- // std::cout << "ROOM EQ : '" << eq << "'\n";
218+ std::string_view eq = param .substr (8 );
219+ std::cout << " ROOM EQ : '" << eq << " '\n " ;
202220 }
203221 else if (startswith (param, " DYNEQ" ))
204222 {
@@ -211,22 +229,41 @@ void ParseResponse(std::string_view line, Response& response)
211229 if (gDynamicVolume .count (val))
212230 response.OnDynamicVolume (gDynamicVolume .at (val));
213231 }
232+ else if (startswith (param, " MODE" ))
233+ {
234+ auto val = param.substr (std::string_view (" MODE" ).size () + 1 );
235+ std::cout << " MODE : '" << val << " '\n " ;
236+ }
214237 else if (startswith (param, " MULTEQ:" ))
215238 {
216239 auto val = param.substr (7 );
217240 if (gRoomEq .count (val))
218241 response.OnMultiEq (gRoomEq .at (val));
219242 }
243+ else if (startswith (param, " TONE" ))
244+ {
245+ auto val = param.substr (std::string_view (" TONE" ).size () + 1 );
246+ }
220247 }},
221248 {" ZM" , [&](){ response.OnPower (param == " ON" ); }},
222249 };
223250
224- for (auto & h: handlers)
251+ std::string cmd;
252+ for (auto line: lines | std::views::split (' \r ' ))
225253 {
226- if ( startswith ( line, h. first ))
254+ for ( auto cmd_r : line | std::views::split ( ' , ' ))
227255 {
228- h.second ();
229- break ;
256+ if (cmd_r.size () < 3 ) continue ;
257+ cmd.assign (std::begin (cmd_r), std::end (cmd_r)); // cmd_r is contiguous, but the view-types don't know that.
258+ param = cmd.substr (2 );
259+ for (auto & h: handlers)
260+ {
261+ if (startswith (cmd, h.first ))
262+ {
263+ h.second ();
264+ break ;
265+ }
266+ }
230267 }
231268 }
232269}
@@ -252,6 +289,7 @@ void Command::RequestStatus()
252289 " PSDYNEQ ?\r "
253290 " PSDYNVOL ?\r "
254291 " PSCINEMA EQ. ?\r "
292+ " PSMODE: ?\r "
255293 " PSMULTEQ: ?\r "
256294 " ECO?\r "
257295 " SSSMG ?\r "
@@ -308,6 +346,12 @@ void Command::DynamicVolume(Denon::DynamicVolume v)
308346}
309347
310348
349+ void Command::DynamicRangeControl (DrcMode v)
350+ {
351+ pConn->Send (" PSDRC " + lu (gDynamicRangeControl , v) + " \r " );
352+ }
353+
354+
311355void Command::CinemaEq (bool v)
312356{
313357 pConn->Send (v ? " PSCINEMA EQ.ON\r " : " PSCINEMA EQ.OFF\r " );
@@ -328,8 +372,12 @@ void Command::EcoMode(Denon::EcoMode e)
328372
329373void Command::SoundMode (Denon::SoundMode m)
330374{
331- // This doesn't seem to do it:
332- // pConn->Send("SSSMG " + lu(gSoundMode, m) + "\r");
375+ // This doesn't seem to do it, neither with ':' or without ' '
376+ /* pConn->Send("SSSMG" + lu(gSoundMode, m) + "\r");
377+ pConn->Send("SSSMG:" + lu(gSoundMode, m) + "\r");
378+ pConn->Send("SSSMG " + lu(gSoundMode, m) + "\r");
379+ pConn->Send("SSSMG: " + lu(gSoundMode, m) + "\r");
380+ */
333381}
334382
335383
0 commit comments