// Copyright 2012 David J Smith, Nanch LLC // This code is available to the general public for use in personal or commercial products free of charge with no implied or explicit liability // This code was used in [ EZ Drop ], a fast and easy way to get files to your droid // https://market.android.com/details?id=co.dropper.ez.android.free package co.dropper.ez.android.free; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; public class LowPassBitrateEstimator { Queue arrivals = new ConcurrentLinkedQueue(); long baseTime = System.currentTimeMillis(); long millisecondInterval = 250; private double multiplier = 1000 / millisecondInterval; private double alpha = .96; long lastEstimatedTime = System.currentTimeMillis() - baseTime; double currentAverage = 0; public LowPassBitrateEstimator() { } public double estimate() { long now = System.currentTimeMillis() - baseTime; if (now - lastEstimatedTime < millisecondInterval) { return currentAverage * multiplier; } if (arrivals.size() == 0) { if (now > millisecondInterval) { for (int i = 0; i < (now - lastEstimatedTime) / millisecondInterval; i++) { currentAverage = alpha * currentAverage + (1 - alpha) * 0; lastEstimatedTime += millisecondInterval; } } } else { long totalBytesReceived = 0; BitrateRecord br = new BitrateRecord(); br = arrivals.peek(); while (br.t < now - millisecondInterval) { while (br.t < lastEstimatedTime + millisecondInterval) { totalBytesReceived += br.v; arrivals.remove(); if (arrivals.size() == 0) { break; } br = arrivals.peek(); } currentAverage = alpha * currentAverage + (1 - alpha) * totalBytesReceived; lastEstimatedTime += millisecondInterval; totalBytesReceived = 0; if (arrivals.size() == 0) { break; } } } return currentAverage * multiplier; } public void push(int val){ BitrateRecord br = new BitrateRecord(); br.t = System.currentTimeMillis() - baseTime; br.v = val; arrivals.add(br); } } ----------------------------- BEGIN BitrateRecord.java ----------------------------- package co.dropper.ez.android.free; public class BitrateRecord { public long t; public long v; }