⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audiortp.cpp

📁 sip 开源代码 源于novell sip 开源代码 源于novell
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    AudioCodec* audiocodec = _ca->getAudioCodec();    if (!audiocodec) { _debug(" !ARTP: No audiocodec available for mic\n"); return; }    // we have to get 20ms of data from the mic *20/1000 = /50    // rate/50 shall be lower than RTP_20S_48KHZ_MAX    int maxBytesToGet = audiolayer->getSampleRate()/50*sizeof(SFLDataFormat);    // available bytes inside ringbuffer    int availBytesFromMic = audiolayer->canGetMic();    // take the lower    int bytesAvail = (availBytesFromMic < maxBytesToGet) ? availBytesFromMic : maxBytesToGet;    //_debug("available = %d, maxBytesToGet = %d\n", availBytesFromMic, maxBytesToGet);    // Get bytes from micRingBuffer to data_from_mic    int nbSample = audiolayer->getMic(_dataAudioLayer, bytesAvail) / sizeof(SFLDataFormat);    int16* toSIP = 0;    if (audiolayer->getSampleRate() != audiocodec->getClockRate() && nbSample) {       SRC_DATA src_data;       #ifdef DATAFORMAT_IS_FLOAT             src_data.data_in = _dataAudioLayer;       #else          src_short_to_float_array(_dataAudioLayer, _floatBuffer48000, nbSample);          src_data.data_in = _floatBuffer48000;        #endif       double factord = (double)audiocodec->getClockRate()/audiolayer->getSampleRate();       src_data.src_ratio = factord;       src_data.input_frames = nbSample;       src_data.output_frames = RTP_20S_8KHZ_MAX;       src_data.data_out = _floatBuffer8000;       src_simple (&src_data, SRC_SINC_BEST_QUALITY/*SRC_SINC_MEDIUM_QUALITY*/, 1); // 1 = channel       nbSample = src_data.output_frames_gen;       //if (nbSample > RTP_20S_8KHZ_MAX) { _debug("Alert from mic, nbSample %d is bigger than expected %d\n", nbSample, RTP_20S_8KHZ_MAX); }       src_float_to_short_array (_floatBuffer8000, _intBuffer8000, nbSample);       toSIP = _intBuffer8000;    } else {      #ifdef DATAFORMAT_IS_FLOAT        // convert _receiveDataDecoded to float inside _receiveData        src_float_to_short_array(_dataAudioLayer, _intBuffer8000, nbSample);        toSIP = _intBuffer8000;       //if (nbSample > RTP_20S_8KHZ_MAX) { _debug("Alert from mic, nbSample %d is bigger than expected %d\n", nbSample, RTP_20S_8KHZ_MAX); }      #else        toSIP = _dataAudioLayer; // int to int      #endif    }    if ( nbSample < (RTP_20S_8KHZ_MAX - 10) ) { // if only 10 is missing, it's ok      // fill end with 0...      //_debug("begin: %p, nbSample: %d\n", toSIP, nbSample);      //_debug("has to fill: %d chars at %p\n", (RTP_20S_8KHZ_MAX-nbSample)*sizeof(int16), toSIP + nbSample);      memset(toSIP + nbSample, 0, (RTP_20S_8KHZ_MAX-nbSample)*sizeof(int16));      nbSample = RTP_20S_8KHZ_MAX;    }    //_debug("AR: Nb sample: %d int, [0]=%d [1]=%d [2]=%d\n", nbSample, toSIP[0], toSIP[1], toSIP[2]);    // for the mono: range = 0 to RTP_FRAME2SEND * sizeof(int16)    // codecEncode(char *dest, int16* src, size in bytes of the src)    int compSize = audiocodec->codecEncode(_sendDataEncoded, toSIP, nbSample*sizeof(int16));    // encode divise by two    // Send encoded audio sample over the network    if (compSize > RTP_20S_8KHZ_MAX) { _debug("! ARTP: %d should be %d\n", compSize, RTP_20S_8KHZ_MAX);}    if (!_sym) {      _sessionSend->putData(timestamp, _sendDataEncoded, compSize);    } else {      _session->putData(timestamp, _sendDataEncoded, compSize);    }    toSIP = 0;  } catch(...) {    _debugException("! ARTP: sending failed");    throw;  }}voidAudioRtpRTX::receiveSessionForSpkr (int& countTime){  if (_ca == 0) { return; }  try {    AudioLayer* audiolayer = Manager::instance().getAudioDriver();    if (!audiolayer) { return; }    const ost::AppDataUnit* adu = NULL;    // Get audio data stream    if (!_sym) {      adu = _sessionRecv->getData(_sessionRecv->getFirstTimestamp());    } else {      adu = _session->getData(_session->getFirstTimestamp());    }    if (adu == NULL) {      return;    }    int payload = adu->getType(); // codec type    unsigned char* data  = (unsigned char*)adu->getData(); // data in char    unsigned int size    = adu->getSize(); // size in char    if ( size > RTP_20S_8KHZ_MAX ) {      _debug("We have received from RTP a packet larger than expected: %s VS %s\n", size, RTP_20S_8KHZ_MAX);      _debug("The packet size has been cropped\n");      size=RTP_20S_8KHZ_MAX;    }    // Decode data with relevant codec    AudioCodec* audiocodec = _ca->getCodecMap().getCodec((CodecType)payload);    if (audiocodec != 0) {      // codecDecode(int16 *dest, char* src, size in bytes of the src)      // decode multiply by two, so the number of byte should be double      // size shall be RTP_FRAME2SEND or lower      int expandedSize = audiocodec->codecDecode(_receiveDataDecoded, data, size);      int nbInt16      = expandedSize/sizeof(int16);      if (nbInt16 > RTP_20S_8KHZ_MAX) {        _debug("We have decoded a RTP packet larger than expected: %s VS %s. crop\n", nbInt16, RTP_20S_8KHZ_MAX);        nbInt16=RTP_20S_8KHZ_MAX;      }      SFLDataFormat* toAudioLayer;      int nbSample = nbInt16;      int nbSampleMaxRate = nbInt16 * 6; // TODO: change it      if ( audiolayer->getSampleRate() != audiocodec->getClockRate() && nbSample) {        // convert here        double         factord = (double)audiolayer->getSampleRate()/audiocodec->getClockRate();        SRC_DATA src_data;        src_data.data_in = _floatBuffer8000;        src_data.data_out = _floatBuffer48000;        src_data.input_frames = nbSample;        src_data.output_frames = nbSampleMaxRate;        src_data.src_ratio = factord;        src_short_to_float_array(_receiveDataDecoded, _floatBuffer8000, nbSample);        src_simple (&src_data, SRC_SINC_BEST_QUALITY/*SRC_SINC_MEDIUM_QUALITY*/, 1); // 1=mono channel               nbSample = ( src_data.output_frames_gen > RTP_20S_48KHZ_MAX) ? RTP_20S_48KHZ_MAX : src_data.output_frames_gen;        #ifdef DATAFORMAT_IS_FLOAT          toAudioLayer = _floatBuffer48000;	#else          src_float_to_short_array(_floatBuffer48000, _dataAudioLayer, nbSample);	  toAudioLayer = _dataAudioLayer;	#endif	      } else {        nbSample = nbInt16;        #ifdef DATAFORMAT_IS_FLOAT      	  // convert _receiveDataDecoded to float inside _receiveData          src_short_to_float_array(_receiveDataDecoded, _floatBuffer8000, nbSample);	  toAudioLayer = _floatBuffer8000;        #else	  toAudioLayer = _receiveDataDecoded; // int to int        #endif      }      audiolayer->putMain(toAudioLayer, nbSample * sizeof(SFLDataFormat));      //_debug("ARTP: %d\n", nbSample * sizeof(SFLDataFormat));      // Notify (with a beep) an incoming call when there is already a call       countTime += time->getSecond();      if (Manager::instance().incomingCallWaiting() > 0) {        countTime = countTime % 500; // more often...        if (countTime == 0) {          Manager::instance().notificationIncomingCall();        }      }    } else {      countTime += time->getSecond();    }    delete adu; adu = NULL;  } catch(...) {    _debugException("! ARTP: receiving failed");    throw;  }}voidAudioRtpRTX::run () {  //mic, we receive from soundcard in stereo, and we send encoded  //encoding before sending  AudioLayer *audiolayer = Manager::instance().getAudioDriver();  try {    // Init the session    initAudioRtpSession();    // start running the packet queue scheduler.    //_debug("AudioRTP Thread started\n");    if (!_sym) {      _sessionRecv->startRunning();      _sessionSend->startRunning();    } else {      _session->startRunning();      //_debug("Session is now: %d active\n", _session->isActive());    }    int timestamp = 0; // for mic    int countTime = 0; // for receive    // TODO: get frameSize from user config     int frameSize = 20; // 20ms frames    TimerPort::setTimer(frameSize);    audiolayer->flushMic();    audiolayer->startStream();    _start.post();    _debug("- ARTP Action: Start\n");    while (!testCancel()) {      ////////////////////////////      // Send session      ////////////////////////////      sendSessionFromMic(timestamp);      timestamp += RTP_20S_8KHZ_MAX;      ////////////////////////////      // Recv session      ////////////////////////////      receiveSessionForSpkr(countTime);      // Let's wait for the next transmit cycle      Thread::sleep(TimerPort::getTimer());      TimerPort::incTimer(frameSize); // 'frameSize' ms    }    //_debug("stop stream for audiortp loop\n");    audiolayer->stopStream();  } catch(std::exception &e) {    _start.post();    _debug("! ARTP: Stop %s\n", e.what());    throw;  } catch(...) {    _start.post();    _debugException("* ARTP Action: Stop");    throw;  }}// EOF

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -