Created
February 10, 2021 19:34
-
-
Save fuji246/d9b6e8e8742e5ebdb1e6a6e0b6b3fbd0 to your computer and use it in GitHub Desktop.
Audio RED simulation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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