Thursday, December 12, 2013

Code Site

Holy Shit, I finally found the internet sweet-spot in my apartment... unfortunately I have to straddle my computer to take a leak, but it's worth it.

So I've finally set up a code-site for my projects... or at least my most current one.
341x768 on a laptop display via an 8-bit AVR. Two-ish years' work getting this to this point!

https://code.google.com/p/avr-lvds-lcd/


and more pics at:
GeekAttempts Site

Friday, December 6, 2013

The Latest


It's been a while since I posted... my internet connection has been too flakey for months. And my combo of old and new technologies always leaves me a bit out of the loop.

In the meantime I've done quite a bit.

iBook G4 12in LCD upgrade
This thing came with 1024x768... my old system (which was stolen) had 1600x1200, so needless to say I was feeling a bit cramped.
Managed to locate a 12in 1400x1050 display on ebay for $30 that wouldn't work directly with this computer. (Details: This display is "dual-pixel" meaning it expects to receive two pixels at a time, rather than one... requiring entirely different circuitry and wiring. Managed to find parts via TI that could make the conversion... yep, it's not only doable; I've designed a circuit-board and have been using it for nearly a year now. 1024x768 was a bitch. Took a bit of effort, besides the circuit. I'm proud of that, too. The screen itself wasn't the same mounting, but when the housing was removed, it fit inside the old display's housing. All in all it was probably $50 worth of parts, including the display... Someone online had found another display that worked immediately, even used that display is still selling for nearly $200; so this was a bit more of a challenge. Had to create a fake EDID chip and figure out all the timing, etc. Huge process, I should probably document it better. For several months I used a hand-wired converter-circuit. Lots of tiny wires soldered directly to TQFP pins; I have no idea how it worked so well for so long. The PCB squeeked out a few more Hz refresh-rate, but isn't nearly as impressive... anyone with as much experience as I have can make a PCB!)

---
yeahp, tried to upload a pic, but the net's still too flakey.
----

The display came from an old "PenEnabled" computer, an old Windows Laptop/Tablet in the era before tablets were mainstream. So I also made the necessary circuitry to use the built-in Wacom tablet on my mac. It involved stealing 12V from the LCD inverter (which blew the fuse and was a pain to replace), voltage-regulators, and a simple AVR circuit to interface between the tablet and a bluetooth transmitter. Worked great, but the tablet itself was a bit wider than the bezel, so after months of leaving the display-housing off, I decided to remove it.
In other related-bits, took a bit of effort but managed to compile the latest GIMP on my PPC so I could use the tablet... even though I only used it a few times. It was nice, though... pressure-sensitive, etc.

LCD/AVR Interface
Apparently I'm somewhat fixated on the idea of using old laptop LCDs with AVR processors.
With quite a bit of hacking, I've managed to drive "FPD-Link" (LVDS) signals via an AVR, using PWM, no less. The latest status is about 1Hz refresh-rate with 341x768 resolution at 48 colors on a 1024x768 display. Leads to some interesting abilities and equally interesting limitations. Also tons of hacking was involved... all *extremely* rigorously documented in my code.
As it stands, I've a pretty decent "Mario Brothers" style Question-Box, which I ultimately intend on hanging somewhere... when you hit the underside, a random award will be displayed (1-up, Biggie, Flower-Power, Invincibility... and the occasional Goomba which you have to hit again to kill). It's *done* code-wise, now I just need to make the box, a robust and reliable "hit-switch," and figure out how to power it wherever I hang it.
I've also created a game ala "Racer" from the ol' TI-82 days... a course is laid out and as the screen slowly refreshes, you have to stay in the track... Sounds slow at such refresh-rates, but actually it's somewhat stimulating.
I've a few other ideas of "games" that can make use of such a slow, but high-resolution, display... one is "Story-board Mario"... showing snapshots of your progress as you go, multiple "story-boards" displayed in each refresh. It could *almost* be real-time like the original Super Mario Bro's itself, just in story-board fashion.

