📄 audiortp.cpp
字号:
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 + -