MumbleCommunicator.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include <cstring>
  2. #include <functional>
  3. #include "MumbleCommunicator.hpp"
  4. void mumble_serversync_callback(char *welcome_text,
  5. int32_t session,
  6. int32_t max_bandwidth,
  7. int64_t permissions,
  8. void *userData) {
  9. printf("%s\n", welcome_text);
  10. }
  11. static int verify_cert(uint8_t *, uint32_t) {
  12. // Accept every cert
  13. return 1;
  14. }
  15. void mumble::MumbleCommunicator::receiveAudioFrameCallback(uint8_t *audio_data, uint32_t audio_data_size) {
  16. int dataPointer = 1;
  17. opus_int16 pcmData[1024];
  18. if (audio_data[0] == 0x80) {
  19. int64_t sessionId;
  20. int64_t sequenceNumber;
  21. int64_t opusDataLength;
  22. bool lastPacket;
  23. dataPointer += mumble_parse_variant(&sessionId, &audio_data[dataPointer]);
  24. dataPointer += mumble_parse_variant(&sequenceNumber, &audio_data[dataPointer]);
  25. dataPointer += mumble_parse_variant(&opusDataLength, &audio_data[dataPointer]);
  26. lastPacket = (opusDataLength & 0x2000) != 0;
  27. opusDataLength = opusDataLength & 0x1fff;
  28. unsigned int iAudioBufferSize;
  29. unsigned int iFrameSize = mumble::SAMPLE_RATE / 100;
  30. iAudioBufferSize = iFrameSize;
  31. iAudioBufferSize *= 12;
  32. int decodedSamples = opus_decode(opusState,
  33. reinterpret_cast<const unsigned char *>(&audio_data[dataPointer]),
  34. opusDataLength,
  35. pcmData,
  36. iAudioBufferSize,
  37. 0);
  38. printf("\nsessionId: %ld, seqNum: %ld, opus data len: %ld, last: %d, pos: %ld, decoded: %d\n",
  39. sessionId, sequenceNumber, opusDataLength, lastPacket, dataPointer, decodedSamples);
  40. } else {
  41. printf("I received %d bytes of audio data\n", audio_data_size);
  42. }
  43. }
  44. static void mumble_audio_callback(uint8_t *audio_data, uint32_t audio_data_size, void *userData) {
  45. mumble::MumbleCommunicator *mumbleCommunicator = static_cast<mumble::MumbleCommunicator *>(userData);
  46. mumbleCommunicator->receiveAudioFrameCallback(audio_data, audio_data_size);
  47. }
  48. mumble::MumbleCommunicator::MumbleCommunicator(std::string user, std::string password, std::string host, int port) {
  49. opusState = opus_decoder_create(SAMPLE_RATE, 1, nullptr); //todo grab error
  50. struct mumble_config config;
  51. std::memset(&config, 0, sizeof(config));
  52. config.user_data = this;
  53. config.size = sizeof(config);
  54. config.host = const_cast<char *>(host.c_str());
  55. if (port > 0) {
  56. config.port = const_cast<char *>(std::to_string(port).c_str());
  57. }
  58. config.server_password = const_cast<char *>(password.c_str());
  59. config.username = const_cast<char *>(user.c_str());
  60. config.user_cert_filename = nullptr;
  61. config.user_privkey_filename = nullptr;
  62. config.ssl_verification_callback = verify_cert;
  63. config.audio_callback = mumble_audio_callback;
  64. config.serversync_callback = mumble_serversync_callback;
  65. mumble = mumble_connect(nullptr, &config);
  66. if (mumble == nullptr) {
  67. throw mumble::Exception("couldn't establish mumble connection");
  68. }
  69. }
  70. mumble::MumbleCommunicator::~MumbleCommunicator() {
  71. mumble_close(mumble);
  72. }
  73. void mumble::MumbleCommunicator::loop() {
  74. int quit = 0;
  75. while (quit == 0) {
  76. int status = mumble_tick(mumble);
  77. if (status < 0) {
  78. throw mumble::Exception("mumble_tick status " + status);
  79. }
  80. //todo Other processing here?
  81. }
  82. }