static void sender_process(MSFilter * f) { SenderData *d = (SenderData *) f->data; RtpSession *s = d->session; mblk_t *im; uint32_t timestamp; if (s == NULL){ ms_queue_flush(f->inputs[0]); return; } if (d->relay_session_id_size>0 && ( (f->ticker->time-d->last_rsi_time)>5000 || d->last_rsi_time==0) ) { ms_message("relay session id sent in RTCP APP"); rtp_session_send_rtcp_APP(s,0,"RSID",(const uint8_t *)d->relay_session_id,d->relay_session_id_size); d->last_rsi_time=f->ticker->time; } while ((im = ms_queue_get(f->inputs[0])) != NULL) { mblk_t *header; timestamp = get_cur_timestamp(f, mblk_get_timestamp_info(im)); ms_filter_lock(f); if (d->skip) { ms_debug("skipping.."); send_dtmf(f, d->skip_until-d->dtmf_duration, timestamp); d->dtmf_start = FALSE; if (!RTP_TIMESTAMP_IS_NEWER_THAN(timestamp, d->skip_until)) { freemsg(im); ms_filter_unlock(f); continue; } d->skip = FALSE; d->dtmf = 0; } if (d->skip == FALSE && d->mute_mic==FALSE){ int pt = mblk_get_payload_type(im); header = rtp_session_create_packet(s, 12, NULL, 0); if (pt>0) rtp_set_payload_type(header, pt); rtp_set_markbit(header, mblk_get_marker_info(im)); header->b_cont = im; rtp_session_sendm_with_ts(s, header, timestamp); } else{ freemsg(im); } if (d->dtmf != 0) { ms_debug("prepare to send RFC2833 dtmf."); d->skip_until = timestamp + d->dtmf_duration; d->skip = TRUE; d->dtmf_start = TRUE; } ms_filter_unlock(f); } }
static void _sender_process(MSFilter * f) { SenderData *d = (SenderData *) f->data; RtpSession *s = d->session; mblk_t *im; uint32_t timestamp; if (d->relay_session_id_size>0 && ( (f->ticker->time-d->last_rsi_time)>5000 || d->last_rsi_time==0) ) { ms_message("relay session id sent in RTCP APP"); rtp_session_send_rtcp_APP(s,0,"RSID",(const uint8_t *)d->relay_session_id,d->relay_session_id_size); d->last_rsi_time=f->ticker->time; } ms_filter_lock(f); im = ms_queue_get(f->inputs[0]); do { mblk_t *header; timestamp = get_cur_timestamp(f, im); if (d->dtmf != 0 && !d->skip) { ms_debug("prepare to send RFC2833 dtmf."); d->skip_until = timestamp + d->dtmf_duration; d->dtmf_ts_cur=timestamp; d->skip = TRUE; } if (d->skip) { uint32_t origin_ts=d->skip_until-d->dtmf_duration; if (RTP_TIMESTAMP_IS_NEWER_THAN(timestamp,d->dtmf_ts_cur)){ ms_debug("Sending RFC2833 packet, start_timestamp=%u, dtmf_ts_cur=%u",origin_ts,d->dtmf_ts_cur); send_dtmf(f, origin_ts); } } if (im){ if (d->skip == FALSE && d->mute_mic==FALSE){ header = rtp_session_create_packet(s, 12, NULL, 0); rtp_set_markbit(header, mblk_get_marker_info(im)); header->b_cont = im; rtp_session_sendm_with_ts(s, header, timestamp); }else{ freemsg(im); } } }while ((im = ms_queue_get(f->inputs[0])) != NULL); if (d->last_sent_time == -1) { if ((d->last_stun_sent_time == -1) || ((f->ticker->time - d->last_stun_sent_time) >= 500)) { d->last_stun_sent_time = f->ticker->time; } if (d->last_stun_sent_time == f->ticker->time) { send_stun_packet(s); } } ms_filter_unlock(f); }
static void _sender_process(MSFilter * f) { SenderData *d = (SenderData *) f->data; RtpSession *s = d->session; mblk_t *im; uint32_t timestamp; if (d->relay_session_id_size>0 && ( (f->ticker->time-d->last_rsi_time)>5000 || d->last_rsi_time==0) ) { ms_message("relay session id sent in RTCP APP"); rtp_session_send_rtcp_APP(s,0,"RSID",(const uint8_t *)d->relay_session_id,d->relay_session_id_size); d->last_rsi_time=f->ticker->time; } ms_filter_lock(f); im = ms_queue_get(f->inputs[0]); do { mblk_t *header; timestamp = get_cur_timestamp(f, im); if (d->dtmf != 0 && !d->skip) { ms_debug("prepare to send RFC2833 dtmf."); d->skip_until = timestamp + d->dtmf_duration; d->dtmf_ts_cur=timestamp; d->skip = TRUE; } if (d->skip) { uint32_t origin_ts=d->skip_until-d->dtmf_duration; if (RTP_TIMESTAMP_IS_NEWER_THAN(timestamp,d->dtmf_ts_cur)){ ms_debug("Sending RFC2833 packet, start_timestamp=%u, dtmf_ts_cur=%u",origin_ts,d->dtmf_ts_cur); send_dtmf(f, origin_ts); } } if (im){ if (d->skip == FALSE && d->mute==FALSE){ header = rtp_session_create_packet(s, 12, NULL, 0); rtp_set_markbit(header, mblk_get_marker_info(im)); header->b_cont = im; mblk_meta_copy(im, header); rtp_session_sendm_with_ts(s, header, timestamp); } else if (d->mute==TRUE && d->skip == FALSE) { process_cn(f, d, timestamp, im); freemsg(im); //Send STUN packet as RTP keep alive check_stun_sending(f); }else{ freemsg(im); } } else if (d->skip == FALSE) { // Send STUN packet as RTP keep alive even if there is no input check_stun_sending(f); } }while ((im = ms_queue_get(f->inputs[0])) != NULL); if (d->last_sent_time == -1) { check_stun_sending(f); } /*every second, compute output bandwidth*/ if (f->ticker->time % 1000 == 0) rtp_session_compute_send_bandwidth(d->session); ms_filter_unlock(f); }
/***************************************************************************** * \brief Signal processing * TODO: Add signal processing modules * TODO: Add on/off setting for each module * \parameters * \return None *****************************************************************************/ void true_voice(tvRxChannels_t rx, tvMicChannels_t mic, tvTxChannels_t tx, tvSpeakerChannels_t ls) { //VAD for LMR //init Elmr, bSpeechLMR, timer bLMRVadOverride // energy_vad(rx.psLmr, &q15Elmr, &bSpeechLMR, &timer_LMR_VAD); // if(bLMRVadOverride == true){ // bSpeechLMR = 1; // } // if(bSpeechLMR == false){ // memset(rx.psLmr, 0, sizeof(q15)*BUFLEN_8KHZ); // } // clock_t t_start, t_stop, t_overhead; // t_start = clock(); // t_stop = clock(); // t_overhead = t_stop - t_start; // t_start = clock(); /*** Microphone noise reduction ***/ if(tvSettings.platform == TV_CONFIG_BS){ vadSettings.bVadStatus[NOIRED_MIC_CH_TECH] = nr_damp(mic.psTechHeadset, mic.psMicNoise, &nr_status[NOIRED_MIC_CH_TECH], vadSettings.bVadOverride[NOIRED_MIC_CH_TECH], vadSettings.sVadSensitivity[NOIRED_MIC_CH_TECH]); vadSettings.bVadStatus[NOIRED_MIC_CH_PILOT] = nr_damp(mic.psPilotHeadset, mic.psMicNoise, &nr_status[NOIRED_MIC_CH_PILOT], vadSettings.bVadOverride[NOIRED_MIC_CH_PILOT], vadSettings.sVadSensitivity[NOIRED_MIC_CH_PILOT]); } else if(tvSettings.platform == TV_CONFIG_CA){ vadSettings.bVadStatus[NOIRED_MIC_CH_TECH] = nr_damp(mic.psTechHeadset, mic.psMicNoise, &nr_status[NOIRED_MIC_CH_TECH], vadSettings.bVadOverride[NOIRED_MIC_CH_TECH], vadSettings.sVadSensitivity[NOIRED_MIC_CH_TECH]); vadSettings.bVadStatus[NOIRED_MIC_CH_PILOT] = nr_damp(mic.psPilotHeadset, mic.psMicNoise, &nr_status[NOIRED_MIC_CH_PILOT], vadSettings.bVadOverride[NOIRED_MIC_CH_PILOT], vadSettings.sVadSensitivity[NOIRED_MIC_CH_PILOT]); } else if(tvSettings.platform == TV_CONFIG_PT){ // I think that pilot channel should be input? vadSettings.bVadStatus[0] = nr_damp(mic.psTechHeadset, mic.psMicNoise, &nr_status[NOIRED_MIC_CH_PILOT], vadSettings.bVadOverride[NOIRED_MIC_CH_PILOT], vadSettings.sVadSensitivity[NOIRED_MIC_CH_PILOT]); } // t_stop = clock(); // printf("Noise reduction took: %f ms\n", (t_stop-t_start-t_overhead)/300E6*1000); //Enable clock first while in debug: Run->Clock->Enable /*** Microphone and LMR channel AGC ***/ // agc(input buffer, struct with agc settings for this channel) agc(mic.psTechHeadset, &agcTech); if(tvSettings.platform == TV_CONFIG_BS || tvSettings.platform == TV_CONFIG_CA){ agc(mic.psPilotHeadset, &agcPilot); } if(tvSettings.platform == TV_CONFIG_BS){ agc(rx.psLmr, &agcLmr); } /*** Pilot switch ***/ // Calculate what state the pilot switch is in (1st tech or CLT). pilot_switch(mic.psPilotCable, mic.psPilotCltCable); /*** CLT/FTN channels LEC ***/ //tx.psCltToLine, tx.psFtnToLine is reference signals to be able to cancel the echo lec(rx.psClt2wire, rx.psClt4wire, tx.psCltToLine, tx.psFtnToLine, rx.psClt, rx.psFtn); /*** Pre mixer ***/ // Pre mixer of technician and ftn so lec can be made on pilot-technician cable // Provide mixer with pointers to audio signals pre_mixer_channel_setup(rx, mic, tx, ls); pre_aircraft_mixer(); /*** Pilot-Tech cable connection LEC ***/ // insert LEC for pilot Tech Cable connection. Only needed when pilot in aircraft choose // to talk to technician i.e when tvSettings.bPilotSwitch = 1. // mic.psPilotCable = (Pilot+CLT+1st tech (+FTN)), ls.psPilotMonoCable = 1st tech (+FTN) // lec to remove 1st tech (+FTN) from mic.psPilotCable if (tvSettings.bPilotSwitch){ lec_aircraft_cable(mic.psPilotCable, ls.psPilotMonoCable); } /*** DTMF tones ***/ // Send to line only on BS. Send to LS on PT as well? if(tvSettings.platform == TV_CONFIG_BS){ send_dtmf(DTMFset.psDTMFbuffer,DTMFqueue, &DTMFset); send_dtmf(DTMFsetLs.psDTMFbuffer,DTMFqueueLs, &DTMFsetLs); } else if(tvSettings.platform == TV_CONFIG_PT){ send_dtmf(DTMFsetLs.psDTMFbuffer,DTMFqueueLs, &DTMFsetLs); } /*** Channel mixer ***/ // Create pilot microphone signals from the processed headset signal or from one of the aircraft cables. Output to rx.psPilot (not on PT) pilot_channel_selection(mic.psPilotHeadset, mic.psPilotCable, mic.psPilotCltCable, rx.psPilot); // Provide mixer with pointers to audio signals mixer_channel_setup(rx, mic, tx, ls); // Creates mono output speaker signals and five channels that serve as input to directive audio. Line output signals are also created mixer(); /*** Directive audio ***/ // Create stereo signal from the five channels created in mixer() directive_audio(ls.psTechLeft, ls.psTechRight); /*** Volume and limiter adjustment on LS ***/ // Add side tone, dtmf and MMI (since it has a fixed volume setting) if(tvSettings.platform == TV_CONFIG_PT) { // volume damping ls channels volume(ls.psTechLeft, volumeSet.q15volumeTech); volume(ls.psTechRight, volumeSet.q15volumeTech); // volume damping sidetone, DTMF and MMI volume(rx.psMmiSounds, volumeSet.q15volumeMMI); volume(mic.psTechHeadset, volumeSet.q15volumeTechSidetone); volume(DTMFsetLs.psDTMFbuffer, volumeSet.q15volumeDTMF); // Add sidetone, dtmf and MMI to ls signal //TODO: Dtmf only if first tech. But empty if not making a call so maybe this is ok? add_sidetone_dtmf_mmi(mic.psTechHeadset,DTMFsetLs.psDTMFbuffer,rx.psMmiSounds, ls.psTechLeft, &limiterLsLeft); add_sidetone_dtmf_mmi(mic.psTechHeadset,DTMFsetLs.psDTMFbuffer,rx.psMmiSounds, ls.psTechRight, &limiterLsRight); } else if(tvSettings.platform == TV_CONFIG_BS) { // volume damping ls channels volume(ls.psTechMono, volumeSet.q15volumeTech); volume(ls.psPilotMono, volumeSet.q15volumePilot); // volume damping sidetone, dtmf and mmi volume(rx.psPilot, volumeSet.q15volumePilotSidetone); volume(rx.psMmiSounds, volumeSet.q15volumeMMI); volume(mic.psTechHeadset, volumeSet.q15volumeTechSidetone); volume(DTMFsetLs.psDTMFbuffer, volumeSet.q15volumeDTMF); // Add sidetone, dtmf and mmi to ls signal add_sidetone_dtmf_mmi(mic.psTechHeadset,DTMFsetLs.psDTMFbuffer,rx.psMmiSounds, ls.psTechMono, &limiterLsTechMono); // rx.psPilot should only be put in ls.psPilotMono if pilot is connected with headset to CA/BS. // If connected with aircraft cable No sidetone and MMI and DTMF should be generated. if (tvSettings.bPilotConnection == HEADSET) { add_sidetone_dtmf_mmi(rx.psPilot,DTMFsetLs.psDTMFbuffer, rx.psMmiSounds, ls.psPilotMono, &limiterLsPilotMono); } } else if(tvSettings.platform == TV_CONFIG_CA) { // volume damping ls volume(ls.psTechLeft, volumeSet.q15volumeTech); volume(ls.psTechRight, volumeSet.q15volumeTech); volume(ls.psPilotMono, volumeSet.q15volumePilot); // volume damping sidetone volume(rx.psPilot, volumeSet.q15volumePilotSidetone); volume(rx.psMmiSounds, volumeSet.q15volumeMMI); volume(mic.psTechHeadset, volumeSet.q15volumeTechSidetone); // Add sidetone and mmi to ls signal add_sidetone_mmi(mic.psTechHeadset, rx.psMmiSounds, ls.psTechLeft, &limiterLsLeft_CA); add_sidetone_mmi(mic.psTechHeadset, rx.psMmiSounds, ls.psTechRight, &limiterLsRight_CA); // rx.psPilot should only be put in ls.psPilotMono if pilot is connected with headset to CA/BS. // If connected with aircraft cable No sidetone and MMI and DTMF should be generated. if (tvSettings.bPilotConnection == HEADSET) { add_sidetone_mmi(rx.psPilot, rx.psMmiSounds, ls.psPilotMono, &limiterLsPilotMono_CA); } } #ifdef USE_DUMPDATA dumpdata_post_dump(); #endif }