PjsuaCommunicator.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #ifndef MUMSI_PJSUACOMMUNICATOR_HPP
  2. #define MUMSI_PJSUACOMMUNICATOR_HPP
  3. #include "ISamplesBuffer.hpp"
  4. #include <pjmedia.h>
  5. #include <string>
  6. #include <stdexcept>
  7. #include <log4cpp/Category.hh>
  8. #include <sndfile.hh>
  9. #include <mutex>
  10. #include <condition_variable>
  11. namespace sip {
  12. constexpr int DEFAULT_PORT = 5060;
  13. constexpr int SAMPLING_RATE = 48000;
  14. class Exception : public std::runtime_error {
  15. public:
  16. Exception(const char *title, pj_status_t status) : std::runtime_error(title) {
  17. char errorMsgBuffer[500];
  18. pj_strerror(status, errorMsgBuffer, sizeof(errorMsgBuffer));
  19. mesg += title;
  20. mesg += ": ";
  21. mesg += errorMsgBuffer;
  22. }
  23. virtual const char *what() const throw() {
  24. return mesg.c_str();
  25. }
  26. private:
  27. std::string mesg;
  28. };
  29. inline pj_str_t toPjString(std::string str) {
  30. return pj_str(const_cast<char *>(str.c_str()));
  31. }
  32. pj_status_t MediaPort_getFrameRawCallback(pjmedia_port *port, pjmedia_frame *frame);
  33. pj_status_t MediaPort_putFrameRawCallback(pjmedia_port *port, pjmedia_frame *frame);
  34. class PjsuaCommunicator : public ISamplesBuffer {
  35. public:
  36. PjsuaCommunicator();
  37. void connect(
  38. std::string host,
  39. std::string user,
  40. std::string password,
  41. unsigned int port = DEFAULT_PORT);
  42. ~PjsuaCommunicator();
  43. virtual void pushSamples(int16_t *samples, unsigned int length);
  44. std::function<void(int16_t *, int)> onIncomingSamples;
  45. // virtual unsigned int pullSamples(int16_t *samples, unsigned int length, bool waitWhenEmpty);
  46. private:
  47. log4cpp::Category &logger;
  48. log4cpp::Category &callbackLogger;
  49. pjmedia_port *mediaPort;
  50. pjmedia_circ_buf *inputBuff;
  51. pjmedia_circ_buf *outputBuff;
  52. std::mutex inBuffAccessMutex;
  53. std::mutex outBuffAccessMutex;
  54. std::condition_variable outBuffCondVar;
  55. // todo make it completely stateless
  56. pjmedia_port *createMediaPort();
  57. void registerAccount(std::string host,
  58. std::string user,
  59. std::string password);
  60. pj_status_t mediaPortGetFrame(pjmedia_frame *frame);
  61. void mediaPortPutFrame(pj_int16_t *samples, pj_size_t count);
  62. /**
  63. * For PJMEDIA implementation reasons, these callbacks have to be functions, not methods.
  64. * That is the reason to use 'friend'.
  65. */
  66. friend pj_status_t MediaPort_getFrameRawCallback(pjmedia_port *port,
  67. pjmedia_frame *frame);
  68. friend pj_status_t MediaPort_putFrameRawCallback(pjmedia_port *port,
  69. pjmedia_frame *frame);
  70. };
  71. }
  72. #endif //MUMSI_PJSUACOMMUNICATOR_HPP