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