# KSP Math Library Beginnings



## Big Bob (Oct 16, 2006)

Hi Guys,

Now that NI has improved the noise situation with the change_vol() function and, we are no longer stuck with only piecewise-linear fade_in/fade_out combinations, I'm hoping to soon revisit some of our former ideas about crossfade shaping and such. With the flexibility of individual note volume shaping, we may be able to improve legato transitions, build upon the formant-corrected bending introduced with the PCE (a year or so ago), etc. Of course, I'm still operating in 'low-profile' mode, but, I still want to do something :wink: .

In any case, in an effort to prepare for writing my next (ahem!) super script :razz: , I decided to start the development of a KSP Math library. Transcendental functions like log(x) (necessary to convert volume ratios to mdb control signals for change_vol), various trig functions like sin(x) and cos(x) (needed for equal-power crossfading ), and such are going to be needed. Since the KSP is rather limited in its number crunching abilities, writing such functions is an interesting challenge. We need functions that will execute quickly but still provide smooth and reasonbly-accurate results. And, if at all possible, we'd like to avoid the use of massive lookup tables (they take up a lot of room and they're pure tedium to initialize)!

Because of KSP limitations, we need to discover or 're-discover' ways around such limitations. While the KSP can only do integer arithmetic, *it does have hardware multiply and divide and, it handles long integers * so, at least compared to the 8 and 16 bit stuff of yesteryear, things could be much worse :roll: ! However, the KSP does not lend itself too well to Taylor series expansion and such because there is usually far too much fiddling around with dynamic scaling. Maybe one of us ought to write a floating-point package for the KSP? If floating point calculations execute fast enough, this would then 'open more doors' to series expansion techniques and such. (Hmmm .... , no I better not even think about it :wink: )

For those of you who are interested in using or examining what I have so far, I'm going to share the source code of my initial Math library (as it stands today) by attaching it to this post. (You'll need the NL Editor V1.1 or higher to compile it). I'm still testing and characterizing some of these routines by writing a relative error analysis program. However, it's been about 10 years since I fired up Delphi and with my 'big-time' memory problems, it'll be a while before I can get back up to speed :cry: . However, initial testing of the Math library in the KSP itself looks very promising. Accuracy and speed seem excellent.

For the log functions, I found an ingenious method of approximating binary (base 2) logarithms that was devised by John DeVos around 2001. This routine is simplicity itself and it was very easy to adapt it to the KSP. Accuracy seems to be on the order of 0.01%. Its code is very compact and, it uses no lookup tables! Of course I realize that logs to the base 2 are (in and of themselves) not too useful but, I'm sure most of you know once you have logs in any base you can easily convert them to another. With DeVos algorithm such base conversions are extremely easy to do. To illustrate this, I have included routines that compute common and natural logs. Even better, I've included a *Get_db *function that converts a linear ratio of volume (*V/Vm*) to *20*log(V/Vm)* in mdb. This will allow us to connect the output of some volume shaping function (such as a sine or cosine routine) to the KSP change_vol() function which requires its input in mdb.

For the trig functions, I used the Binary Cordic algorithm (usually credited to Jack Volder, circa 1959). This algorithm is also ideally suited to the capabilities of the KSP. I provided two forms of this routine. The 'inner' routine, *SinCos* requires that the input angle be confined to the first quadrant while the second routine, *FSinCos* is an 'outer' shell that does angle reduction and reflection before calling SinCos. *FSinCos* can accept any size angle, plus or minus. I wrote these routines to accept angles in deci-grads (1000 deci-grads = PI/2 radians = 90 degrees). However, by simply rescaling the small arctan table, you can use any desired angle units such as 'brads' (256 brads per 90 degrees).

One nice thing about the Cordic is that it computes both the sine and the cosine at the same time! Initial tests indicate about 4 decimal digits of accuracy and the execution time is on the order of 12 microseconds (to obtain both sin and cos). The Cordic is also a very versatile algoritmn capable of generating arc tangents, hyperbolic functions, and many other things. I'll no doubt be adding more such related functions in the near future.

With the attached Math library, I'm including about 5 little test scripts that will allow you to fire up the library functions and play with them. Let me know what you think. I'm also hoping that this offering will stimulate others to submit nice 'lean and mean' math functions that you may have been 'hoarding' :razz: (or whenever you may come across them). Now that Nils has added 'import' as well as the everpanding 'function' capability, hopefully we will begin to see some useful libraries start to develop.

God Bless,