AVR/SDRAM (Free-Running)
I've also managed to figure out a way to connect an old SDRAM to an AVR in such a way that the entire memory can be output in a single (or repeated) burst... After the AVR is done loading the memory, the SDRAM itself is responsible for its own control and addressing... I call it "Free-Running Mode," where several of the SDRAM outputs are fed directly back into its inputs (command-signals, address-signals, etc).
I've used it to drive the same LCD, at full resolution and full-color... refresh-rates limited only by the SDRAM's clock-rate, which currently is (though needn't be) limited to the AVR's clock. Though, if you do the math, 1024x768x7 (x7 because there are 7bits in each LVDS transaction) leads to quite a bit of loading from the AVR, so this particular system is best-suited to stationary images, or those that change only a few pixels between each refresh.
Other possibilities include using the SDRAM as a high-bandwidth logic-analyzer (32bits, easily, probably 133MS/s for a few seconds, depending on the RAM size), and more.
The latest design uses no external components, just an SDRAM card and an AVR, oh and a crystal oscillator.
Other design-improvement ideas involve:
Using the SDRAM to completely control itself after loading a few basic instructions from the AVR... e.g. "write" and "read" as well as "nop." Possibly the SDRAM could generate its own clock signal, though this is a bit of a stretch.
These involve splitting the SDRAM into different "banks", one which is responsible for control, and another for actual data I/O.

Quite a bit was learned in each of these projects as far as (undocumented) abilities and limitations of these systems... For example:
SDRAM is supposed to be refreshed, in entirety, every 64ms... but realistically can last for several seconds without a refresh. Further, rather than using explicit "refresh" commands, simply opening and closing a memory-location is enough to refresh that location. This leads to some nice work-arounds; a typical "refresh" command requires that the entire memory be "closed;" meaning that the memory could no longer directly control itself... but it *can easily* open and close its own memory locations while doing other things in "free-running mode."
Similarly, LCDs are specified as having required timings WAY FASTER than an AVR can accomplish... but they also have technologies that accommodate being pushed well-beyond their documented limits. Because TFT displays have, essentially, memory at every pixel, refresh rates of 1Hz, or even 1/5Hz are achievable (on displays which allow out-of-range timing-signals, again completely undocumented). The image is held between each refresh by the transistor on each pixel.

And pushing things in ways they were never intended:
"FPD-Link" (aka LVDS) compatible signals can be generated via an AVR's PWM outputs, no joke. Since many signals are repeated multiple times, (e.g. "Horizontal Sync") it requires loading a PWM value, and allowing it to repeat while the processor is used for other (e.g. image-generation) tasks. Using the "Dead-Time Generator" on these PWM signals allows for creating *almost* serial data for the FPD-Link signal. A bit of hacking reveals that 48 colors distributed almost evenly across the whole range are possible by simply timing the different PWM signals with different start and stop times. 

Likewise, the PWM signals on this particular AVR can be run at frequencies much higher than the AVR's clock signal... The ATtiny861 is specified to run at 8MHz, and its PWM signals at 64MHz, but manipulation of some registers and fuses can push it to 16MHz and PWM at 128MHz... 128MHz FPD-Link is nearly the specification. So, if resolution (which is entirely dependent on the AVR's processing abilities) isn't a concern, the screen itself could be refreshed at nearly its specified rates.
Personally, I've found that a display flickering at 30Hz is less pleasing to the eye than one with a visible scrolling refresh every second... And the higher resolution is a big plus.

Another hack was due to the memory-limitations on the AVR... 512Bytes of RAM doesn't allow for full-screen frame-buffer. In fact, it can't even handle an entire row. So, instead of storing data in a frame (or row) buffer, I've opted for a "Row-segment buffer" wherein a row's image-data is stored as segments with a color-value and a value representing the number of pixels.
This works great for images where in a single row there isn't much change... But text, for instance, has a shitton of color-changes between each character, and even within a character. A simple solution is rotating the display (and text) 90 degrees. In the most complicated of characters, there might be 6 color-changes vertically, and since each "row-segment buffer" can handle something like 64 separate segments, we have no issue displaying several rows (separate from display-rows) of dense text in columns, where each LCD "row" is now a column, each "row-segment" is now a column-segment. This is getting hard to explain.

Anyways, the point is, there's quite a bit that can be done to make use of a display at 1Hz refresh with 341x768 usable pixels, 48 colors, and only 512Bytes of RAM...

Oh, a further hack... LVDS requires weird voltage-ranges, as far as most devices are concerned... AVR's output roughly 1=V+ and 0=0V, where V+ is usually 3.3V or 5V, but LVDS requires a differential voltage with about 1V peak-to-peak... This has been found to be easily accomplished with standard TTL IC's, from the 1980's, no-less. By loading the outputs with an LVDS load (100-ohm resistance between the - signal and the + signal), the voltage-levels output by the TTL chips are right within range. Yes, this is stressing the chips quite a bit. These TTL LS chips are rated for 5V, and I'm running them at 3.3V, the outputs are specified to drive *way lower* loads than specified, but, amazingly, pushing them way outside their specified-ranges, the outputs seem to be darn-near *exactly* what's required by LVDS. (It's almost like LVDS was designed around out-of-range TTL chips?!).

Taking a step back... what else have I worked on recently...?

Audio-recording with an AVR to an SD card...
Nokia LCD display <- AVR
Hacking an old Nokia phone for keypad entry via a single AVR analog-comparator input.
Transferred a bunch of VHS's to AVI's
Experimented with (and determined damned-near-useless) Windows XP-64 on a computer found in my building's "free-section"
Determined the "ol' Plasma" to be a fruitless venture, but using its Tuner for my ol' tube TV to get HDTV stations.
Have an old XBox360 that has a flakey DVD drive, been trying to repair it repeatedly... seems to be an alignment issue (the gliders the head rides on seem to be askew) combined with a laser adjustment issue (those danged potentiometers seem to adjust perfectly for one DVD, but not for the next)... can't afford a new drive, so if nothing else, it's a good system for watching AVI's on.
Hey that XBox controller I bought is better than just for watching movies! Someone hacked a driver for MacOS to use it as a joystick... so I've been getting some ol' NES time in via Mednafen. Super Mario Bro's is way too frustrating, what with the need to restart from scratch every time you die... I suppose I could learn to use Mednafen's Save-State, but haven't yet.

This list, of course, is limited to my geekish-endeavors... There's plenty more going on in my life... Like fighting for causes that would be lost-causes except you can't call something a lost-cause if no one except you is fighting for 'em in the first place. Or, like, going to a bar I thought I had friends at, only to find out someone's dropped something in my drink and waking up in the hospital... and receiving a bill for half a year's income. Or, like, being flat-out-manipulated by people you consider friends. So, yeah, let's keep this geekish... I'm proud of my accomplishments.

Oh I forgot one...
My PBG4's keyboard was falling apart... missing several keys... etc. Discovered that the ol' PBG3 keyboard I had laying around was, in fact, pin-compatible... except for one thing... well, a dozen really. First: It was reversed... yeahp. Sounds like a simple fix, but these ribbon-cables can't be soldered-to, and certainly aren't long enough to twist. Managed to solder up an adaptor that *just fit* in the space available. Tons of tiny wires. But, Sweet. Had to cut a few pieces off the computer's housing to get it to fit (it's just *slightly* wider than the original). Did a few hacks here and there to get it to hold-in relatively well... It's a bit gummy-feeling, since it's not really mounted right, but overall it's certainly better than before. 

Oh, and this AMD64 I found in the "free-section" is a bit of a joke, but maybe I'll do something with it. I pieced together a couple machines that were sitting there, so now it's in a D-Vine "Home Entertainment PC" case, which could be groovy. Trying to download linux, let's see what this Mint thing is all about... (Lessee, I started on Slackware in middleschool, Debian in highschool, Ubuntoo recently on my PBG4 which I removed... was thinking about Arch, but apparently it's *heavily* dependent on a reliable net connection which I don't have...) A few more days' downloading and I might have a DVD image to burn.

It's a strange position to be in... having once had Cable Internet when others were still using dialup (or didn't even have internet at all), now being happy with 10KB/s downloads... nah *ecstatic* if I get 10KB/s, while all those "the internet is for geeks" folks are surfing YouTube on their phones...

And, since we're ranting... how is it that mainstream opensource distributors aren't even capable of something so ubiquitous as download-resume...?! And is there *anything* that exists anymore without a net-based-installer? I had to search for hours to find a distro that *might* install without reliable internet... Seriously... If I live in a first-world country, in the firstest-of-worlds communities and can only get flakey internet... how are people getting by elsewhere?! I mean, seriously... I can't even upload an image without the site crashing... Thankfully somehow it saved a draft! 'cause I've been getting a shitton of this:  "
An error occurred while trying to save or publish your post. Please try again. Dismiss"

The Latest...

It's been a while since I posted... my internet connection has been too flakey for months. And my combo of old and new technologies always leaves me a bit out of the loop.

In the meantime I've done quite a bit.

iBook G4 12in LCD upgrade
This thing came with 1024x768... my old system (which was stolen) had 1600x1200, so needless to say I was feeling a bit cramped.
Managed to locate a 12in 1400x1050 display on ebay for $30 that wouldn't work directly with this computer. (Details: This display is "dual-pixel" meaning it expects to receive two pixels at a time, rather than one... requiring entirely different circuitry and wiring. Managed to find parts via TI that could make the conversion... yep, it's not only doable; I've designed a circuit-board and have been using it for nearly a year now. 1024x768 was a bitch. Took a bit of effort, besides the circuit. I'm proud of that, too. The screen itself wasn't the same mounting, but when the housing was removed, it fit inside the old display's housing. All in all it was probably $50 worth of parts, including the display... Someone online had found another display that worked immediately, even used that display is still selling for nearly $200; so this was a bit more of a challenge. Had to create a fake EDID chip and figure out all the timing, etc. Huge process, I should probably document it better. For several months I used a hand-wired converter-circuit. Lots of tiny wires soldered directly to TQFP pins; I have no idea how it worked so well for so long. The PCB squeeked out a few more Hz refresh-rate, but isn't nearly as impressive... anyone with as much experience as I have can make a PCB!)

---
yeahp, tried to upload a pic, but the net's still too flakey.
----

