Saturday, October 28, 2006

how to keep frame counter from clobbering toolbar hints

in CMainFrame::OnNotify:

if (nmh->code == TBN_HOTITEMCHANGE) {
if (lpnmhi->dwFlags & HICF_ENTERING) // if entering toolbar
m_HideFrameCounter = TRUE; // hide frame counter
else if (lpnmhi->dwFlags & HICF_LEAVING) // if leaving toolbar
m_HideFrameCounter = FALSE; // show frame counter

How to get a huge file size

static bool GetFileSizeEx(LPCSTR Path, LARGE_INTEGER& Size)
Size.LowPart = GetFileSize(hFile, (PULONG)&Size.HighPart);
return(Size.LowPart != 0xFFFFFFFF || GetLastError() != NO_ERROR);

Friday, October 20, 2006

More on matching original big hex

Considerable progress has been made, using a special version of WhorldFF that reads jumps times from a list, i.e. a file containing a list of the frame numbers at which to do random jumps. The frame numbers were determined by painstaking experimentation.

The key concept is that in the version of FFRend that created original big hex, all of WhorldFF's parameters were initially set by the host. By comparison, in the current version of FFRend, parameters are only set if they differ from their defaults. So for example, number of rings defaults to .5. If it's .5 in the preset, it won't be sent to WhorldFF, so WhorldFF will use the patch's value (1000) instead of 154 (what .5 denormalizes to). The corrected preset uses a value of .500001 rather than .5, because this tricks FFRend into sending WhorldFF the parameter, but is also close enough to the desired number (.5) so that it makes no difference.

Another thing: Tile's Cell Width and Cell height have to start at .54, not .5! No idea why but it's crucial. With this change we get exact matching at 640 x 480, except for very minor variations near the jump points.

Oh and one more thing: original big hex's initial frame offset turns out to 65, not 67. This was obscured by the Tile Cell parameter error.

Minor detail: still # 4454 was mislabeled, it's actually 4554.

Iages 2288 and 2297 aren't correct even at 640 x 480, and since they're suspiciously close to the jump at 2283, it's likely that 2283 is misplaced. The 1105 image is also off (the jump is at 1104, a single frame before!).

Tuesday, October 17, 2006

qsort-based template class for sorting arrays

template class CSortArray {
static void Sort(T *a, int Size, bool Desc = FALSE) {
qsort(a, Size, sizeof(T), Desc ? CmpDesc : CmpAsc);

static int CmpAsc(const void *arg1, const void *arg2) {
if (*(T *)arg1 < *(T *)arg2)
if (*(T *)arg1 > *(T *)arg2)
static int CmpDesc(const void *arg1, const void *arg2) {
if (*(T *)arg1 > *(T *)arg2)
if (*(T *)arg1 < *(T *)arg2)

Sunday, October 15, 2006

SetTimer granularity problem, and multimedia alternative

SetTimer's granularity is 10 ms in w2k, and 15.625 ms in XP. As the following data shows, w2k can achieve exactly 25 Hz, but in XP the best fit is 21.33 Hz. Neither OS can achieve 30 Hz, and worse yet, they fail differently: a period of 33 ms gets you 25 Hz in w2k, and 21.33 Hz in XP.

available fequencies (w2k):
period 1..10 11..20 21..30 31..40 41..50 51..60
freq 100 50 33.33 25 20 16.67

available fequencies (XP):
period 1..15 16..31 32..46 47..62 63..78 79..93
freq 64 32 21.33 16 12.8 10.67

Note: in XP, weird behavior occurs near the above boundaries, e.g. at period = 31, freq oscillates between 31.03 and 30.52.

Multimedia timers appear to have 1 ms granularity, but are significantly more expensive in terms of CPU load. Note that that the callback runs in a system thread and must not post timer messages while OnTimer is running; otherwise if OnTimer consumes more than one timer period's worth of CPU time, the GUI will be non-responsive.

volatile BOOL m_InTimer; // true if we're in OnTimer
static void CALLBACK MMTimeProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
if (!m_InTimer)
PostMessage((HWND)dwUser, WM_TIMER, 0, 0);

Saturday, October 14, 2006

Matching big hex at HD high-res

At 1920 x 1440, Zoom FF param should be (log(0.997395 * 3) + 1) / 2 = .737994
Must also compensate line width! Should be 3 * 6 = 18
Perfect match with WhorldFF, Kaleidascope and Tile. Problem lies further down the signal chain.
Timeblur is also a perfect match, Solarize is also fine, the problem is with Glow.
Hypothesis: if resolution is doubled, inner and outer radius must both be doubled also.
Result: It works fine up to 1280 x 960. At 1600 x 1200 and above, Glow exhibits unexpected behavior.
Bummer. Looks like we're limited to 1280 x 960.

NOTE that you can't change the desired frame rate in the options dialog without also compensating master speed, otherwise all the automations will be off, e.g. if you double the frame rate you must also double master speed.

Friday, October 13, 2006

Resolume plugins that aren’t compatible with FFRend

Invalid bit depth (24-bit only):


Doesn’t work?

Making big images

Recording at 1920 x 1080 (HD) works fine. On the hot rod, I get almost 2 FPS uncompressed and around 1 FPS using XVID. That seems pretty damn slow, but it's about 3000 times faster than Electric Sheep. The question is whether 1080 is good enough for generating poster-sized images, e.g. 11 x 17 at 300 DPI. HD 1080 is only 6.4 x 3.6 at 300 DPI. I tried 5100 x 3300 and it didn't seem to work even on the hot rod. There was memory to spare, so I'm guessing that the exponential increase in compute time would mean render times on the order of an hour per frame, like Electric Sheep's. It would be interesting to see whether it eventually coughs up some frames.

Tuesday, October 10, 2006

Matching the original big hex recording

Hue parameter must be .50000001 which fools "don't set parm needlessly" test, so that hue gets set.

Since origin motion is random, WhorldFF does an initial jump even though the tempo is zero. It takes a while to settle down because of damping. The final location is:

x = .001251258888516
y = .563585314493240

After the initial jump it appears to stay put, but NO, it jumps again at around frame 5000. Why? Looks like a divide by zero problem somewhere, maybe CRealTimer::SetFreq isn't handling zero correctly.

It's hopeless, because the illustrated curves patch uses a random oscillator for poly sides. The random jumps are being triggered asynchronously by CRealTimer's thread, which causes both the origin sequence and the poly sides sequence to be unpredictable.

So the original can't be matched. Sorry! One option is to just live with big hex being different every time it'srecorded. That's either a cool feature or a pain in the ass, depending on your point view. Another option is to disable random jumps in the illustrated curves patch. That should make big hex deterministic, though this needs to be proved. (Yes, it's deterministic, provided you remember to restart the app before each recording).

Disabling random jumps also fixes the occasional inconsistencies in big hex's origin motion. Since whorld and the kaleidescope effect both have origin motion, they're adding or subtracting, and sometimes canceling each other out, which causes the origin to lurch, hesitate, or reverse. But is this good or bad behavior? Again it's subjective: it could be interesting, or annoying. I generally like the smooth origin motion better.

Experiment: big hex 66% with Al Fasawz. The animation moves too fast and spoils the mood of the music. Try a master pitch of 27%. That's the maximum speed reduction possible without losing some time blur (the original had time blur = .27, and .27 / .27 = 1.0, which is the maximum Freeframe parameter). Slow enough?