diff --git a/src/public_api/include/roc/config.h b/src/public_api/include/roc/config.h index 4335e7bfe..38efb2b69 100644 --- a/src/public_api/include/roc/config.h +++ b/src/public_api/include/roc/config.h @@ -569,8 +569,8 @@ typedef enum roc_resampler_backend { * stage is needed, and this becomes fastest possible backend working almost as fast * as memcpy(). * - * When frame and packet rates are different, usage of this backend compared to - * \c ROC_RESAMPLER_BACKEND_SPEEX allows to sacrify some quality, but somewhat + * When frame and packet rates are different, usage of this backend, compared to + * \c ROC_RESAMPLER_BACKEND_SPEEX, allows to sacrify some quality, but somewhat * improve scaling precision and CPU usage in return. * * This backend is available only when SpeexDSP was enabled at build time. @@ -600,6 +600,33 @@ typedef enum roc_resampler_profile { ROC_RESAMPLER_PROFILE_LOW = 3 } roc_resampler_profile; +/** PLC backend. + * + * Packet loss concealment (PLC), is used to reduce distortion caused by lost + * packets by filling gaps with interpolated or extrapolated data. + * + * PLC is used when a packet was lost and FEC was not able to recover it. + */ +typedef enum roc_plc_backend { + /** No PLC. + * Gaps are filled with zeros (silence). + */ + ROC_PLC_BACKEND_DISABLE = -1, + + /** Default backend. + * Current default is \c ROC_PLC_BACKEND_DISABLE. + */ + ROC_PLC_BACKEND_DEFAULT = 0, + + /** Dummy "beep" backend. + * Gaps are filled with a sine wave to produce loud beep. + * This backend makes losses very audible instead of masking them. + * Useful for debugging to distinguish packet losses from distortion + * caused by I/O on sender or receiver. + */ + ROC_PLC_BACKEND_BEEP = -2, +} roc_plc_backend; + /** Context configuration. * * It is safe to memset() this struct with zeros to get a default config. It is also @@ -854,6 +881,13 @@ typedef struct roc_receiver_config { */ roc_resampler_profile resampler_profile; + /** PLC backend. + * Allows to reduce distortion cased by packet loss. + * + * If zero, default backend is used (\ref ROC_PLC_BACKEND_DEFAULT). + */ + roc_plc_backend plc_backend; + /** Target latency, in nanoseconds. * * How latency is calculated depends on \c latency_tuner_backend field. diff --git a/src/public_api/src/adapters.cpp b/src/public_api/src/adapters.cpp index 805846c6d..4a4560d4f 100644 --- a/src/public_api/src/adapters.cpp +++ b/src/public_api/src/adapters.cpp @@ -230,6 +230,13 @@ bool receiver_config_from_user(node::Context&, return false; } + if (!plc_backend_from_user(out.session_defaults.plc.backend, in.plc_backend)) { + roc_log(LogError, + "bad configuration: invalid roc_receiver_config.plc_backend:" + " should be valid enum value"); + return false; + } + return true; } @@ -472,6 +479,25 @@ bool resampler_profile_from_user(audio::ResamplerProfile& out, roc_resampler_pro return false; } +ROC_ATTR_NO_SANITIZE_UB +bool plc_backend_from_user(audio::PlcBackend& out, roc_plc_backend in) { + switch (enum_from_user(in)) { + case ROC_PLC_BACKEND_DISABLE: + out = audio::PlcBackend_None; + return true; + + case ROC_PLC_BACKEND_DEFAULT: + out = audio::PlcBackend_Default; + return true; + + case ROC_PLC_BACKEND_BEEP: + out = audio::PlcBackend_Beep; + return true; + } + + return false; +} + ROC_ATTR_NO_SANITIZE_UB bool packet_encoding_from_user(unsigned& out_pt, roc_packet_encoding in) { switch (enum_from_user(in)) { diff --git a/src/public_api/src/adapters.h b/src/public_api/src/adapters.h index 1cf27fab4..b0ae87515 100644 --- a/src/public_api/src/adapters.h +++ b/src/public_api/src/adapters.h @@ -53,6 +53,8 @@ bool latency_tuner_profile_from_user(audio::LatencyTunerProfile& out, bool resampler_backend_from_user(audio::ResamplerBackend& out, roc_resampler_backend in); bool resampler_profile_from_user(audio::ResamplerProfile& out, roc_resampler_profile in); +bool plc_backend_from_user(audio::PlcBackend& out, roc_plc_backend in); + bool packet_encoding_from_user(unsigned& out_pt, roc_packet_encoding in); bool fec_encoding_from_user(packet::FecScheme& out, roc_fec_encoding in);