00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "wvrateadjust.h"
00011
00012 WvRateAdjust::WvRateAdjust(int _sampsize, int _irate_base, int _orate)
00013 #if 0
00014 : log("RateAdj", WvLog::Debug5)
00015 #endif
00016 {
00017 orate_n = _orate;
00018 orate_d = 1;
00019 match_rate = NULL;
00020
00021 init(_sampsize, _irate_base);
00022 }
00023
00024
00025 WvRateAdjust::WvRateAdjust(int _sampsize, int _irate_base,
00026 WvRateAdjust *_match_rate)
00027 #if 0
00028 : log("RateAdj", WvLog::Debug5)
00029 #endif
00030 {
00031 match_rate = _match_rate;
00032 assert(match_rate);
00033
00034 orate_n = match_rate->irate_n;
00035 orate_d = match_rate->irate_d;
00036
00037 init(_sampsize, _irate_base);
00038 }
00039
00040
00041 void WvRateAdjust::init(int _sampsize, int _irate_base)
00042 {
00043 sampsize = _sampsize;
00044 irate_n = _irate_base * 10;
00045 irate_d = 10;
00046 epoch = wvtime();
00047 epoch.tv_sec--;
00048 bucket = 0;
00049 }
00050
00051
00052
00053
00054 bool WvRateAdjust::_encode(WvBuf &inbuf, WvBuf &outbuf, bool flush)
00055 {
00056 if (!inbuf.used()) return true;
00057 assert((inbuf.used() % sampsize) == 0);
00058
00059 WvTime now = wvtime();
00060 unsigned isamps = inbuf.used() / sampsize;
00061
00062
00063 if (match_rate)
00064 {
00065 orate_n = match_rate->irate_n;
00066 orate_d = match_rate->irate_d;
00067 }
00068
00069
00070 if (!epoch.tv_sec)
00071 epoch = now;
00072 irate_n += isamps * 10;
00073 irate_d = msecdiff(wvtime(), epoch) / 100;
00074 if (!irate_d)
00075 irate_d = 1;
00076
00077 #if 0
00078 log("irate=%s (%s/%s), orate=%s (%s/%s), bucket=%s\n",
00079 getirate(), irate_n, irate_d, getorate(), orate_n, orate_d,
00080 bucket);
00081 #endif
00082
00083
00084
00085
00086
00087
00088
00089 if (irate_d > 100)
00090 {
00091 epoch.tv_sec++;
00092 irate_n = irate_n * (irate_d - 10)/irate_d;
00093 irate_d -= 10;
00094
00095 #if 0
00096 log(" JUMP! new irate=%s (%s/%s)\n", getirate(), irate_n, irate_d);
00097 #endif
00098 }
00099
00100 int plus = orate_n * irate_d, minus = irate_n * orate_d;
00101
00102
00103 unsigned omax = isamps + isamps/2;
00104
00105
00106 const unsigned char *iptr = inbuf.get(isamps * sampsize);
00107 unsigned char *ostart, *optr;
00108
00109 ostart = optr = outbuf.alloc(omax * sampsize);
00110
00111
00112 for (unsigned s = 0; s < isamps; s++, iptr += sampsize)
00113 {
00114 bucket += plus;
00115
00116
00117 while (bucket >= minus)
00118 {
00119
00120 if ((unsigned)(optr - ostart) >= omax * sampsize)
00121 ostart = optr = outbuf.alloc(omax * sampsize);
00122
00123 for (int i = 0; i < sampsize; i++)
00124 optr[i] = iptr[i];
00125 optr += sampsize;
00126 bucket -= minus;
00127 }
00128 }
00129
00130 unsigned un = omax*sampsize - (optr - ostart);
00131
00132 outbuf.unalloc(un);
00133
00134 return true;
00135 }
00136
00137