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