Here's everything all done, ready for testing. I used an optional scale, defaulting to 1000 (msec for shutter time) and aperture conversions. ISO conversions ignore the scale, although I left it in the lua function in case we want to use it for some reason.
I've also included my test lua script, which uses all the functions and options, including setting the scale to usuck, uh, usec (microseconds), or 1000000. I had ISO set to "auto" for the first part, and 100,200,400,800,1600,3200 at the end. Market values in auto seem to be off, but the convert function works properly.
I really think the optional scale factor adds a lot. Wasn't it reyalp who had the idea of adding an optional scale to get_histo_range(from, to, scale)? So I can blame him for giving me the idea in the first place. Try it. I think you'll like it.
static int luaCB_shutter_to_tv96( lua_State* L )
{
lua_pushnumber( L, convert96(luaL_checknumber(L,1),
luaL_optnumber(L,2,1000), 1 )); //1 is type for shutter_to_tv96
return 1;
}
static int luaCB_tv96_to_shutter( lua_State* L )
{
lua_pushnumber( L, convert96(luaL_checknumber(L,1),
luaL_optnumber(L,2,1000), 2 )); //type 2
return 1;
}
static int luaCB_iso_to_sv96( lua_State* L )
{
lua_pushnumber( L, convert96(luaL_checknumber(L,1),
luaL_optnumber(L,2,1), 3 )); //type 3 - scale ignored
return 1;
}
static int luaCB_sv96_to_iso( lua_State* L )
{
lua_pushnumber( L, convert96(luaL_checknumber(L,1),
luaL_optnumber(L,2,1), 4 )); //type 4 - scale ignored
return 1;
}
static int luaCB_aperture_to_av96( lua_State* L )
{
lua_pushnumber( L, convert96(luaL_checknumber(L,1),
luaL_optnumber(L,2,1000), 5 )); //type 5
return 1;
}
static int luaCB_av96_to_aperture( lua_State* L )
{
lua_pushnumber( L, convert96(luaL_checknumber(L,1),
luaL_optnumber(L,2,1000), 6 )); //type 6
return 1;
}
//************************************************************
static int convert96(int x, int scale, int type) //converts for lua integers
{
switch(type)
{
case 1: //shutter speed (msec) to tv96
if(x==0)break; //shutter speed 0 invalid
double f=(double)x;
if(x<0)f = -scale/f; //<0 means 1000/x. example: -2000 means 1/2 sec shutter speed
else f /= scale; //500 means 1/2 sec also
return (int)(-318.90509710918*log10(f)+0.5); //-96*log2(f)
case 2: //tv96 to shutter speed(msec)
return (int)(scale*pow(2,(((double)-x)*0.010416666666667))+0.5); //2^(-t/96)
//if tv96<0 you can call with -tv96(positive) and print as ("1/",tv96_to_shutter(-tv))
case 3: //iso to sv96 scale=1?
return (int)(318.90509710918*log10(0.297301778750680*x)+0.5); // (96/log10(2))*log10(N*ISO)
case 4: //sv96 to iso
return (int)(pow(2,(((double)(x+168))*0.010416666666667))); //2^((x+96N)/96) N=2^(-7/4)
case 5: //aperture to av96
if(x<1)break;
return (int)(log10(((double)x)/scale)*637.810194218373+0.5); //log2(x/1000)*96
case 6: //av96 to aperture
return (int)(pow(2,((double)x)*0.005208333333333)*scale+0.5 ); //2^(x/192)*1000
}
return 0; //invalid type or input
}
--[[
@title Apex96
--]]
function seconds(tv) -- converts tv96 to time string i.e. print(seconds(tv))
pre=""
if(tv>0)then
tv=-tv
pre="1/"
end
tv=tv96_to_shutter(tv) -- tv96 to msec
ti=tv/1000 -- integer part
ts=string.format("%s%u.%03u",pre,ti,tv%1000) -- xx.xxx or 1/xx.xxx
if(ti>1)then -- truncate digits to reflect decimal precision
if(ti>149)then ti=-5
elseif(ti>14)then ti=-3
else ti=-2 end
ts=string.sub(ts,1,ti)
end
return ts
end
print_screen(-2)
print(os.date())
press("shoot_half")
repeat sleep(10) until get_shooting()
tv96=get_tv96();
shutter=tv96_to_shutter(tv96,1000000)
print(string.format("tv96=%d shutter=%d.%06d %s seconds",tv96,shutter/1000000,shutter%1000000,seconds(tv96)))
print("back to tv96=",shutter_to_tv96(shutter,1000000))
sv96=get_sv96()
iso=sv96_to_iso(sv96)
print("sv96=",sv96,iso,"ISO real=",get_iso_real(),"market=",get_iso_market())
print("back to sv96=",iso_to_sv96(iso))
av96=get_av96()
ap=av96_to_aperture(av96)
print(string.format("av96= %d f/%d.%d",av96,ap/1000,ap%1000))
print("back to av96=",aperture_to_av96(ap))
print()
print_screen(false)