Audio RED simulation
import argparse | |
import random | |
import matplotlib.pyplot as plt | |
from collections import defaultdict | |
class PktDrop(object): | |
def drop(self): | |
return False | |
class BernoulliDrop(PktDrop): | |
def __init__(self, p): | |
self.pktloss = p | |
def drop(self): | |
return random.random() < self.pktloss | |
class IntervalDrop(PktDrop): | |
def __init__(self, burst, interval): | |
# loss burst packet every interval | |
assert burst <= interval | |
self.burst = burst | |
self.interval = interval | |
self.idx = 0 | |
def drop(self): | |
drop = False | |
remain = self.idx % self.interval | |
if remain < self.burst: | |
drop = True | |
self.idx += 1 | |
return drop | |
class GilbertSimpleDrop(PktDrop): | |
GOOD_ST = 0 | |
BAD_ST = 1 | |
def __init__(self, loss, burstlen): | |
self.g2bP = loss / burstlen / ( 1 - loss) | |
self.b2gR = 1.0 / burstlen | |
self.state = GilbertSimpleDrop.GOOD_ST | |
def drop(self): | |
prob = random.random() | |
drop = False | |
if self.state == GilbertSimpleDrop.GOOD_ST: | |
if prob <= self.g2bP: | |
self.state = GilbertSimpleDrop.BAD_ST | |
else: | |
if prob <= self.b2gR: | |
self.state = GilbertSimpleDrop.GOOD_ST | |
drop = True | |
return drop | |
class REDSimulation(object): | |
def __init__(self, pktNum, lossModel, distance): | |
self.pktNum = pktNum | |
self.lossModel = lossModel | |
self.distance = distance | |
def run(self): | |
drop = 0 | |
actualDrop = 0 | |
gap = 0 | |
for i in range(self.pktNum): | |
if self.lossModel.drop(): | |
#print('drop %d' % i) | |
gap += 1 | |
else: | |
#print('recv %d' % i) | |
actualDrop += gap | |
gap = max(gap - self.distance, 0) | |
drop += gap | |
gap = 0 | |
residualLoss = drop * 1.0 / self.pktNum | |
loss = actualDrop * 1.0 / self.pktNum | |
print('total:%d , lost: %d, recovered: %d, rloss:%.2f, loss:%.2f' % (self.pktNum, actualDrop, actualDrop - drop, residualLoss, loss)) | |
return residualLoss | |
def bernoulli_red_sim(p, pktNum, d): | |
rl = defaultdict(list) | |
for distance in d: | |
print('\ndistance = %d' % distance) | |
for lr in p: | |
lossModel = BernoulliDrop(lr) | |
redsim = REDSimulation(pktNum, lossModel, distance) | |
residualLoss = redsim.run() | |
rl[distance].append((lr,residualLoss)) | |
# plot | |
plt.title('RED simulation') | |
plt.xlabel('loss ratio') | |
plt.ylabel('residual loss ratio') | |
for distance, results in rl.items(): | |
loss = [l[0] for l in results] | |
residualLoss = [l[1] for l in results] | |
plt.plot(loss, residualLoss, label='distance: %d' % distance) | |
plt.legend() | |
plt.show() | |
def gilbertsimple_red_sim(p, pktNum, d, blens): | |
rl = defaultdict(list) | |
for burst in blens: | |
for distance in d: | |
print('\ndistance = %d, burst = %d' % (distance, burst)) | |
for lr in p: | |
lossModel = GilbertSimpleDrop(lr, burst) | |
redsim = REDSimulation(pktNum, lossModel, distance) | |
residualLoss = redsim.run() | |
rl[(distance, burst)].append((lr,residualLoss)) | |
# plot | |
plt.title('RED simulation') | |
plt.xlabel('loss ratio') | |
plt.ylabel('residual loss ratio') | |
for key, results in rl.items(): | |
loss = [l[0] for l in results] | |
residualLoss = [l[1] for l in results] | |
distance, burst = key | |
plt.plot(loss, residualLoss, label='distance: %d, burst: %d' % (distance, burst)) | |
plt.legend() | |
plt.show() | |
if __name__ == '__main__': | |
p = [lr/100.0 for lr in range(2, 82, 2)] | |
pktNum = 10000 | |
d = [1, 2, 3, 4, 5] | |
blens = [2, 3] | |
argParser = argparse.ArgumentParser() | |
argParser.add_argument('--ber', action="store_true", default=False, help="Bernoulli loss model simulation") | |
argParser.add_argument('--gilbers', action="store_true", default=False, help="GilbertSimple loss model simulation") | |
args = argParser.parse_args() | |
if args.ber: | |
bernoulli_red_sim(p, pktNum, d) | |
if args.gilbers: | |
gilbertsimple_red_sim(p, pktNum, d, blens) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment