This is an archived, read-only copy of the United-TI subforum , including posts and topic from May 2003 to April 2012. If you would like to discuss any of the topics in this forum, you can visit Cemetech's Your Projects subforum. Some of these topics may also be directly-linked to active Cemetech topics. If you are a Cemetech member with a linked United-TI account, you can link United-TI topics here with your current Cemetech topics.

This forum is locked: you cannot post, reply to, or edit topics. Project Ideas/Start New Projects => Your Projects
Author Message
FloppusMaximus


Advanced Member


Joined: 22 Aug 2008
Posts: 472

Posted: 17 Aug 2009 10:14:52 pm    Post subject:

I'll try it out it a little while. But first... does this program do anything weird to Flash? When I turned my 83+ SE on a little while ago, to try to test this program out, it had mysteriously lost its OS.

It's probably my fault, not GuitCalc's - I'm the sort of person who does weird things to his calculator OS from time to time Smile - but I don't think I've done anything all that unusual to this calculator recently. Maybe having those giant archived files caused some weird glitch?

Edit: Oi, this is definitely not your fault. I just finished installing the OS, and a minute later - without my doing anything else - it jumped back to "Please install calculator software." WTF? Sad


Last edited by Guest on 17 Aug 2009 10:16:11 pm; edited 1 time in total
Back to top
Seren


Newbie


Joined: 14 Aug 2009
Posts: 27

Posted: 17 Aug 2009 10:26:38 pm    Post subject:

Well, just to reassure you, it does not directly modify the Flash (just reads from it). Otherwise it makes use of the Arc_Unarc bcall.

Well, we are all hoping for a fast recovery from your calculator! It's never nice to see the poor things get ill Sad.

Edit:
Now I'm thinking about how I would like to compress the sound. A quick scan of the hex values in the AppVars shows that it is very rare that the same byte of information appears in sequence (generally just before a song starts/after the end, when there is no music).

However, if you take a look at the frequency of each individual hex value from 3 different AppVars (includes the header & checksum of the files, but those a negligeable):



Certain combinations (notable $AA and $55) appear much more often than others (the image on the right is at the end of the song, where there is silence, hence the abundance of $AAs.

I believe that RLE would be pretty useless, given the scattered nature of the values.
On the other hand, I think I've read about something called Huffman compression... yup (http://en.wikipedia.org/wiki/Huffman_coding).

This means that, to sum it up, common bytes will be represented in 2-3 bits ($AA appears about 5000 times per AppVar), while the ones you almost never see ($CA appears 0 times in the topleft chart, 22 times in the one on the right, and 1 time in the bottom one) take up a lot more space (such as 10-15 bits).

Has anyone experimented with Huffman compression before?

It's generally divided into two parts
-The first part is of variable length, generally all composed of 1 bits
-The second is a set length composed of either 0s or 1s

So

Let's say the second part is 3 bits long, then the following sequences of bits would each represent a specific byte


Code:
Example Huffman Table
000     $AA     Most common bytes (4000-5000) - saving about 5625 bytes here
001     $55
010     $00     Next most common (1000-3000) - and about 7000 bytes here (however I'd be losing bytes on the less common combinations)
011     $56
1-000     $5A
1-001     $6A
1-010     $95
1-011     $A5
11-000     $A9
11-001     $FF
11-010     $01     Not rare (500-1000)
11-011     $05
111-000     $15
etc.


What I would like to do is convert a bunch of songs (perhaps 15 or so), then sum up the frequency of each value in all of the individual AppVars to discover what appears in the greatest frequency and generate a static Huffman table that will be used for every single song (hardcoded into the program - but they all follow the same pattern so not too much should be lost due to differences in frequency in different songs). Then I'd experiment with various lengths for the second part of a compressed piece of information.

How does that sound?

To keep up with decompression without adding extra processing cycles in the game engine while running the song live, I have to be able to decompress a byte of information in slightly over 1000 cycles - which I believe is probably do-able (if not, then I could add an extra cycle)


Last edited by Guest on 17 Aug 2009 11:18:36 pm; edited 1 time in total
Back to top
FloppusMaximus


Advanced Member


Joined: 22 Aug 2008
Posts: 472

Posted: 18 Aug 2009 12:38:31 am    Post subject:

I wouldn't expect plain Huffman coding on the data bytes would give you that much of an advantage, but try it and see, I guess. I would give RLE a try, perhaps using a variable length code (such as an Elias code) for the run lengths.

Here's an idea I had recently; I don't know how workable it is or how much compression you could expect to get out of it. Break down the input signal into a sum of square wave pulses, each of height 1. Basically, it's RLE compression where runs can overlap. That is to say, if you had the input sequence
0, 0, 1, 1, 2, 2, 2, 2, 1, 0, 1, 1, 1, 0
you could encode it as
(2, 7), (4, 8), (10, 12)
meaning "add 1 to all values between t=2 and t=7, then to all values between t=4 and t=8, then to all values between t=10 and t=12." With the right data format, this would, I think, lend itself to quick, constant-time decompression. I don't know how efficient it would be at compressing real data, though.


Last edited by Guest on 18 Aug 2009 12:39:07 am; edited 1 time in total
Back to top
fullmetalcoder


Member


Joined: 01 Aug 2009
Posts: 139

Posted: 18 Aug 2009 04:15:39 am    Post subject:

failed to launch the latest version. well it reached the splash screen but stayed there and any keypress cause a return to MirageOS... (I have the "1", "A", "B", "C", "D" and "E" appvar in flash).

as for compression I think Huffman nibble is a good candidate. Using nibbles (4bits) may slightly decrease the compression rate (it imposes a maximum of 50%) but it should allow for vastly improved decompression code (yay RLD and RRD). Also Huffman is quite flexible and you could try to change it to compress sequence of two (or more) bytes if it make sense (depends on the file format I guess) so a nibble would not repesent a byte but a word which would cap the compression rate at 25% but requires a "proper" distribution of words.

I think a pretty good huffman-like scheme would be something like (nibble are one hex digit)
* 0-D : compressed value of the 14 most common bytes (50% gain)
* E : indicate a two nibbles (one byte) compression (no gain, no loss) followed by 0-F (15 other common values)
* F : indicate an uncompressed byte, followed by the byte in question (33% loss for all values except thee 29 most common ones)

I had planned writing a huffman-nibble routine already and I might do it sooner than planned if you're interested.
Back to top
ztrumpet


Active Member


Joined: 06 May 2009
Posts: 555

Posted: 18 Aug 2009 08:28:20 am    Post subject:

Wow, that's great! The sound quality is vastly improved. Although if you could, make it better yet. (I heard real sound...)

How may minutes of music dose a SE hold? (uncompressed)

Edit: What if when you compressed each song you found the most often bytes used and at the beggining of SongNameA you had a table showing what each of these represented?


Last edited by Guest on 18 Aug 2009 08:35:50 am; edited 1 time in total
Back to top
Seren


Newbie


Joined: 14 Aug 2009
Posts: 27

Posted: 18 Aug 2009 11:59:29 am    Post subject:

FloppusMaximus wrote:
I wouldn't expect plain Huffman coding on the data bytes would give you that much of an advantage, but try it and see, I guess. I would give RLE a try, perhaps using a variable length code (such as an Elias code) for the run lengths.

Here's an idea I had recently; I don't know how workable it is or how much compression you could expect to get out of it. Break down the input signal into a sum of square wave pulses, each of height 1. Basically, it's RLE compression where runs can overlap. That is to say, if you had the input sequence
0, 0, 1, 1, 2, 2, 2, 2, 1, 0, 1, 1, 1, 0
you could encode it as
(2, 7), (4, Cool, (10, 12)
meaning "add 1 to all values between t=2 and t=7, then to all values between t=4 and t=8, then to all values between t=10 and t=12." With the right data format, this would, I think, lend itself to quick, constant-time decompression. I don't know how efficient it would be at compressing real data, though.

The progression of my data files are so chaotic that I really doubt that any encoding based on a range of data would not work well at all, I'm afraid. Your previous example uses 14 numbers = 28 bits = 3.5 bytes, while you use 6 numbers to represent it (and how much room must each number take up? 2 bytes for address + 3 bits to specific which bit in the byte to start at?)

And I thought Huffman was a form of variable length code... isn't it?

fullmetalcoder wrote:
failed to launch the latest version. well it reached the splash screen but stayed there and any keypress cause a return to MirageOS... (I have the "1", "A", "B", "C", "D" and "E" appvar in flash).

as for compression I think Huffman nibble is a good candidate. Using nibbles (4bits) may slightly decrease the compression rate (it imposes a maximum of 50%) but it should allow for vastly improved decompression code (yay RLD and RRD). Also Huffman is quite flexible and you could try to change it to compress sequence of two (or more) bytes if it make sense (depends on the file format I guess) so a nibble would not repesent a byte but a word which would cap the compression rate at 25% but requires a "proper" distribution of words.

I think a pretty good huffman-like scheme would be something like (nibble are one hex digit)
* 0-D : compressed value of the 14 most common bytes (50% gain)
* E : indicate a two nibbles (one byte) compression (no gain, no loss) followed by 0-F (15 other common values)
* F : indicate an uncompressed byte, followed by the byte in question (33% loss for all values except thee 29 most common ones)

I had planned writing a huffman-nibble routine already and I might do it sooner than planned if you're interested.


Hmm... are you sure that it's in Flash? The only reason why it would kick you out after the splash is if it does not detect any song files (not the sound - so you need to make sure that the "1" AppVar is in the archive). The other time it would kick you out would be before seeing the splash if you have a 15 mHz incompatible calculator (Ti-83+ BE).

-

Well, no thanks for writing your own routine, because my routine will probably not make use of loops as I need to clock the exact time it takes, leading to some pretty awkward code which will have to be based on whatever specific format I use.

Did a quick calculation using your Huffman scheme and
50% will be compressed (-4)
20% will have no gain, no loss (0)
30% will lose space (+4)

Which means it would end up with approximately 20% compression using your scheme. I'll figure out more precise values for all of my bytes and experiment a bit today to try and figure out how much I would be able to compress max with Huffman.

ztrumpet wrote:
Wow, that's great! The sound quality is vastly improved. Although if you could, make it better yet. (I heard real sound...)

How may minutes of music dose a SE hold? (uncompressed)

Edit: What if when you compressed each song you found the most often bytes used and at the beggining of SongNameA you had a table showing what each of these represented?


83+: Ram-24KB Rom-160KB = 1:20 (but it is not supported as it cannot run at 15 mHz)
83+SE: Ram-24KB Rom-1.5 MB = 12:30 (a couple of your favourite songs, and you could play other songs in silent mode)
84+: Ram-24KB Rom-480KB = 4:00 (1 song, if it isn't one of the longer ones)
84+SE: Ram-24KB Rom-1.5MB = 12:30 (like the other SE)

With 20% compression you would have an extra 3 minutes on the SE, and an extra minute on the 84+, and an extra 20 seconds on the Ti-83+

So I don't want to make it better, really, as the music is very clearly audible, even though there is some distortion with it, because then you wouldn't be able to play any songs. The reason why it's worse than RealSound is that it uses 2-bit sound instead of 8-bit sound. (and the information is stored at 8.000 kHz, while RealSound can go up to 32 kHz)

Oh, and if I had a different Huffman table for each song file, it would work, but it would be a lot faster & simpler to just have 1 universal table for all songs (and as you saw in the image in my previous post, in the different files, all the different bytes follow in general the same frequency everywhere)


Last edited by Guest on 18 Aug 2009 12:05:18 pm; edited 1 time in total
Back to top
fullmetalcoder


Member


Joined: 01 Aug 2009
Posts: 139

Posted: 18 Aug 2009 12:33:29 pm    Post subject:

Finally managed to make it run (the difficulty file was not archived...)

As for compression, here's a quick draft (untested, not even sure it compiles...) using the scheme I described above. As you can see it uses loops but it is easy to remove those loops (which would free a 16bit register and signifcantly increase the speed). Also I you want to use a static huffman table you could optimize it even more (and possibly not need shadow regs anymore). Note that there is now way to have constant time decompression unless you pad the fastest path with useless instructions to adjust the timing (nop, complementary push/pop...)


Code:
;
; Huffman nibble decompression routine, written in a hurry and UNTESTED (got to write a
; compression routine as well to test it...)
;

; compressed data structure :
; * 0-D : compressed nibble
; * E : var length compressed (i.e the byte to compress end up taking a byte) followed by a nibble
; * F : uncompressed byte

; Huff table struct : 30 bytes, in that order
;   * the 14 most common bytes in the uncompressed data to which are assigned the 0-D representation
;   in the compressed data
;   * the 16 next most common bytes in the uncompressed data to which are assigned the E0-EF
;   representation in the compressed data

; hl -> compressed data
; bc -> size of compressed data
; de' -> buffer to hold decompressed data
; hl' -> huffman table (30 bytes)
; b' -> 0
; d -> 2
; !!! require interrupts disabled !!!
; destroys : af, bc, de, hl, af', bc', de',  hl'

; timing per byte decompressed :
; bounds : 119-243
; inaccurate average : ~196
;
; accurate timing require a knowledge of the distribution of the three branches
; in the compressed file so it is impossible to do generally but we know for
; sure that branch 1 (the quickest, yay!) is going to be the most frequent,
; followed by branch 2 and then branch 3.
; slightly more accurate average :
;   * frequencies : b1 = 0.5 | b2 = 0.2 | b3 = 0.3 [estimation for GuitCalc]
;   -> ~189
;
; to compute a really accurate timing, one must actually consider not only the frequencies
; of branching but also the probability for the processed nibble to be aligned. This is not
; undoable but just compilcated enough that I won't do it right now...
;
huff.decomp:
   di
   xor   a
huff.decomp.loop:
; common : 35
   rld      ; 18
   cp   $0E   ; 7
   jp   nc, huff.decomp.special; 10
   
; branch 1 : 84/166 : avg = 125 per compressed nibble
   
   exx      ; 4
   ld   c, a; 4
   add   hl, bc; 11
   ex   af, af'; 4
   ld   a, (hl); 7
   or   a   ; 4
   sbc   hl, bc; 15
   ld   (de), a; 7
   ex   af, af'; 4
   inc   de   ; 6
   exx      ; 4
   
   dec   d   ; 4
   jp   nz, huff.decomp.loop; 10
; one byte done
   dec   bc   ; 6
   ex   af, af'; 4
   ld   a, b; 4
   or   c   ; 4
   ret   z   ; 5 (11 when cond true)
   ex   af, af'; 4
   rld      ; 18
   inc   hl   ; 6
   ld   d, 2; 7
   jp   huff.decomp.loop; 10
   

huff.decomp.special:
   rrca   ; 4
   jp   c, huff.decomp.uncompressed; 10
   
; branch 2 : 14 + 22 + 37/0 + 110 + 0/68 -> 183/214 : avg = 199 per compressed nibble
   
   rlca   ; 4
   ld   e, a; 4
   dec   d   ; 4
   jp   nz, huff.decomp.special.samebyte; 10
; extended nibble was the lower nibble : go to next byte to find the other nibble
; restore input (compressed) byte
   rld      ; 18
; update counters, don't bother checking for bc = 0 here, that would mean corrupt data...
   dec   bc   ; 6
   inc   hl   ; 6
   ld   d, 2; 7
huff.decomp.special.samebyte:
   rld      ; 18
   add   a, e; 4
   
   exx      ; 4
   ld   c, a; 4
   add   hl, bc; 11
   ex   af, af'; 4
   ld   a, (hl); 7
   or   a   ; 4
   sbc   hl, bc; 15
   ld   (de), a; 7
   in   de   ; 6
   exx      ; 4
   
   ex   af, af'; 4
   sub   e   ; 4
   
   dec   d   ; 4
   jp   nz, huff.decomp.loop; 10
   rld      ; 18
   inc   hl   ; 6
   ld   d, 2; 7
   dec   bc   ; 6
   ex   af, af'; 4
   ld   a, b; 4
   or   c   ; 4
   ret   z   ; 5 (11 when true)
   ex   af, af'; 4
   jp   huff.decomp.loop; 10

huff.decomp.uncompressed:
   rlca   ; 4
   dec   d   ; 4
   jp   nz, huff.decomp.uncomp.split; 10
   
; branch 3 : 32 + 105/149 : avg = 159 per nibble
   
; extended nibble was the lower nibble : go to next byte to find the other nibble
; restore input (compressed) byte
   rld      ; 18
; update counters, don't bother checking for bc = 0 here, that would mean corrupt data...
   dec   bc   ; 6
   inc   hl   ; 6
   ld   d, 2; 7
   
; uncompressed byte is aligned on byte boundary, yay!
   ld   a, (hl); 7
   inc   hl   ; 6
   dec   bc   ; 6
   
   exx      ; 4
   ld   (de), a; 7
   inc   de   ; 7
   exx      ; 4
   
   ld   a, b; 4
   or   c   ; 4
   ret   z   ; 5 (11 when cond true)
   xor   a   ; 4
   jp   huff.decomp.loop; 10
   
huff.decomp.uncomp.split:
; uncompressed byte is split accross two bytes, damn!
   
   rld      ; 18
   ld   e, a; 4
   sla   e   ; 8
   sla   e   ; 8
   sla   e   ; 8
   sla   e   ; 8
   rld      ; 18
   inc   hl   ; 6
   dec   bc   ; 6
   rld      ; 18
   xor   e   ; 4
   exx      ; 4
   ld   (de), a; 7
   inc   de   ; 7
   exx      ; 4
   xor   e   ; 4
   ld   d, 1; 7
   
   jp   huff.decomp.loop; 10
Back to top
Seren


Newbie


Joined: 14 Aug 2009
Posts: 27

Posted: 18 Aug 2009 12:56:32 pm    Post subject:

Well, the shadow registers are already locked up, but given that I have +- 1000 cycles to decompress a single byte it shouldn't be a problem. I'll look through your code and see what I can do (after figuring out more precisely which bytes are more common etc.)

I've never used RRD or RLD, so just to confirm...

RLD:

(hl)=$AB
a=$CD

changes to

(hl)=$BD
a=$CA

?

And I know all about delays... this is my most often used function:


Code:
wait159:
   nop
wait155:
   nop
wait151:
   nop
wait147:
   nop
wait143:
   nop
wait139:
   nop
wait135:
   nop
wait131:
   nop
wait127:
   nop
wait123:
   nop
wait119:
   nop
wait115:
   nop
wait111:
   nop
wait107:
   nop
wait103:
   nop
wait99:
   nop
wait95:
   nop
wait91:
   nop
wait87:
   nop
wait83:
   nop
wait79:
   nop
wait75:
   nop
wait71:
   nop
wait67:
   nop
wait63:
   nop
wait59:
   nop
wait55:
   nop
wait51:
   nop
wait47:
   nop
wait43:
   nop
wait39:
   nop
wait35:
   nop
wait31:
   nop
wait27:
   ret
Back to top
fullmetalcoder


Member


Joined: 01 Aug 2009
Posts: 139

Posted: 18 Aug 2009 01:29:13 pm    Post subject:

Seren wrote:
Well, the shadow registers are already locked up, but given that I have +- 1000 cycles to decompress a single byte it shouldn't be a problem. I'll look through your code and see what I can do (after figuring out more precisely which bytes are more common etc.)

1K cycles per decompressed byte? well that's quite a lot of room you have here. A couple of push/pop are affordable and together with the drop of the loop counter it'll be extremely easy to get rid of shadow regs.

Seren wrote:
I've never used RRD or RLD, so just to confirm...

RLD:

(hl)=$AB
a=$CD

changes to

(hl)=$BD
a=$CA

?

Exactly.

Seren wrote:
And I know all about delays... this is my most often used function:


Code:
wait159:
   nop
wait155:
   nop
wait151:
   nop
wait147:
   nop
wait143:
   nop
wait139:
   nop
wait135:
   nop
wait131:
   nop
wait127:
   nop
wait123:
   nop
wait119:
   nop
wait115:
   nop
wait111:
   nop
wait107:
   nop
wait103:
   nop
wait99:
   nop
wait95:
   nop
wait91:
   nop
wait87:
   nop
wait83:
   nop
wait79:
   nop
wait75:
   nop
wait71:
   nop
wait67:
   nop
wait63:
   nop
wait59:
   nop
wait55:
   nop
wait51:
   nop
wait47:
   nop
wait43:
   nop
wait39:
   nop
wait35:
   nop
wait31:
   nop
wait27:
   ret

masterpiece of engineering! :biggrin:
Back to top
Seren


Newbie


Joined: 14 Aug 2009
Posts: 27

Posted: 18 Aug 2009 02:05:08 pm    Post subject:

Well, so my next few steps are:

√ Made a mistake in counting the amount of clock cycles at one point, so I have just adjusted that.
√ Calculated the speed of the song: it runs at about 104% speed
√ Adjusted the engine to slow it down a bit - inversely, now there is more time to update the game & decompress.
√ Chose 16 songs to use for analysis in compression
√ Converted the 16 songs into AppVars
√ Wrote a Visual Basic program to analyze all the files and sum up the frequency of each value (ignoring the header & checksum)
√ Determined an optimal Huffman table (or other)
√ Integrated a compression routine in my AppVar-creation program
√ Integrated a decompression routine in Guitar Calculator
χ Re-integrating the game into Guitar Calculator

Edit: Here's a discovery - when I write to the LCD with a delay of 143 (inbetween each output), occasionally (perhaps 1% of the time), the delay is too short and the information isn't sent.

Edit: Here's 15 more songs in the 2-bit version. I haven't actually listened to them yet, but there's no reason why they shouldn't work.

Edit: I figured out the frequencies of each hex value. $AA tops the chart, appearing 1086796 times (14.2% of the time), while the least common possibility is $33, appearing 7 times (0.000091% of the time).

Edit: Following fullmetalcoder's method, I determined the most efficient method (compressed to 76% - WinZip at Best compression managed 65%) to be:


Code:
0-A     1 nibble byte
B-E     2 nibble byte
F     3 nibble byte


Notice how I have only 11 bytes that are compressed, and 64 that do not lose space, as opposed to 14 and 16.


Last edited by Guest on 19 Aug 2009 09:06:48 pm; edited 1 time in total
Back to top
fullmetalcoder


Member


Joined: 01 Aug 2009
Posts: 139

Posted: 18 Aug 2009 07:20:52 pm    Post subject:

Seren wrote:
Edit: Here's a discovery - when I write to the LCD with a delay of 143 (inbetween each output), occasionally (perhaps 1% of the time), the delay is too short and the information isn't sent.

the LCD delay is supposed to be ~10µs so about 150T-states in 15Mhz mode. If you want to be on the safe side on SE calculators you can use the LCD delays port ($29, $2A, $2B and $2C, see wikiti for details)

Seren wrote:
Edit: I figured out the frequencies of each hex value. $AA tops the chart, appearing 1086796 times (14.2% of the time), while the least common possibility is $33, appearing 7 times (0.000091% of the time).

Edit: Following fullmetalcoder's method, I determined the most efficient method (compressed to 76% - WinZip at Best compression managed 65%) to be:


Code:
0-A     1 nibble byte
B-E     2 nibble byte
F     3 nibble byte


Notice how I have only 11 bytes that are compressed, and 64 that do not lose space, as opposed to 14 and 16.

Stripping about one fourth of the song size is a good improvement already but since you got as many as 1k spare T-states it might be possible to use some more elaborate compression schemes (LZ family for instance) but they would probably be more challenging to adapt to your needs...
Back to top
Seren


Newbie


Joined: 14 Aug 2009
Posts: 27

Posted: 18 Aug 2009 09:39:17 pm    Post subject:

fullmetalcoder wrote:
the LCD delay is supposed to be ~10µs so about 150T-states in 15Mhz mode. If you want to be on the safe side on SE calculators you can use the LCD delays port ($29, $2A, $2B and $2C, see wikiti for details)

As far as I understood it, changing that port increased the amount of clock cycles it took to do the in/out operations. http://www.geocities.com/jimm09876/calc/port29.html

fullmetalcoder wrote:
Stripping about one fourth of the song size is a good improvement already but since you got as many as 1k spare T-states it might be possible to use some more elaborate compression schemes (LZ family for instance) but they would probably be more challenging to adapt to your needs...


Well yes, but I myself am satisfied to be compressing at, on average, 70% of WinZip's efficiency. My compression routine works now, and I'm not inclined to change compression methods again Razz. I also don't believe LZ would compress well unless combined with other methods - and then it would be a lot more complicated and long Sad.

Edit:
I got Guitar Calculator to decompress compressed files during runtime (see attached files). Next I'll work on re-integrating the game (and perhaps adding hammer-ons & the thing where you hold down on the note).


Last edited by Guest on 19 Aug 2009 10:27:56 pm; edited 1 time in total
Back to top
Seren


Newbie


Joined: 14 Aug 2009
Posts: 27

Posted: 03 Sep 2009 04:32:45 pm    Post subject:

I finished updating the code to support the 15 mHz processor, and I must say that it looks a lot better (the notes flow smoothly down the screen instead of the jerking you occasionally saw at 6 mHz, for example). The sound quality is a lot better.

All my newer files etc. are at http://www.omnimaga.org/index.php?topic=1013.0

Does anyone know the file format for Frets on Fire (so that we could have an easy conversion from their large database of songs for GuitCalc)?
Back to top
Madskillz


Active Member


Joined: 02 Jan 2004
Posts: 608

Posted: 15 Sep 2009 10:21:16 pm    Post subject:

Something interesting caught my eye while reading through engadget this morning...

here it is

I dont know if it was just something they threw out there, but I thought the little mention of a guitar hero on a graphing calculator had to be a little nudge your way.


Last edited by Guest on 16 Sep 2009 09:40:19 pm; edited 1 time in total
Back to top
DigiTan
Unregistered HyperCam 2


Super Elite (Last Title)


Joined: 10 Nov 2003
Posts: 4468

Posted: 15 Sep 2009 11:29:14 pm    Post subject:

When all this is finished, you should ask MysteryGuitarman to do one of those crazy videos about this!
Back to top
Display posts from previous:   
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
    » Goto page Previous  1, 2, 3
» View previous topic :: View next topic  
Page 3 of 3 » All times are UTC - 5 Hours

 

Advertisement