00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #define KATE_INTERNAL
00011 #include "kate_internal.h"
00012
00013 #include "kate/kate.h"
00014
00022 int kate_granule_shift(const kate_info *ki)
00023 {
00024 if (!ki) return KATE_E_INVALID_PARAMETER;
00025 return ki->granule_shift;
00026 }
00027
00037 kate_int64_t kate_time_granule(const kate_info *ki,kate_float base,kate_float offset)
00038 {
00039 kate_int64_t gbase,goffset;
00040 kate_float actual_base,actual_offset;
00041
00042 if (!ki) return KATE_E_INVALID_PARAMETER;
00043 if (base<0 || offset<0) return KATE_E_INVALID_PARAMETER;
00044
00045 gbase=(kate_int64_t)((base*ki->gps_numerator)/ki->gps_denominator);
00046 actual_base=gbase*(kate_float)ki->gps_denominator/ki->gps_numerator;
00047 gbase=(kate_int64_t)((actual_base*ki->gps_numerator)/ki->gps_denominator+(kate_float)0.5);
00048 actual_offset=offset+(base-actual_base);
00049 if (actual_offset<0) actual_offset=0;
00050 goffset=(kate_int64_t)((actual_offset*ki->gps_numerator)/ki->gps_denominator+(kate_float)0.5);
00051
00052 if (gbase>=(((kate_int64_t)1)<<(63-ki->granule_shift))-1) return KATE_E_LIMIT;
00053 if (goffset>=(((kate_int64_t)1)<<ki->granule_shift)-1) return KATE_E_LIMIT;
00054 return (gbase<<ki->granule_shift)|goffset;
00055 }
00056
00067 int kate_granule_split_time(const kate_info *ki,kate_int64_t granulepos,kate_float *base,kate_float *offset)
00068 {
00069 kate_int64_t gbase,goffset;
00070
00071 if (!ki || !base || !offset) return KATE_E_INVALID_PARAMETER;
00072 if (granulepos<0) return KATE_E_INVALID_PARAMETER;
00073
00074 gbase=granulepos>>ki->granule_shift;
00075 goffset=granulepos-(gbase<<ki->granule_shift);
00076 *base=gbase*(kate_float)ki->gps_denominator/ki->gps_numerator;
00077 *offset=goffset*(kate_float)ki->gps_denominator/ki->gps_numerator;
00078
00079 return 0;
00080 }
00081
00090 kate_float kate_granule_time(const kate_info *ki,kate_int64_t granulepos)
00091 {
00092 kate_float base,offset;
00093 int ret;
00094
00095 ret=kate_granule_split_time(ki,granulepos,&base,&offset);
00096 if (ret<0) return (kate_float)ret;
00097 return base+offset;
00098 }
00099
00108 kate_int64_t kate_duration_granule(const kate_info *ki,kate_float duration)
00109 {
00110 kate_int64_t granule;
00111
00112 if (!ki) return KATE_E_INVALID_PARAMETER;
00113 if (duration<0) return KATE_E_INVALID_PARAMETER;
00114
00115 granule=(kate_int64_t)((duration*ki->gps_numerator)/ki->gps_denominator+(kate_float)0.5);
00116 if (granule<0) return KATE_E_BAD_GRANULE;
00117 return granule;
00118 }
00119
00128 kate_float kate_granule_duration(const kate_info *ki,kate_int64_t duration)
00129 {
00130 if (!ki) return KATE_E_INVALID_PARAMETER;
00131 if (duration<0) return KATE_E_INVALID_PARAMETER;
00132
00133 return duration*(kate_float)ki->gps_denominator/ki->gps_numerator;
00134 }
00135