The display came from an old "PenEnabled" computer, an old Windows Laptop/Tablet in the era before tablets were mainstream. So I also made the necessary circuitry to use the built-in Wacom tablet on my mac. It involved stealing 12V from the LCD inverter (which blew the fuse and was a pain to replace), voltage-regulators, and a simple AVR circuit to interface between the tablet and a bluetooth transmitter. Worked great, but the tablet itself was a bit wider than the bezel, so after months of leaving the display-housing off, I decided to remove it.
In other related-bits, took a bit of effort but managed to compile the latest GIMP on my PPC so I could use the tablet... even though I only used it a few times. It was nice, though... pressure-sensitive, etc.

LCD/AVR Interface
Apparently I'm somewhat fixated on the idea of using old laptop LCDs with AVR processors.
With quite a bit of hacking, I've managed to drive "FPD-Link" (LVDS) signals via an AVR, using PWM, no less. The latest status is about 1Hz refresh-rate with 341x768 resolution at 48 colors on a 1024x768 display. Leads to some interesting abilities and equally interesting limitations. Also tons of hacking was involved... all *extremely* rigorously documented in my code.
As it stands, I've a pretty decent "Mario Brothers" style Question-Box, which I ultimately intend on hanging somewhere... when you hit the underside, a random award will be displayed (1-up, Biggie, Flower-Power, Invincibility... and the occasional Goomba which you have to hit again to kill). It's *done* code-wise, now I just need to make the box, a robust and reliable "hit-switch," and figure out how to power it wherever I hang it.
I've also created a game ala "Racer" from the ol' TI-82 days... a course is laid out and as the screen slowly refreshes, you have to stay in the track... Sounds slow at such refresh-rates, but actually it's somewhat stimulating.
I've a few other ideas of "games" that can make use of such a slow, but high-resolution, display... one is "Story-board Mario"... showing snapshots of your progress as you go, multiple "story-boards" displayed in each refresh. It could *almost* be real-time like the original Super Mario Bro's itself, just in story-board fashion.

AVR/SDRAM (Free-Running)
I've also managed to figure out a way to connect an old SDRAM to an AVR in such a way that the entire memory can be output in a single (or repeated) burst... After the AVR is done loading the memory, the SDRAM itself is responsible for its own control and addressing... I call it "Free-Running Mode," where several of the SDRAM outputs are fed directly back into its inputs (command-signals, address-signals, etc).
I've used it to drive the same LCD, at full resolution and full-color... refresh-rates limited only by the SDRAM's clock-rate, which currently is (though needn't be) limited to the AVR's clock. Though, if you do the math, 1024x768x7 (x7 because there are 7bits in each LVDS transaction) leads to quite a bit of loading from the AVR, so this particular system is best-suited to stationary images, or those that change only a few pixels between each refresh.
Other possibilities include using the SDRAM as a high-bandwidth logic-analyzer (32bits, easily, probably 133MS/s for a few seconds, depending on the RAM size), and more.
The latest design uses no external components, just an SDRAM card and an AVR, oh and a crystal oscillator.
Other design-improvement ideas involve:
Using the SDRAM to completely control itself after loading a few basic instructions from the AVR... e.g. "write" and "read" as well as "nop." Possibly the SDRAM could generate its own clock signal, though this is a bit of a stretch.
These involve splitting the SDRAM into different "banks", one which is responsible for control, and another for actual data I/O.

Quite a bit was learned in each of these projects as far as (undocumented) abilities and limitations of these systems... For example:
SDRAM is supposed to be refreshed, in entirety, every 64ms... but realistically can last for several seconds without a refresh. Further, rather than using explicit "refresh" commands, simply opening and closing a memory-location is enough to refresh that location. This leads to some nice work-arounds; a typical "refresh" command requires that the entire memory be "closed;" meaning that the memory could no longer directly control itself... but it *can easily* open and close its own memory locations while doing other things in "free-running mode."
Similarly, LCDs are specified as having required timings WAY FASTER than an AVR can accomplish... but they also have technologies that accommodate being pushed well-beyond their documented limits. Because TFT displays have, essentially, memory at every pixel, refresh rates of 1Hz, or even 1/5Hz are achievable (on displays which allow out-of-range timing-signals, again completely undocumented). The image is held between each refresh by the transistor on each pixel.

And pushing things in ways they were never intended:
"FPD-Link" (aka LVDS) compatible signals can be generated via an AVR's PWM outputs, no joke. Since many signals are repeated multiple times, (e.g. "Horizontal Sync") it requires loading a PWM value, and allowing it to repeat while the processor is used for other (e.g. image-generation) tasks. Using the "Dead-Time Generator" on these PWM signals allows for creating *almost* serial data for the FPD-Link signal. A bit of hacking reveals that 48 colors distributed almost evenly across the whole range are possible by simply timing the different PWM signals with different start and stop times.

Likewise, the PWM signals on this particular AVR can be run at frequencies much higher than the AVR's clock signal... The ATtiny861 is specified to run at 8MHz, and its PWM signals at 64MHz, but manipulation of some registers and fuses can push it to 16MHz and PWM at 128MHz... 128MHz FPD-Link is nearly the specification. So, if resolution (which is entirely dependent on the AVR's processing abilities) isn't a concern, the screen itself could be refreshed at nearly its specified rates.
Personally, I've found that a display flickering at 30Hz is less pleasing to the eye than one with a visible scrolling refresh every second... And the higher resolution is a big plus.

Another hack was due to the memory-limitations on the AVR... 512Bytes of RAM doesn't allow for full-screen frame-buffer. In fact, it can't even handle an entire row. So, instead of storing data in a frame (or row) buffer, I've opted for a "Row-segment buffer" wherein a row's image-data is stored as segments with a color-value and a value representing the number of pixels.
This works great for images where in a single row there isn't much change... But text, for instance, has a shitton of color-changes between each character, and even within a character. A simple solution is rotating the display (and text) 90 degrees. In the most complicated of characters, there might be 6 color-changes vertically, and since each "row-segment buffer" can handle something like 64 separate segments, we have no issue displaying several rows (separate from display-rows) of dense text in columns, where each LCD "row" is now a column, each "row-segment" is now a column-segment. This is getting hard to explain.

Anyways, the point is, there's quite a bit that can be done to make use of a display at 1Hz refresh with 341x768 usable pixels, 48 colors, and only 512Bytes of RAM...

Oh, a further hack... LVDS requires weird voltage-ranges, as far as most devices are concerned... AVR's output roughly 1=V+ and 0=0V, where V+ is usually 3.3V or 5V, but LVDS requires a differential voltage with about 1V peak-to-peak... This has been found to be easily accomplished with standard TTL IC's, from the 1980's, no-less. By loading the outputs with an LVDS load (100-ohm resistance between the - signal and the + signal), the voltage-levels output by the TTL chips are right within range. Yes, this is stressing the chips quite a bit. These TTL LS chips are rated for 5V, and I'm running them at 3.3V, the outputs are specified to drive *way lower* loads than specified, but, amazingly, pushing them way outside their specified-ranges, the outputs seem to be darn-near *exactly* what's required by LVDS. (It's almost like LVDS was designed around out-of-range TTL chips?!).

Taking a step back... what else have I worked on recently...?

Audio-recording with an AVR to an SD card...
Nokia LCD display <- AVR
Hacking an old Nokia phone for keypad entry via a single AVR analog-comparator input.
Transferred a bunch of VHS's to AVI's
Experimented with (and determined damned-near-useless) Windows XP-64 on a computer found in my building's "free-section"
Determined the "ol' Plasma" to be a fruitless venture, but using its Tuner for my ol' tube TV to get HDTV stations.
Have an old XBox360 that has a flakey DVD drive, been trying to repair it repeatedly... seems to be an alignment issue (the gliders the head rides on seem to be askew) combined with a laser adjustment issue (those danged potentiometers seem to adjust perfectly for one DVD, but not for the next)... can't afford a new drive, so if nothing else, it's a good system for watching AVI's on.
Hey that XBox controller I bought is better than just for watching movies! Someone hacked a driver for MacOS to use it as a joystick... so I've been getting some ol' NES time in via Mednafen. Super Mario Bro's is way too frustrating, what with the need to restart from scratch every time you die... I suppose I could learn to use Mednafen's Save-State, but haven't yet.

This list, of course, is limited to my geekish-endeavors... There's plenty more going on in my life... Like fighting for causes that would be lost-causes except you can't call something a lost-cause if no one except you is fighting for 'em in the first place. Or, like, going to a bar I thought I had friends at, only to find out someone's dropped something in my drink and waking up in the hospital... and receiving a bill for half a year's income. Or, like, being flat-out-manipulated by people you consider friends. So, yeah, let's keep this geekish... I'm proud of my accomplishments.

Oh I forgot one...
My PBG4's keyboard was falling apart... missing several keys... etc. Discovered that the ol' PBG3 keyboard I had laying around was, in fact, pin-compatible... except for one thing... well, a dozen really. First: It was reversed... yeahp. Sounds like a simple fix, but these ribbon-cables can't be soldered-to, and certainly aren't long enough to twist. Managed to solder up an adaptor that *just fit* in the space available. Tons of tiny wires. But, Sweet. Had to cut a few pieces off the computer's housing to get it to fit (it's just *slightly* wider than the original). Did a few hacks here and there to get it to hold-in relatively well... It's a bit gummy-feeling, since it's not really mounted right, but overall it's certainly better than before.

Oh, and this AMD64 I found in the "free-section" is a bit of a joke, but maybe I'll do something with it. I pieced together a couple machines that were sitting there, so now it's in a D-Vine "Home Entertainment PC" case, which could be groovy. Trying to download linux, let's see what this Mint thing is all about... (Lessee, I started on Slackware in middleschool, Debian in highschool, Ubuntoo recently on my PBG4 which I removed... was thinking about Arch, but apparently it's *heavily* dependent on a reliable net connection which I don't have...) A few more days' downloading and I might have a DVD image to burn.

It's a strange position to be in... having once had Cable Internet when others were still using dialup (or didn't even have internet at all), now being happy with 10KB/s downloads... nah *ecstatic* if I get 10KB/s, while all those "the internet is for geeks" folks are surfing YouTube on their phones...

And, since we're ranting... how is it that mainstream opensource distributors aren't even capable of something so ubiquitous as download-resume...?! And is there *anything* that exists anymore without a net-based-installer? I had to search for hours to find a distro that *might* install without reliable internet... Seriously... If I live in a first-world country, in the firstest-of-worlds communities and can only get flakey internet... how are people getting by elsewhere?! I mean, seriously... I can't even upload an image without the site crashing... Thankfully somehow it saved a draft! 'cause I've been getting a shitton of this:  "
An error occurred while trying to save or publish your post. Please try again. Dismiss"

Saturday, May 19, 2012

How many times... re: motion-ramping

I guess there are just some things I have to admit are my white whale...

I can't count the number of times I've coded the same thing to come to the same conclusion. It seems simple at first... You have a motor which moves from one position to another... you have a top speed, and you want it to ramp from stop to the top speed, continue at that speed for a while, then ramp back down to stop at the end position.

I've solved this problem, already, with a convoluted solution: treat the ramping motion like a quarter of a sine-wave, and instead of setting the *speed*, give a simpler motion algorithm (without ramping) multiple intermediate endpoints along that sine-wave, telling it how long to take between each step (a constant time-value). If you're on a circle it makes more sense... the overall speed around the circle is constant; it takes the same amount of time to traverse from one angle on the circle to another... A circle, of course, has a maximum speed of 1 and a minimum of 0 along a single axis while rotating over 90 degrees. Then taking that back to a single-axis you're simply telling it to take a certain amount of time to traverse between different angles on the sine-wave.

But every time I set the project down for a year or two, I look at it and think "damn that's convoluted, why don't I just vary the velocity constantly?" And I recode it with a seemingly simple algorithm. Tonight's was: for the first third of the distance vary the speed linearly from 0 to max, continue at max for the second third, then vary the speed linearly down from max to 0.

Seems simple, really, it probably is, too, because that's how it's taught to implement "simple ramping." But there're several inherent problems I always run into. First: Distance, Time, (and the calculations!) are discrete, here... so it doesn't quite work like in physics. The math doesn't *quite* work out. It works great for ramping UP, but ramping DOWN is a pain, the math is off by a tiny fraction here or there, that error adds up, and suddenly I'm at velocity zero long before the endpoint.

It really seems my problem is I keep trying to approach this from the ideal physics/math standpoint; I keep thinking about *speed* as the main concern, when really time (and position) is what matters (and *works*). If I can fully wrap my head around why the sine-wave approach works, I could probably use the same logic to implement linear-ramping. Maybe instead of using points on a sine-wave, I could use points on a parabola... tell it exactly how long to take between each of those points. Because, without ramping, I can easily get from one point to the next in a specific amount of time. Either way, sinusoidal ramping is smoother than linear, so it doesn't *really* make sense to go back, except to simplify the code that's already written and works (but always has to be modified slightly each time I'm reusing it).

It's just friggin' annoying that I keep recoding this over and over to come to the same conclusions. This last time I didn't even realize I was coding the same thing until the very end... I came to the same faulty conclusion from a completely different direction... thought I had that ah-hah moment, only to realize it was exactly the same as before.

Sine waves, stick to 'em!

Friday, April 27, 2012

back and forward in bash

One of the things I like about window-based file-browsing is the back and forward buttons...

So here're my bash scripts. Feel free to use them. If you find them handy buy me a beer (or post a comment)! Unless, of course, you're planning to profit off 'em, then you can and should buy me a brewery after asking my permission.

There are four files. mycd.sh, back.sh, fwd.sh, and mycdlist.sh
They have to be run in a way I just learned about today (in order to export the variables back to the running bash session) using "source" or "." (explained further, below)

I have added the following to my ~/.bash_profile:
####### For scripts, etc. that need to export variables back to bash ######
# create the script as normal
# all variables in the script are set when returning to bash...
# so best to use this only when all variables are safe...
# (Maybe call another script from the one that's exporting variables?)
# either call them as ". script.sh", "source script.sh" or add them here:
# alias script="source script.sh"
alias cd="source ~/myexecs/mycd.sh"
alias back="source ~/myexecs/back.sh"
alias fwd="source ~/myexecs/fwd.sh"
alias cdls="source ~/myexecs/mycdlist.sh"

So, I have overridden bash's "cd" command with my own... we'll see how safe this is with some testing, but currently it seems to work great. (Thinking about using this method for rm to move things to the trash... not sure yet. The trash is kinda annoying sometimes. Or at least to require a verification beforehand...)

mycd.sh is called just like a normal "cd" command, and should, in fact, work identically, with the addition of creating a variable for history...
back.sh is a simple command, has no arguments, steps one step back in the history written by mycd.sh. As set up in my bash-profile, it's called by typing "back" at the command prompt
fwd.sh does the opposite (called by typing "fwd")
mycdlist.sh lists the history and shows where you are currently (no arguments). I call it by "cdls" and its output looks like this (after calling "back" once):
MYCDPOS='1'
MYCDLASTPOS='2'
[0]='/Users/meh'
[1]='/Users/meh/Another Directory' <-- You Are Here [2]='/Users/meh/Another Directory/AndYetAnother' Here are the files (Don't forget to chmod +x). Oh, one thing... I'm not a genius, and lots of what's in here is new to me as of the past few hours... it hasn't been tested for longer than that. I'll post updates if I revise these. ******** mycd.sh: #!/bin/bash if [ "$MYCDPOS" == "" ] ; then MYCDLASTPOS=0 MYCDPOS=0 MYCDHIST[0]="$PWD" # Make these available to scripts that are called WITHOUT "source" # (Actually, I don't think this works... mycdlist was difficult with this assumption) export MYCDLASTPOS export MYCDPOS export MYCDHIST fi MYCDPOS=$(( MYCDPOS + 1 )) if [ $(( MYCDLASTPOS >= $MYCDPOS )) -eq 1 ] ; then
echo "- Overwriting history -"
fi


MYCDLASTPOS=$MYCDPOS

#echo "$@"

#cd "$@"
### Stolen from /usr/bin/cd from: $FreeBSD: src/usr.bin/alias/generic.sh,v 1.2 2005/10/24 22:32:19 cperciva Exp $
#builtin ${0##*/} ${1+"$@"}
# Doesn't work, I assume, because this is technically mycd.sh even though it's aliased as cd
builtin cd ${1+"$@"}

MYCDHIST[$MYCDPOS]="$PWD"


*************** back.sh:


#!/bin/bash

# Check if there's any history yet...
if [ "$MYCDPOS" == "" ] ; then
echo "- No history yet -"

# Check if there's still history to enter
elif [ $((MYCDPOS - 1)) -lt 0 ] ; then
echo "- End of history -"

#This shouldn't happen in the back case, but it's still a decent test...
elif [ "${MYCDHIST[$((MYCDPOS - 1))]}" != "" ] ; then

MYCDPOS=$(( MYCDPOS - 1 ))

# Check if we're entering old history...
# This happens when back is used a couple times
# then mycd is used, then fwd is used...
# mycd will place new entries beginning at the last
# position used (via back/forward),
# which might overwrite a history entry,
# but it doesn't clear all entries
# This doesn't matter, but it might be helpful to know
if [ $((MYCDPOS > MYCDLASTPOS)) -eq 1 ] ; then
echo "- In old history -"
fi

echo "'${MYCDHIST[$MYCDPOS]}'"
builtin cd "${MYCDHIST[$MYCDPOS]}"

# WTF?
else
echo "- WTF? -"
fi




***************** fwd.sh:


#!/bin/bash

# Check if there's any history yet...
if [ "$MYCDPOS" == "" ] ; then
echo "- No history yet -"

# Check if there's still history to enter
elif [ "${MYCDHIST[$((MYCDPOS + 1))]}" != "" ] ; then

MYCDPOS=$(( MYCDPOS + 1 ))

# Check if we're entering old history...
# This happens when back is used a couple times
# then mycd is used, then fwd is used...
# mycd will place new entries beginning at the last
# position used (via back/forward),
# which might overwrite a history entry,
# but it doesn't clear all entries
# This doesn't matter, but it might be helpful to know
if [ $((MYCDPOS > MYCDLASTPOS)) -eq 1 ] ; then
echo "- Entering old history -"
fi

echo "'${MYCDHIST[$MYCDPOS]}'"
builtin cd "${MYCDHIST[$MYCDPOS]}"

# Reached the end of the history
else
echo "- End of history -"
fi


***************** mycdlist.sh:


#!/bin/bash

MYCDTEMPitemNum=0

echo "MYCDPOS='$MYCDPOS'"
echo "MYCDLASTPOS='$MYCDLASTPOS'"
#Allegedly (and experimentally) there's no way to export arrays
#Thus mycdlist.sh must also be called via "source" or "."
#even though it's only *reading* the variables which are shown
#in bash when you type "set." I'm no export expert, this is kinda voodoo to me.

#echo "MYCDHIST="

if [ "$MYCDPOS" != "" ] ; then
while [ 1 ]
do
MYCDTEMPitem="${MYCDHIST[$MYCDTEMPitemNum]}"
# echo "item='$MYCDTEMPitem'"
if [ "$MYCDTEMPitem" == "" ] ; then
break
else
if [ $MYCDTEMPitemNum -eq $MYCDPOS ] ; then
echo "[$MYCDTEMPitemNum]='$MYCDTEMPitem' <-- You Are Here"
else
echo "[$MYCDTEMPitemNum]='$MYCDTEMPitem'"
fi
fi
MYCDTEMPitemNum=$(( MYCDTEMPitemNum + 1 ))
done
else
echo "- No history -"
fi


************ That's it! I suppose zip files would be nicer...

Tuesday, April 24, 2012

ó vs ó

(Wow, I can actually see the difference, when typed in this window!) ó vs ó ó vs ó ó vs ó
Maybe not... might just be antialiasing...
Anyhow.

Apparently MacOS's bash handles these differently in different cases.

Comparing the following two strings returns FALSE:

'Debaixo Dos Caracóis'
'Debaixo Dos Caracóis'

whereas comparing these two returns TRUE:

'Debaixo Dos Caracóis'
'Debaixo Dos Caracóis'

Duh!

The weird thing is that they come from the same source. The only difference is that one was entered directly with the filename (which contains this string) typed using tab-completion, and the other was entered via for-loop of all files in the directory. Seems like a bug to me, but what do I know?

Some investigating led to how to remove accents from characters: Source
It didn't work for me directly, I had to do some fiddling to get any conversion for the second string (otherwise it would return "iconv couldn't convert")

using the command echo "$string" | iconv -t UTF-7 I get the following two values:

'Debaixo Dos Carac+APM-is'
'Debaixo Dos Caraco+AwE-is'

So, apparently the two accented o's are coming up different, even though they appear the same! Again, oddly, if I run my script within a for loop iterating over all files in the directory, I get "o+AwE-" and if I use tab-completion on the command line I get "+APM-" and the strings match.

Further investigation reveals some useful info: printf can be run from the command line! Source


$ first=`echo "+APM-" | iconv -f UTF-7 -t UTF-8`
$ second=`echo "o+AwE-" | iconv -f UTF-7 -t UTF-8`
$ echo $first
ó
$ echo $second
ó
$ printf '%d\n' "'$first"
-61
$ printf '%d\n' "'$second"
111
$ if [ "$first" == "$second" ] ; then echo YEP ; fi
$

So there you have it... their values aren't even the same. Are they ASCII? I have no idea. This locale and Unicode and other codepage stuff completely eludes me. Here's the page that can tell you all about it. It's WAY over my head: Locale And it doesn't even seem there's such thing as a universal Unicode chart (like there is for 7-bit ASCII)

All I know is that my bash is set with a locale of en-US.UTF-8 and apparently that doesn't match the filenames on my hard drive (?!)

That "o+AwE-" is strangely remniscent of how accents (used to?) be entered on Macs way back in the OS7.5 days... first you typed the letter, then some combination of CTRL and whatnot. I was fascinated by it once and wrote a whole chart. The "+APM-" seems more like PC-style entering a value directly using ALT-###, but I could be imagining things.

This would make my whole project extremely more difficult, except I'd already been working on fuzzy string-matching for differences like McDonalds vs MacDonalds so thankfully I can use that instead of trying to figure out a table of special cases like this. Otherwise, frankly, I'd be at a complete loss as to how to procede without dropping the character entirely. Even the iconv locales don't seem to convert them to anything directly-comparable (only visually). Actually, it could still become a problem for filenames with too many accents... UGH

Monday, April 16, 2012

MP3 Spectrograms

Since MP3s are encoded by frequency-content, shouldn't it be *extremely fast* to convert an mp3 to a spectrogram? Utilities I've seen, so far, (such as sox) seem to convert it to samples first, then back to frequency-content.

---

Been looking into it, a bit. I think the reason this isn't highly-effective is because the actual frequency-content encoded into an MP3 bitstream is something like 32 (or 16?) samples... so even if a DCT is visualizable similar to a FFT spectrogram (which I have yet to find on the 'net), for an MP3 it would only be 32 frequencies tall (including DC), (and *really* wide). I can't quite wrap my head around all this, but I think that's the jist. So, I guess lower frequencies appear DC in these small snippets.

Also, there's something about frequency subbands and long vs short blocks which I can't wrap my head around, either. From what I can piece together from the libmad code, the inverse-DCT seems to be performed directly on small chunks, written directly into an array of samples. I can't figure out where the subbands come into play, nor if they somehow overlap... (which would, I presume, imply "sampleArray[i]+=" instead of "sampleArray[i]=").

This wasn't my original intent, but my original project takes literally 24 hours to process 7GB worth of music... so I guess it was a worthy venture to look into.