mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-04 09:42:19 +00:00
netsim: Add gamma distribution for delay
This simulates the delay on wifi networks better.
This commit is contained in:
parent
531b1e326f
commit
c9002e3dd5
2 changed files with 69 additions and 9 deletions
|
@ -43,6 +43,7 @@ distribution_get_type (void)
|
||||||
static const GEnumValue values[] = {
|
static const GEnumValue values[] = {
|
||||||
{DISTRIBUTION_UNIFORM, "uniform", "uniform"},
|
{DISTRIBUTION_UNIFORM, "uniform", "uniform"},
|
||||||
{DISTRIBUTION_NORMAL, "normal", "normal"},
|
{DISTRIBUTION_NORMAL, "normal", "normal"},
|
||||||
|
{DISTRIBUTION_GAMMA, "gamma", "gamma"},
|
||||||
{0, NULL, NULL}
|
{0, NULL, NULL}
|
||||||
};
|
};
|
||||||
GType g_define_type_id =
|
GType g_define_type_id =
|
||||||
|
@ -226,20 +227,17 @@ get_random_value_uniform (GRand * rand_seed, gint32 min_value, gint32 max_value)
|
||||||
return g_rand_int_range (rand_seed, min_value, max_value + 1);
|
return g_rand_int_range (rand_seed, min_value, max_value + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate a value from a normal distributation with 95% confidense interval
|
/* Use the Box-Muller transform. */
|
||||||
* between LOW and HIGH, using the Box-Muller transform. */
|
static gdouble
|
||||||
static gint
|
random_value_normal (GRand * rand_seed, gdouble mu, gdouble sigma,
|
||||||
get_random_value_normal (GRand * rand_seed, gint32 low, gint32 high,
|
|
||||||
NormalDistributionState * state)
|
NormalDistributionState * state)
|
||||||
{
|
{
|
||||||
gdouble u1, u2, t1, t2;
|
gdouble u1, u2, t1, t2;
|
||||||
gdouble mu = (high + low) / 2.0;
|
|
||||||
gdouble sigma = (high - low) / (2 * 1.96); /* 95% confidence interval */
|
|
||||||
|
|
||||||
state->generate = !state->generate;
|
state->generate = !state->generate;
|
||||||
|
|
||||||
if (!state->generate)
|
if (!state->generate)
|
||||||
return round (state->z1 * sigma + mu);
|
return state->z1 * sigma + mu;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
u1 = g_rand_double (rand_seed);
|
u1 = g_rand_double (rand_seed);
|
||||||
|
@ -251,7 +249,64 @@ get_random_value_normal (GRand * rand_seed, gint32 low, gint32 high,
|
||||||
state->z0 = t1 * cos (t2);
|
state->z0 = t1 * cos (t2);
|
||||||
state->z1 = t1 * sin (t2);
|
state->z1 = t1 * sin (t2);
|
||||||
|
|
||||||
return round (state->z0 * sigma + mu);
|
return state->z0 * sigma + mu;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate a value from a normal distributation with 95% confidense interval
|
||||||
|
* between LOW and HIGH */
|
||||||
|
static gint
|
||||||
|
get_random_value_normal (GRand * rand_seed, gint32 low, gint32 high,
|
||||||
|
NormalDistributionState * state)
|
||||||
|
{
|
||||||
|
gdouble mu = (high + low) / 2.0;
|
||||||
|
gdouble sigma = (high - low) / (2 * 1.96); /* 95% confidence interval */
|
||||||
|
gdouble z = random_value_normal (rand_seed, mu, sigma, state);
|
||||||
|
|
||||||
|
return round (z);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Marsaglia and Tsang's method */
|
||||||
|
static gdouble
|
||||||
|
random_value_gamma (GRand * rand_seed, gdouble a, gdouble b,
|
||||||
|
NormalDistributionState * state)
|
||||||
|
{
|
||||||
|
const gdouble d = a - 1.0 / 3.0;
|
||||||
|
const gdouble c = 1.0 / sqrt (9 * d);
|
||||||
|
gdouble x, u, z, v;
|
||||||
|
|
||||||
|
if (a >= 1.0) {
|
||||||
|
while (TRUE) {
|
||||||
|
z = random_value_normal (rand_seed, 0.0, 1.0, state);
|
||||||
|
if (z > -1.0 / c) {
|
||||||
|
u = g_rand_double (rand_seed);
|
||||||
|
v = 1.0 + c * z;
|
||||||
|
v = v * v * v;
|
||||||
|
if (log (u) < (0.5 * z * z + d * (1 - v + log (v)))) {
|
||||||
|
x = d * v;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
u = g_rand_double (rand_seed);
|
||||||
|
x = random_value_gamma (rand_seed, a + 1, b, state) * pow (u, 1.0 / a);
|
||||||
|
}
|
||||||
|
|
||||||
|
return x * b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gint
|
||||||
|
get_random_value_gamma (GRand * rand_seed, gint32 low, gint32 high,
|
||||||
|
NormalDistributionState * state)
|
||||||
|
{
|
||||||
|
/* shape parameter 1.25 gives an OK simulation of wireless networks */
|
||||||
|
/* Find the scale parameter so that P(0 < x < high-low) < 0.95 */
|
||||||
|
/* We know: P(0 < x < R) < 0.95 for gamma(1.25, 1), R = 3.4640381 */
|
||||||
|
gdouble shape = 1.25;
|
||||||
|
gdouble scale = (high - low) / 3.4640381;
|
||||||
|
gdouble x = random_value_gamma (rand_seed, shape, scale, state);
|
||||||
|
/* Add offset so that low is the minimum possible value */
|
||||||
|
return round (x + low);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -276,6 +331,10 @@ gst_net_sim_delay_buffer (GstNetSim * netsim, GstBuffer * buf)
|
||||||
delay = get_random_value_normal (netsim->rand_seed, netsim->min_delay,
|
delay = get_random_value_normal (netsim->rand_seed, netsim->min_delay,
|
||||||
netsim->max_delay, &netsim->delay_state);
|
netsim->max_delay, &netsim->delay_state);
|
||||||
break;
|
break;
|
||||||
|
case DISTRIBUTION_GAMMA:
|
||||||
|
delay = get_random_value_gamma (netsim->rand_seed, netsim->min_delay,
|
||||||
|
netsim->max_delay, &netsim->delay_state);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -49,7 +49,8 @@ typedef struct _GstNetSimClass GstNetSimClass;
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
DISTRIBUTION_UNIFORM,
|
DISTRIBUTION_UNIFORM,
|
||||||
DISTRIBUTION_NORMAL
|
DISTRIBUTION_NORMAL,
|
||||||
|
DISTRIBUTION_GAMMA
|
||||||
} GstNetSimDistribution;
|
} GstNetSimDistribution;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
Loading…
Reference in a new issue