Bob


----------



## Thonex (Oct 16, 2006)

Bob,

THANK YOU for taking the iniative on this.

I've done some scripts that use log tables (mostly for detune-to-tempo calculations) and it was a big pain in the butt... to say the least.

I wish I could be of use to you guys in all this... but I think I would be just dead weight. I can however test things when things slow down a little.

But this is a great idea. 

As I understand it, these "simplified" formulas are only appoximations, so I'm curious how these formulas will work with NI's convention of using 0-1 million for many of its value ranges.

Cheers,

T


----------



## Thonex (Oct 17, 2006)

HI Guys,

I posted a Log Table for pitch to tempo detuning here but it would be soooo much better if it could be used as a formula.



Big Bob @ Mon Oct 16 said:


> I realize that logs to the base 2 are (in and of themselves) not too useful but, I'm sure most of you know once you have logs in any base you can easily convert them to another.



Do you think there would be an efficient way to do this in KSP... it is the standard formula for pitch to tempo with drum loops...


detune amount =(1200/LOG(2)*LOG(BPM/SampleBPM))*1000 

Thanks,

T


----------



## Big Bob (Oct 17, 2006)

> Do you think there would be an efficient way to do this in KSP... it is the standard formula for pitch to tempo with drum loops...
> 
> 
> detune amount =(1200/LOG(2)*LOG(BPM/SampleBPM))*1000
> ...



Hi Andrew,

