From c72e5070ef7b0ce7687faa57f1eb0f4085892cf5 Mon Sep 17 00:00:00 2001 From: Andreas Eversberg Date: Sun, 30 Oct 2022 16:14:17 +0100 Subject: [PATCH] Add comfort noise when call is on hold This is required so that the RTP stream does not interrupt. --- src/isdn/dss1.c | 11 +++++++++-- src/isdn/isdn.c | 31 ++++++++++++++++++++++++++++++- src/isdn/isdn.h | 3 ++- src/isdn/main.c | 12 ++++++++++++ 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/isdn/dss1.c b/src/isdn/dss1.c index 3fd6653..4f46cfe 100644 --- a/src/isdn/dss1.c +++ b/src/isdn/dss1.c @@ -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); diff --git a/src/isdn/isdn.c b/src/isdn/isdn.c index 22e4758..3634cfb 100644 --- a/src/isdn/isdn.c +++ b/src/isdn/isdn.c @@ -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; + } +} diff --git a/src/isdn/isdn.h b/src/isdn/isdn.h index 1fab144..8fe2ad4 100644 --- a/src/isdn/isdn.h +++ b/src/isdn/isdn.h @@ -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); diff --git a/src/isdn/main.c b/src/isdn/main.c index 799f329..98f0b9d 100644 --- a/src/isdn/main.c +++ b/src/isdn/main.c @@ -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);