Add comfort noise when call is on hold

This is required so that the RTP stream does not interrupt.
This commit is contained in:
Andreas Eversberg 2022-10-30 16:14:17 +01:00
parent e8a91e12f9
commit c72e5070ef
4 changed files with 53 additions and 4 deletions

View File

@ -951,7 +951,9 @@ void hold_ind(call_t *call, uint32_t pid, struct l3_msg *l3m)
/* set hold state */
call->hold = 1;
#warning use clock to send empty packets/holdmusic
/* reset jitter buffer, to ignore packets coming from remote */
jitter_reset(&call->tx_dejitter);
/* acknowledge hold */
PDEBUG(DDSS1, DEBUG_INFO, "HOLD-ACKNOWLEDGE REQUEST (pid = 0x%x callref = %d)\n", pid, call->cc_callref);
@ -1066,7 +1068,9 @@ void suspend_ind(call_t *call, uint32_t pid, struct l3_msg *l3m)
new_state(call, ISDN_STATE_SUSPENDED);
memcpy(call->park_callid, callid, len);
call->park_len = len;
#warning use clock to send empty packets/holdmusic
/* reset jitter buffer, to ignore packets coming from remote */
jitter_reset(&call->tx_dejitter);
/* send message to osmo-cc */
osmo_cc_ll_msg(&call->isdn_ep->cc_ep, call->cc_callref, msg);
@ -1149,6 +1153,9 @@ void resume_ind(isdn_t *isdn_ep, uint32_t pid, struct l3_msg *l3m)
new_state(call, ISDN_STATE_CONNECT);
/* reset jitter buffer */
jitter_reset(&call->tx_dejitter);
/* send message to osmo-cc */
osmo_cc_ll_msg(&call->isdn_ep->cc_ep, call->cc_callref, msg);

View File

@ -1656,7 +1656,7 @@ void isdn_rtp_work(isdn_t *isdn_ep)
}
/* send audio from RTP to B-channel's jitter buffer */
void rtp_receive(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len)
void rtp_receive(struct osmo_cc_session_codec *codec, uint8_t __attribute__((unused)) marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len)
{
call_t *call = codec->media->session->priv;
@ -2140,3 +2140,32 @@ void isdn_bchannel_work(isdn_t *isdn_ep)
} while (w);
}
}
#define COMFORT_NOISE (0.02 * SPEECH_LEVEL) /* audio level of comfort noise (relative to ISDN level) */
void hold_clock(isdn_t *isdn_ep, int len)
{
call_t *call;
call = isdn_ep->call_list;
while (call) {
if ((call->state == ISDN_STATE_SUSPENDED || call->hold) && call->codec) {
int16_t noise[len];
uint8_t *data;
int i;
int16_t r;
for (i = 0; i < len; i++) {
r = random();
noise[i] = (double)r * COMFORT_NOISE;
}
if (call->isdn_ep->law == 'a')
g711_encode_alaw_flipped((uint8_t *)noise, len * 2, &data, &len);
else
g711_encode_ulaw_flipped((uint8_t *)noise, len * 2, &data, &len);
osmo_cc_rtp_send(call->codec, data, len, 0, 1, len);
free(data);
}
call = call->next;
}
}

View File

@ -208,5 +208,6 @@ void bchannel_bridge(call_t *call, int pcm_bridge, int rx_slot, int tx_slot, int
void bchannel_event(isdn_t *isdn_ep, int index, int event);
int seize_bchannel(call_t *call, int channel, int exclusive);
void drop_bchannel(call_t *call);
void rtp_receive(struct osmo_cc_session_codec *codec, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len);
void rtp_receive(struct osmo_cc_session_codec *codec, uint8_t marker, uint16_t sequence_number, uint32_t timestamp, uint32_t ssrc, uint8_t *data, int len);
void hold_clock(isdn_t *isdn_ep, int len);

View File

@ -307,6 +307,7 @@ static int mISDNlib_debug(const char *file, int line, const char *func, int __at
int main(int argc, char *argv[])
{
double last_time_call = 0, now;
int argi, rc;
int misdn_initialized = 0;
int ph_drv_initialized = 0;
@ -412,6 +413,17 @@ int main(int argc, char *argv[])
while (!quit) {
int w;
/* send clock calls to provide audio to suspended/helt calls */
now = get_time();
if (now - last_time_call >= 0.1)
last_time_call = now;
if (now - last_time_call >= 0.020) {
last_time_call += 0.020;
/* call hold-clock every 20ms */
hold_clock(isdn_ep, 160);
}
process_timer();
isdn_bchannel_work(isdn_ep);
isdn_rtp_work(isdn_ep);