A speed-tatstic way to look up a value? (LUTs)


Closed Thread
Results 1 to 13 of 13

Hybrid View

  1. #1
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by rmteo View Post
    That's exactly what I was thinking of - so now, how to implement in picbasic!

    Imagine an array 100 deep (& for simplicity's sake, populated with values 1 thru 100), with an incoming number of 90 to 'look up' against...

    So, the methodology....

    is new incoming value higher or lower than 50

    (result = higher therefore the next stage...)

    is new incoming number higher of lower than 75

    result = higher again, & so on it continues...

    but eventually it all starts getting tricky (because half way between 75 & 100 is 87.5 ....what to do here, etc?)
    Last edited by HankMcSpank; - 3rd October 2010 at 19:36.

  2. #2
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    something I've been thinking about. since this is music, i assume there is a predictable difference between the low or high numbers? I ask because if you could divide all the numbers to create a case type lookup.

    The answer to 87.5 IMHO is to use 87 or 88. Since the half tests are hard coded in(at least for your example) no need to be exact.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  3. #3
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by cncmachineguy View Post
    something I've been thinking about. since this is music, i assume there is a predictable difference between the low or high numbers? I ask because if you could divide all the numbers to create a case type lookup.

    The answer to 87.5 IMHO is to use 87 or 88. Since the half tests are hard coded in(at least for your example) no need to be exact.

    The table I posted earlier was the shortened version, I had diffs formatting the full version, but this screenshot shows what I'm getting at...



    (note the first two notes in the table will actually cause a timer 1 overflow and therefore can't be monitored when using a 20Mhz Osc - well not without extra code in the interrupt handler - so I include them only for completeness)


    the frequency of the incoming signal is derived from the the number of comparator interrupts rx'ed for the frequency 'peroid' ...& becuase I want to map the frequency to a midi 'note' - and musical 'notes' are set in stone (ie no such thing a middle C.23) - I therefore also need to establish what the midway count is between successive note 'frequencies' (the note boundary if you like)

    ....but with a LUT 50 deep & with two conditions to check for per LUT entry, eg .....

    Code:
    if (comp1time>= 66194 and comp1time <= 62478) then note = $27
    then if the incoming frequency is changing rapidly (becuase the notes are changing rapidly), then I need to have a fast way of resolving the incoming frequency to a note value.
    Last edited by HankMcSpank; - 3rd October 2010 at 21:06.

  4. #4
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    Well I only count 32 notes, but I'm on my phone so maybe I don't get to see the whole thing.

    That said, A is the last note I see, and it seems there is a count of ~11,000 for that note. So to me that's ~11,000 instructions to waste before a new interupt. That's tons of time if I understand your chart correctly. In any event, I like to get things done fast. My suggestion is a hybrid search. Maybe check the middle, decide higher or lower, then do a linear search from there.

    Now back to the numbers: If each test took 25 instructions and you have 50 tests: that's 1250 instructions. Approx 10% of the time between interupts. So still no prob.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  5. #5
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    Let me just add, 25 instructions is a lot of asm just to check that. See, this is why I want to know how long things take.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  6. #6
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default

    Quote Originally Posted by cncmachineguy View Post
    Well I only count 32 notes, but I'm on my phone so maybe I don't get to see the whole thing.
    Sorry, should have made it clear...the table I posted above is actually longer, but I shortened it to be easier on the eye! (the jist of the table was just to show the methodology of converting incoming frequency (guitar notes), to counts (comparator1 interrupt counts) & finally the end goal - a midi note value.

    the LUT will only have something like this (first two columns are upper and lower comparator 'counts' for each individual musical note boundary)

    Code:
    Lo       Hi       Midi Note 
    62479	58971	28
    58972	55662	29
    55663	52538	2A
    52539	49589	2B
    49590	46806	2C
    46807	44179	2D
    44180	41699	2E
    41700	39359	2F
    39360	37150	30
    37151	35065	31
    35066	33097	32
    33098	31239	33
    31240	29486	34
    29487	27831	35
    27832	26269	36
    26270	24794	37
    24795	23403	38
    23404	22089	39
    22090	20849	3A
    20850	19679	3B
    19680	18575	3C
    18576	17532	3D
    17533	16548	3E
    16549	15619	3F
    15620	14743	40
    14744	13915	41
    13916	13134	42
    13135	12397	43
    12398	11701	44
    11702	11044	45
    11045	10424	46
    10425	9839	47
    9840	9287	48
    9288	8766	49
    8767	8274	4A
    8275	7810	4B
    7811	7371	4C
    7372	6957	4D
    6958	6567	4E
    6568	6198	4F
    6199	5850	50
    5851	5522	51
    5523	5212	52
    5213	4919	53
    4920	4643	54
    4644	4383	55
    4384	4137	56
    4138	3905	57
    3906	3800	58
    There are about 50 individual notes on a guitar - from lowest open E (82.4Hz) thru the highest E fretted at the 24th fret of the top E string (1318.51Hz)....so an LUT will need an array 50 deep & a check condition along these lines for any change in the count value...

    Code:
    if (comp1time>= 66194 and comp1time <= 62478) then note = $27
    but to apply 50 of code like that each & every time guitar note changes is going to get time consuming, hence wanting something like a binary search algorithm for picbasic (a search on the forum yields almost nothing)
    Last edited by HankMcSpank; - 3rd October 2010 at 21:34.

  7. #7
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    based on your chart, I would look first to see if count < 10000. thats the one to take care of the quickest. then check somewhere between 10000 and 65000.

    Of course when you find the range, just use if then like you posted
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

  8. #8
    Join Date
    Aug 2010
    Location
    Maryland, USA
    Posts
    869


    Did you find this post helpful? Yes | No

    Default

    How bout something like this?

    Code:
    'Is this the right symbel for comments?
    'This is what I'm using it for
    '
    'Assuming count is the number to be checked
    '
    'This set of checks breaks it into 3 16 possible chuncks
    
    If count < 3800 then ERROR                            ' count under 3800 must be wrong, but it could mean TMR rolled over
    If (count <= 9288) and (count >= 3800) then LowCount ' 
    If count <= 23404 then MidCount                       ' no need to check lower limit because that was in last check
    if count <= 62479 then HighCount                      ' still no lower check
    
    'now do the same for the each section:
    
    LowCount
    if count <= 4920 then LLowCount
    if count <= 6568 then MLowCount
    ' must be High low count
    'at this point do another chunck break or code for all possibles
    'another chunck break
    
    if count <=8275 then LhLowCount
    'choice of 4 now
    'at this point count MUST be >8275 and <=9288
    
    LhLowCount ' count between 6569 and 8275
    if (count >=6569) and (count <=7372) then note=4D : goto NoteFound
    If (count >=7371) and (count <=7372) then note=4C : goto NoteFound
    if (count >=7810) and (count <=8275) then note=4B : goto NoteFound
    Dose this make any sense? I think there is a problem with your numbers, but it could be me. Seems like high and low of next up note are reversed. For instance note 4D is 7372-6957, and 4C is 7811-7371.
    -Bert

    The glass is not half full or half empty, Its twice as big as needed for the job!

    http://foamcasualty.com/ - Warbird R/C scratch building with foam!

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts