mode2_decode.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // Quick and dirty tool to decode mode2 data from LIRC
  2. // Copyright 2018 Brett T. Warden
  3. // based on c2_decode.cpp, Copyright 2017 Jorge Cisneros
  4. // Usage example:
  5. // mode2 -H udp -d 5000 | ./mode2_decode
  6. /* Sample input (alternating space and pulse durations in microseconds):
  7. space 500000
  8. pulse 915
  9. space 793
  10. pulse 488
  11. space 366
  12. pulse 915
  13. space 793
  14. pulse 427
  15. space 500000
  16. */
  17. #include <errno.h>
  18. #include <inttypes.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <iostream>
  22. #include <sstream>
  23. #include <string>
  24. #include "IRsend.h"
  25. #include "IRsend_test.h"
  26. #include "IRutils.h"
  27. const uint16_t kMaxGcCodeLength = 10000;
  28. void str_to_uint16(char *str, uint16_t *res, uint8_t base) {
  29. char *end;
  30. errno = 0;
  31. intmax_t val = strtoimax(str, &end, base);
  32. if (errno == ERANGE || val < 0 || val > UINT16_MAX || end == str ||
  33. *end != '\0')
  34. return;
  35. *res = (uint16_t)val;
  36. }
  37. void usage_error(char *name) {
  38. std::cerr << "Usage: " << name << " [-raw]" << std::endl;
  39. }
  40. int main(int argc, char *argv[]) {
  41. bool dumpraw = false;
  42. // Check the invocation/calling usage.
  43. if (argc > 2) {
  44. usage_error(argv[0]);
  45. return 1;
  46. }
  47. if (argc == 2 && strncmp("-raw", argv[1], 4) == 0) {
  48. dumpraw = true;
  49. }
  50. int index = 0;
  51. std::string line, type;
  52. std::string pulse = "pulse";
  53. std::string space = "space";
  54. int duration;
  55. IRsendTest irsend(4);
  56. IRrecv irrecv(4);
  57. irsend.begin();
  58. irsend.reset();
  59. while (getline(std::cin, line)) {
  60. std::istringstream iss1(line);
  61. iss1 >> type;
  62. iss1 >> duration;
  63. // Clamp duration to int16_t
  64. if (duration > 0xFFFF) {
  65. duration = 0xFFFF;
  66. }
  67. if (pulse.compare(type) == 0) {
  68. irsend.mark(duration);
  69. } else if (space.compare(type) == 0) {
  70. irsend.space(duration);
  71. }
  72. index++;
  73. if (duration > 20000 || index >= kMaxGcCodeLength) {
  74. // Skip long spaces at beginning
  75. if (index > 1) {
  76. irsend.makeDecodeResult();
  77. irrecv.decode(&irsend.capture);
  78. std::cout << "Code length " << index << std::endl
  79. << "Code type " << irsend.capture.decode_type << " ("
  80. << typeToString(irsend.capture.decode_type) << ")"
  81. << std::endl
  82. << "Code bits " << irsend.capture.bits << std::endl;
  83. if (hasACState(irsend.capture.decode_type)) {
  84. std::cout << "State value 0x";
  85. for (uint16_t i = 0; i < irsend.capture.bits / 8; i++)
  86. printf("%02X", irsend.capture.state[i]);
  87. std::cout << std::endl;
  88. } else {
  89. std::cout << "Code value 0x" << std::hex << irsend.capture.value
  90. << std::endl
  91. << "Code address 0x" << std::hex << irsend.capture.address
  92. << std::endl
  93. << "Code command 0x" << std::hex << irsend.capture.command
  94. << std::endl;
  95. }
  96. if (dumpraw || irsend.capture.decode_type == UNKNOWN)
  97. irsend.dumpRawResult();
  98. }
  99. irsend.reset();
  100. index = 0;
  101. }
  102. }
  103. return 0;
  104. }