26 May 2011, 14:54 | #1 |
Registered User
Join Date: Aug 2008
Location: Salisbury
Posts: 744
|
Maths question, divisions, remainders etc.
Hi guys
Bit of a maths question today. Funnily enough relating to scope code again. It's to do with sample rates (or periods! as they are called on the amiga) and time calculations. This is a section of code from the original protracker scope code.. Code:
MOVEQ.L #0,D1 MOVE.W ns_period(A2),D1 LSR.W #1,D1 BEQ.S ScoNextChan MOVE.L #35469,D2 DIVU D1,D2 EXT.L D2 ADD.L D2,D0 So, at present all the scopes I've seen or worked on simply draw the samples byte by byte to the screen and uses this calculation to simply move the pointer each frame to where the sample should be. This is not an accurate representation of the wave form, however it does suffice most requirements. What I want to do is draw the wave at the frequency it is being played at. My idea was to simply divide the 35469 by the pixel width of the scope, then use this value to increment the sample pointer for each pixel. However, I very quickly realised that you cannot get away with this as the remainder from the division needs to be taken into consideration for each pixel iteration. Code:
moveq #0,d1 MOVE.W #172,D1 ; period LSR.W #1,D1 MOVE.L #35469/160,D2 ; magic number div by 160 pixels DIVU D1,D2 So... how do you go about performing this type of calculation in 68k? On a side note, it doesn't need to be fast, just accurate as it will all get pre-calced into look up tables anyhow. |
26 May 2011, 15:40 | #2 | |
Registered User
Join Date: Sep 2007
Location: Las Cruces, USA
Age: 71
Posts: 351
|
Quote:
One possible way is to convert to double float, do the calculations, round to an integer, and then convert back to integers. It's slow but it works. You may still be off at the end, it just depends on how well the rounding averages out. I've used this method for scaling the data for plotting purposes. |
|
26 May 2011, 16:14 | #3 |
Registered User
Join Date: Aug 2008
Location: Salisbury
Posts: 744
|
How do you do a double float in assembly?
|
26 May 2011, 17:42 | #4 |
tulou
Join Date: Jun 2006
Location: Gothenburg / Sweden
Posts: 88
|
If you're on 020, you can use divu.l with 35469<<16 to get a 16.16 bit fixed point representation. That should be sufficient for 160 pixels.
If you're not on 020, perhaps Bresenham interpolation could be a solution. |
26 May 2011, 23:19 | #5 |
Registered User
Join Date: Sep 2007
Location: Las Cruces, USA
Age: 71
Posts: 351
|
Use the Amiga math libs to do the converting and calculations. The easiest way would be to use the math libs to convert all your integers like 35469 and integers in the data registers, to single or double float. Calculate and then use the math libs to convert back to integers. It's basically a pain. It's a lot easier to do it in C. When I was doing a lot of assembly I had macros to make it a lot easier, I also came up with my own double float constants and wrote a program that would search through my source codes and convert double float constants like 35469.0 into two dc.l. Eventually I got an assembler that new about double float constants. After 20 years of assembly programing I finally wised up and learned C, now I do assembly only when it's necessary. I can already feel the hate from the pure assembly programers, like I used to be. |
27 May 2011, 14:22 | #6 |
Registered User
Join Date: Aug 2008
Location: Salisbury
Posts: 744
|
Thanks for the response Ed, however, i'm more interested in how to solve this problem with assembly. I know that maths lib might be the easiest, but I'd love to know how these kind of problems are resolved when working directly with the CPU.
|
27 May 2011, 15:44 | #7 | |
Registered User
Join Date: Sep 2007
Location: Las Cruces, USA
Age: 71
Posts: 351
|
Quote:
I know what you mean, I've tried to complish the same thing dealing with the remainder but it's always been very difficult. Seems like there's always some odd combination of things that causes problems, so I end up using double floating point. Recently I did manage to use the remainder method and it was working, but in the normal use of what I was doing I would frequently end up with numbers after the divide that were larger then a long could handle and it messed up my whole plan. In this case speed was important and using double floating point was slow but I ended up using it anyway, I had no choice. My math isn't good enough to figure out how to use remainders reliably to do what I needed. Especially rounding. I use WinUAE so the emulated fpu is really fast, so when I really need my float points to be fast I compile to use inline FPU code. But that also requires using at least a 68020, but you want 68000. If you could use a 68020 you can also use an assembler that knows fpu commands and use the fpu to convert, calculate, and convert back to integers. From a assembly programmers point of view the fpu is a dream to use and very fast. |
|
30 May 2011, 15:15 | #8 |
Registered User
Join Date: Feb 2009
Location: Copenhagen / Denmark
Posts: 11
|
I'm not experienced with asm, so I might not understand your code correctly, but from what it looks like to me is, that you divide D1 with D2, where D2 is a division of 35469/160, which have a remainder.
The math can be rewritten: A / (B / C) = (A * C) / B -> ( D1 * 160 ) / 35469 Assuming that A * C does not overflow you have removed the imprecision of one division. Last edited by MSL; 30 May 2011 at 15:21. Reason: Spelling mistake |
07 June 2011, 14:35 | #9 |
Registered User
Join Date: Aug 2008
Location: Salisbury
Posts: 744
|
Just thought I'd put a quick update here, managed to crack it in the end...
Code:
ScopeInitFreq lea FreqTable+(scopebytewd*8*2),a0 moveq #1,d0 ; current period .nextperiod move.l #35469/(scopebytewd*8),d6 ; the magic number! moveq #0,d5 move.w #scopebytewd*8-1,d7 moveq #0,d2 moveq #0,d3 .test add.l d6,d5 move.l d5,d1 divu d0,d1 move.w d1,d2 sub.w d3,d1 move.w d1,(a0)+ ; store byte move size move.w d2,d3 dbra d7,.test add.w #1,d0 cmp.w #scopemaxperiod,d0 blo.b .nextperiod RTS |
24 June 2011, 00:03 | #10 |
Moderator
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,602
|
If you're using The Player to optimize modules, there's a scope routine accurate to 1/262144th of a sample in the latest P61 playroutine by me, P6108, if you enable it it will give you pointer and length for a 50Hz frame for each playing channel. It wraps loops correctly and gives a bunch of zeroes if the channel is quiet or ending.
|
24 June 2011, 08:40 | #11 |
gone
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
|
@ Photon: going slightly off topic I suppose but not too far I hope - I integrated ThePlayer into my demo shell recently but I didn't manage to get your "super optimised, all singing, all dancing" version to assemble and had to use the latest "old" release of ThePlayer instead.
With your version I got 200+ errors on assembly using Devpac3.18 - was I doing something obviously and stupidly wrong...? |
24 June 2011, 18:35 | #12 |
Moderator
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,602
|
Differences between assemblers will give errors, basically for all sources "not made for your assembler flavor". The Player source is special in that it uses loads of conditionals and a few macros, and these features might not be supported or need to be written in another way to be used in your assembler. Same thing if someone releases a Devpac source and uses features not found in say, AsmOne or PhxAss.
The most common complaint about The Player sources is the structures macros. Have you set ASMONE=0, to start with? This attempts to replace AsmOne macros with other flavors. If there are remaining differences you'll have to reconcile them, or you could rip out the Scope routine+a few vars added for it at the end of the source and see if it talks to P6106. Or check what it does and modify it to talk to Protracker, that would be ace |
24 June 2011, 23:58 | #13 |
Registered User
Join Date: Aug 2008
Location: Salisbury
Posts: 744
|
Hey photn, thanks for the offer, however I've got my scope routine already integrated into the player. Fixed all the original bugs that came with the original source, such as sample offset, loops sample endings. I've recently done a version which draws the sample at the sample rate its playing at. Next up is it see if I can combine all four channels into one massive scope
|
25 June 2011, 00:00 | #14 | |
AMOS Extensions Developer
Join Date: Jun 2007
Location: near Cambridge, UK
Age: 44
Posts: 1,924
|
Quote:
Now I always compile assemble with case-sensitive mode off. Regards, Lonewolf10 Last edited by Lonewolf10; 25 June 2011 at 00:05. Reason: typo (assembling not compiling) |
|
25 June 2011, 09:06 | #15 |
gone
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
|
Errrm, no - not using case sensitive and had already done all the other obvious stuff.
While Photon was around I thought I'd ask out of curiosity but now I know (rather than just suspecting...) the answer is basically to go though those errors and remedy each one I'm gonna take the approach I'd already decided on: stick with the latest un-Photon'd version of ThePlayer that works for me. |
25 June 2011, 21:44 | #16 |
Moderator
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,602
|
pmc, I'd be interested in differences in error log between P6106 and P6108, so email me them if you want !
h0ffman, hm, read pmc's reply as one of yours, sorry for the confusion. The scope routine would then only be of abstract use for your playroutine, anyway good to hear you fixed it up! And yes, 4 fullres scopes running separately consume a not negligible amount of raster time on OCS, visualizing 4 added together to reduce the amount of plots or similar you use to visualize it is a very good idea |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
La bosse des maths 5ème | dlfrsilver | request.Old Rare Games | 2 | 12 February 2013 18:23 |
Educational maths title, skateboard? | Nipedley | Looking for a game name ? | 8 | 29 April 2011 21:56 |
Intel representative cant do maths | alexh | Retrogaming General Discussion | 5 | 18 November 2007 23:47 |
Soioty & Sweep maths game | ElectroBlaster | HOL contributions | 0 | 19 September 2006 01:11 |
Abuse AGA & Merlin's Maths | icewizard2k5 | request.Old Rare Games | 2 | 21 February 2005 12:14 |
|
|