As to whether or not you can replace your tables with a function call, I guess it all depends on the overall accuracy you are looking for. Your tables have entries that imply a 6 or 7 decimal digit accuracy (I don't know if you need that much though). The Math library log routine is pretty accurate in and of itself, but in actual usage, small errors can be amplified as I'll illustrate below.

In crafting a 'Retune' routine, we start with the fact that your input is the ratio of playback speed to the sample's recorded speed. Let's denote the ratio as Tp/Ts (tempo of playback to tempo of the sample). Let's then simplify by calling this ratio R = Tp/Ts, where 0.5 <= R <= 3.0. Since the KSP can only deal with integers and you want some resolution, you have scaled R by 100. In general, we can express this as R*S where S is some scaling factor to get rid of the fractional component.

Now, using the standard formula for tuning, we have:

(1) pitch_change = (1200000/log(2))*[log(R)] in mcents

However, we don't have R, we have R*S, so we rewrite equation (1) as:

(2) pitch_change = K1*(log(RS/S)) = K1*(log(RS) - log(S)) where K1 is 1200000/log(2)

Now, since the library function for log(x) returns 10,000 times the actual log and, since
we are scaling by S = 100, we can write:

(3) pitch_change = K*(log(RS) - 20000) where K = 120/log(2)

I'm attaching a little script that implements equation (3) using the KSP_Math#1 library. You can fire it up and start checking whether or not it has sufficient accuracy for your purposes. I checked a half-dozen or so ratios against your table and find most of the errors are quite small (on the order of 0.1%). The log function itself is typically an order of magnitude more accurate than that but notice in equation (3) that we are taking the difference between two logs that aren't always so far apart. Whenever you take the difference between two nearly equal numbers, any errors in the numbers can be amplified considerably.

One of the larger errors I found was for R = 0.75. An accurate answer would be as you have it in your table, namely: 498045. However, 'Retune' gives us: 499149 which is high by about 1 cent in 500 cents (about 0.2% error). If you try more examples, you might find some larger errors. Incidentally, I did find some errors in your table so when you think that 'Retune' is too much in error, you had better get out your calculator and verify that your table for that input is correct.

Let me know if this works out for you.

God Bless,

Bob

_{ Test Script for 'Retune' Routine 10-17-06 Big Bob }_

*import* "KSP_Math#1.txt"

*on init*
``*declare* ui_value_edit Ratio (50,300,100)
````set_text(Ratio,'Tp/Ts')
````move_control(Ratio,1,1)
````Ratio := 200
``*declare* ui_label ShowTune (1,2)
````move_control(ShowTune,1,2)
``*declare* tune_amt
*end on* _{ init }_

*on ui_control* (Ratio)
``Retune(Ratio,tune_amt)
``set_text(ShowTune,' Detune By:')
``add_text_line(ShowTune,tune_amt & ' mcts')
*end on* _{ Ratio }_

*function* Retune(tempo_ratio,detune)
_{ 'tempo_ratio' = Tp/Ts*100, 'detune' is in mdb }_
``*declare* logx
``*declare* *const* K := 399``_{ 120/log(2)*10 }_
``log(tempo_ratio,logx)
``detune := -K*(logx - 20000)``_{ -K*(log(Tp/Ts) - log(100) }_
*end function* _{ Retune }_


----------



## Big Bob (Oct 17, 2006)

Hi Andrew,

After my last post, I got to thinking that this might be one of those situations where we might get more accuracy with our binary (base 2) log function since the equi-tempered scale is based on fractional powers of 2.

So, returning to equation (2):

(2) pitch_change = K1*(log(RS/S)) = K1*(log(RS) - log(S)) where K1 is 1200000/log(2)

Instead of common logs (base 10) lets rewrite (2) as:

(3) pitch_change = 120/lg(2)*(lg(RS) - lg(100)) = 120*(lg(RS) - K) 
where now K = lg(100)*10000 = 66439

Now here's the revised 'Retune' function:

_{ Test Script for 'Retune' Routine
Using the Binary lg(x) function 10-17-06 Big Bob }_ 

*import* "KSP_Math#1.txt" 

*on init* 
``*declare* ui_value_edit Ratio (50,300,100) 
````set_text(Ratio,'Tp/Ts') 
````move_control(Ratio,1,1) 
````Ratio := 200 
``*declare* ui_label ShowTune (1,2) 
````move_control(ShowTune,1,2) 
``*declare* tune_amt
``make_persistent(Ratio)
``Update_Display 
*end on* _{ init }_ 

*on ui_control* (Ratio) 
``Update_Display
*end on* _{ Ratio }_

*function* Update_Display
``Retune(Ratio,tune_amt) 
``set_text(ShowTune,' Detune By:') 
``add_text_line(ShowTune,tune_amt & ' mcts') 
*end function* 

*function* Retune(tempo_ratio,detune) 
_{ 'tempo_ratio' = Tp/Ts*100, 'detune' is in mdb }_ 
``*declare* logx 
``*declare* *const* K := 66439[color=white:abò,   GãÉ,   GãÊ,   GãË,   GãÌ,   GãÍ,   GãÎ,   GãÏ,   GãÐ,   GãÑ,   GãÒ,   GãÓ,   GãÔ,   GãÕ,   GãÖ,   Gã×,   GãØ,   GãÙ,   GãÚ,   GãÛ,   GãÜ,   GãÝ,   GãÞ,   Gãß,   Gãà,   Gãá,   Gãâ,   Gãã,   Gãä,   Gãå,   Gãæ,   Gãç,   Gãè,   Gãé,   Gãê,   Gãë,   Gãì,   Gãí,   Gãî,   Gãï,   Gãð,   Gãñ,   Gãò,   Gãó,   Gãô,   Gãõ,   Gãö,   Gã÷,   Gãø,   Gãù,   Gãú,   Gãû,   Gãü,   Gãý,   Gãþ,   Gãÿ,   Gä ,   Gä,   Gä,   Gä,   Gä,   Gä,   Gä,   Gä,   Gä,   Gä	


----------



## Frederick Russ (Oct 18, 2006)

Brilliant! Thanks Big Bob for this and your valued contribution to the K2 community.


----------



## Big Bob (Oct 18, 2006)

kotori @ Tue Oct 17 said:


> Wow Bob!  This is really impressive stuff. Very very useful. Sorry that I've been too busy lately to discuss these things with you. This is really the most impressing function library I've seen so far. In fact seeing this I'm now feeling some extra pressure to implement return values :wink:.
> 
> Thank you Bob for this great contribution to the community.
> 
> ...



Hi Nils,

When you do get some time for the next fabulous NL Editor update, in addition to return values, I want to remind you of something you suggested some time back about not compiling variables that are never referenced. That would be a great feature to support things like a math library. Sometimes users will only want to use one or two of the functions and won't want all the extra baggage slowing down the KSP editor. As it is, when a library is 'imported', the unreferenced functions don't get compiled but all their local variables do. So, your idea of not compiling unreferenced variables would really be a nice feature.

But, I also realize that you have been very busy, so please don't feel any pressure to work on this until you really have the time. All of us who write scripts already owe you a very big debt of gratitude for sharing your editor with us. Without it, I wouldn't even be suggesting anything like a math library. I'd hate to see what a mess the source code would look like with all these functions and things 'balooning' up the 'on note' handler :cry: ! No wonder I hardly ever even 'peek' at the compiled K2 source code anymore!

God Bless,

Bob


----------



## kotori (Oct 18, 2006)

Big Bob @ Wed Oct 18 said:


> Hi Nils,
> 
> When you do get some time for the next fabulous NL Editor update, in addition to return values, I want to remind you of something you suggested some time back about not compiling variables that are never referenced.



Hi Bob
I haven't forgotten about it. This is one of the top things on my list. The number one priority now though is to fix the problems which were introduced when I allowed function expansion at an earlier stage. I would like to clear up things in the source of the compiler. I'll probably go for a complete rewrite of the core compiler code. I've been reading up on a nice parser package for Python called PLY and I think I'm going to rebuild the compiler using this. I will have to run some benchmarks on large scripts to see if it'll work out performance-wise first though. This approach would mean:
the formatting of the code would not be preserved in the compiled code (spaces and comments).
 it would be possible to detect all syntax and semantic errors
 it would be much easier to implement a better solution for variable scopes.
 it might be possible to execute/debug code from within the editor (would require some extra work of me though)
 the compiler would be much easier to understand and maintain.
Cheers,
Nils


----------



## Nickie Fønshauge (Oct 18, 2006)

Hi Nils,

The prospects you listed look promising. Sounds like version 2, or whatever you are going to call it, is going to be a very interesting update. :smile: 

I still think you should include the "if 1 = 1" feature I suggested. It would be a nice thing with large scripts. You could make it optional, if you think not everybody would benefit from it.


----------



## Thonex (Oct 18, 2006)

Wow Bob.... ok..... first I have to say this is absolutely brilliant!!!! Both your script and Nils' editor with all those functions and whatnot... I'll have to step up to the plate and learn all these things.

A couple of observations and a couple of questions.

First, are all the declarations referenced that are in the compiled script? Or are some of those declarations "place holders" in the event you want to reference another Math function?

Bob... your script works great. It blows my mind that I can just type in the numbers and it is so close to my table reading. One interesting thing I've found (you probably already know this) is that your Log calculations become more accurate the further away from 1.00 the ratio is (except for 1.0 of course). I also found this to be a bit of a problem with drum loops using my table. If the tempo of my piece was only a little faster or slower (say 1 or 2 bpm) than the sample bpm... then I would have to compensate a little by adding some VERY subtle pichbend. Is there any way around this? Would it be possible to have a different formula for ratios 0.80<=R<=1.20 or similar?

Also, in my script, (it's been a while now) I think I did some calculations where I multiplied the sampleBPM / DAWBPM ratios by a factor of 10 and then used the remainder to get a linear interpolation between table values. I'm guessing something like this is still possible with your formula... but do you think the "approximations" would rear their ugly head and give worse results?

hhhmmmmm... I guess the only way for me to really see how this would work in a real life way would be to put your script into mine.... a little easier said than done.

Oh... you mentioned some of my table readings were wrong. I just put the values into an ExCel spread sheet and copy/pasted the results. You can download it http://www.andrewkmusic.com/filearea/K2%20Scripts/BPM%20Pitch%20Logarithm%202.xls (HERE).

This is very exciting stuff Bob.... I really want you to know how appreciative I am of all this hard work. You too Nils.

Cheers,

T


----------



## Big Bob (Oct 18, 2006)

Hi Andrew,

Thanks for all the kind remarks, you are always so appreciative :mrgreen: 



> Bob... your script work great. It blows my mind that I can just type in the numbers and it is so close to my table reading. One interesting thing I've found (you probably already know this) is that your Log calculations become more accurate the further away from 1.00 the ratio is (except of 1.0 of course). I also found this to be a bit of a problem with drum loops using my table. If the tempo of my piece was only a little faster or slower (say 1 or 2 bpm) than the sample bpm... then I would have to compensate a little by adding some VERY subtle pichbend. Is there any way around this? Would it be possible to have a different formula for ratios 0.80<=R<=1.20 or similar?



I suspect the cause of this is related to what I already discussed. When the ratio whose logarithm you seek passes through 1.0 on the way down, the actual logarithm changes sign. That is, log(1.0) = 0 and when x < 1.0, log(X) < 0. Since the KSP log functions only work with 1 <= X < 2^16, we handle fractions by scaling X so that it is always an integer of one or more in value. This then requires subracting log(S) from log(SR). It is here that the larger relative error around x = 1.0 occurs.

For example, suppose that you want the log(R), where R = 0.95. First we multiply 0.95 by our scale factor of S = 100. Thus, we calculate log(95) = log(0.95*100). Now, since this is the log of something that's 100 timòƒ   Gø·ƒ   Gø¸ƒ   Gø¹ƒ   Gøºƒ   Gø»ƒ   Gø¼ƒ   Gø½ƒ   Gø¾ƒ   Gø¿ƒ   GøÀƒ   GøÁƒ   GøÂƒ   GøÃƒ   GøÄƒ   GøÅƒ   GøÆƒ   GøÇƒ   GøÈƒ   GøÉƒ   GøÊƒ   GøËƒ   GøÌƒ   GøÍƒ   GøÎƒ   GøÏƒ   GøÐƒ   GøÑƒ   GøÒƒ   GøÓƒ   GøÔƒ   GøÕƒ   GøÖƒ   Gø×ƒ   GøØƒ   GøÙƒ   GøÚƒ   GøÛƒ   GøÜƒ   GøÝƒ   GøÞƒ   Gøßƒ   Gøàƒ   Gøáƒ   Gøâƒ   Gøãƒ   Gøäƒ   Gøåƒ   Gøæƒ   Gøçƒ   Gøèƒ   Gøéƒ   Gøêƒ   Gøëƒ   Gøìƒ   Gøíƒ   Gøîƒ   Gøïƒ   Gøðƒ   Gøñƒ   Gøòƒ   Gøóƒ   Gøôƒ   Gøõƒ   Gøöƒ   Gø÷ƒ   Gøøƒ   Gøùƒ   Gøúƒ   Gøûƒ   Gøüƒ   Gøýƒ   Gøþƒ   Gøÿƒ   Gù ƒ   Gùƒ   Gùƒ   Gùƒ   Gùƒ   Gù„   G÷˜„   G÷™„   Gøl„   Gøm„   Gøn„   Gøo„   Gøp„   Gøq„   Gù
„   Gù„   Gù„   Gù „   Gù„   Gù„   Gù„   Gù„   Gù„   Gù„   Gù„   Gù„   Gù„   Gù„   Gù„   Gù„   Gù„   Gù„   Gù„   Gù„   Gù„   Gù„   Gù „   Gù!„   Gù"              ò„   Gù$„   Gù%„   Gù&„   Gù'„   Gù(„   Gù)„   Gù*„   Gù+„   Gù,„   Gù-„   Gù.„   Gù/„   Gù0„   Gù1„   Gù2„   Gù3„   Gù4„   Gù5„   Gù6„   Gù7„   Gù8„   Gù9„   Gù:„   Gù;„   Gù<„   Gù=„   Gù>„   Gù?„   Gù@„   GùA„   GùB„   GùC„   GùD„   GùE„   GùF„   GùG„   GùH„   GùI„   GùJ„   GùK…   GùL…   GùM…   GùN…   GùO…   GùP…   GùQ…   GùR…   GùS…   GùT…   GùU…   GùV…   GùW…   GùX…   GùY…   GùZ…   Gù[…   Gù\…   Gù]…   Gù^…   Gù_…   Gù`…   Gùa…   Gùb…   Gùc…   Gùd…   Gùe…   Gùf…   Gùg…   GùÐ…   GùÑ…   GùÒ…   GùÓ…   GùÔ…   GùÕ…   GùÖ…   Gù×…   GùØ…   GùÙ…   GùÚ…   GùÛ…   GùÜ…   GùÝ†   Gùj†   Gùk†   Gùl†   Gùm†   Gùn†   Gùo†   Gùp†   Gùq†   Gùr†   Gùs†   Gùt†   Gùu†   Gùv†   Gùw†   Gùx†   Gùy†   Gùz†   Gù{†   Gù|†   Gù}†   Gù~†   Gù†   Gù€†   Gù†   Gù‚†   Gùƒ†   Gù„†   Gù…†   Gù††   Gù‡              ò†   Gù‰†   GùŠ†   Gù‹†   GùŒ†   Gù†   GùŽ†   Gù†   Gù†   Gù‘†   Gù’†   Gù“†   Gù”†   Gù•†   Gù–†   Gù—†   Gù˜†   Gù™†   Gùš†   Gù›†   Gùœ†   Gù†   Gùž†   GùŸ†   Gù †   Gù¡†   Gù¢†   Gù£†   Gù¤†   Gù¥†   Gù¦†   Gù§†   Gù¨†   Gù©†   Gùª†   Gù«†   Gù¬†   Gù­†   Gù®†   Gù¯†   Gù°†   Gù±†   Gù²†   Gù³†   Gù´†   Gùµ†   Gù¶†   Gù·†   Gù¸†   Gù¹†   Gùº†   Gù»†   Gù¼†   Gù½†


----------



## Big Bob (Oct 18, 2006)

> Thanks Bob for all this detailed info.... you realize I have to read your posts very slowly.... a few times.... just to understand half of it



I'm sorry! And here I thought it would be clear as mud :o


----------



## Dynamitec (Oct 25, 2006)

Wow.
It's getting really interesting here! VERY interesting! But with all due respect to Bob's great work: why do we (or should i say: he :lol: ) still have to find workarounds for everthing when it could be so easily implemented by NI - compared to all the other stuff they release? Compared to Core, Massive, Batter 3...it should be SO easy to implement some math functions into KSP... :shock: :???:


----------



## Big Bob (Oct 25, 2006)

Hey Benj,

Let's hope that they at least add 'real' user functions so we can all stop fooling around with the 'play_note zero' thing! The NL editor does a beautiful job of structuring our source code, but, the compiled, K2-ready code still has to put all those function calls in line.

This is OK for smaller scripts, but, then there's the infamous KSP Editor 'molasses' problem that forces us to try to emulate 'real' subroutine calls by hanging them in the RCB and 'calling' them with something like a phony note-on. I think we've all been forced into tricks like this.

On the other hand, (ahem), if these problems didn't exist, what would we do with all of our time? :wink: 

Bob


----------



## Thonex (Oct 25, 2006)

Dynamitec @ Wed Oct 25 said:


> Wow.
> It's getting really interesting here! VERY interesting! But with all due respect to Bob's great work: why do we (or should i say: he :lol: ) still have to find workarounds for everthing when it could be so easily implemented by NI - compared to all the other stuff they release? Compared to Core, Massive, Batter 3...it should be SO easy to implement some math functions into KSP... :shock: :???:
> 
> They'll make it a PAID upgrade :lol: :lol: :lol: :roll:



Ooops... I hit Edit instead of Quote... sorry Dyn.. :lol: 

So.. I'll edit out what I wrote on your post. 

Cheers,

T


----------



## Nickie Fønshauge (Oct 26, 2006)

Big Bob @ 26th October 2006 said:


> On the other hand, (ahem), if these problems didn't exist, what would we do with all of our time? :wink:



Life would be soooo boring without NI. 

Thank you, NI! :twisted: :mrgreen:


----------



## Dynamitec (Nov 8, 2006)

Hi Bob!

Thank you very much! I'm VERY interested in the pdf you are writing at moment. Amazing stuff...while studying psychology i had a lot of statistic at university butsometimes it was not mathematic - it was how to fake your results in the best way. So i really wish i would understand more of this real math stuff you are doing here!

Thank you again!


----------



## Nickie Fønshauge (Nov 8, 2006)

Sounds good Bob. Thank you for sharing this with us. I'll give the .pdf a try when it is ready. I have not been dealing with mathematics for 20 years, though, so I am afraid the wheels might squeak a little. :wink:


----------



## Big Bob (Nov 8, 2006)

Hey Guys,

Just out of curiosity, were any of you able to download the attachment? I notice that it seems to have disappeared for me. I've been having funnies lately though like having to re-enter my user name and password to post.

Do you guys still see the attachment?

And as to accuracy improvement Andrew, it was rather small (since the first version I posted was already fairly accurate). It is *slightly better *and, as I indicated, more uniformly distributed (which should translate into a smoother curve).

I'll provide all the accuracy data I have with the upcoming .pdf (that is if I can get my attachments to stay put :cry: ).

God Bless,

Bob

PS I notice after posting this reply, the attachments are once again visible. It must be that when I first sign-on, I don't have 'attachment privilege' :roll:


----------



## Nickie Fønshauge (Nov 8, 2006)

Hi Bob,

I did download the attachment, but it is either damaged or invalid.




I tried again - it's OK now.


----------



## Big Bob (Nov 8, 2006)

Nickie Fønshauge @ Wed Nov 08 said:


> Hi Bob,
> 
> I did download the attachment, but it is either damaged or invalid.
> 
> ...



Thanks for the feedback Nickie,

It seems to be working OK now for me too. In my case, my computer must have 'lost a cookie' (or maybe 2 or 3 :lol: ). 

Ah yes, the Internet seems to be full of things that 'go bump in the night' these days. :wink:


----------

