Matthew van Eerde's web log

  • Matthew van Eerde's web log

    Second cousins, cousins once removed; relationships by generations to common ancestor

    • 0 Comments

    Raymond Chen explains some common terms for blood relatives of varying distance across cultures in his blog post "What kind of uncle am I?"

    He links to a diagram on genealogy.com that I felt was lacking something... so here's my version, with consanguinary colors.

    Red means "marriage is almost certainly legally prohibited."

    Yellow means "marriage may be legally prohibited - check your region's laws."

    Green means "marriage is amost certainly legal."


    Relationship by generations to common ancestor
    # 0 1 2 3 4 ... m
    0 self father/mother grand
    (father/mother)
    great‑
    grand
    (father/mother)
    (great‑)2
    grand
    (father/mother)

    (great-)m ‑ 2
    grand
    (father/mother)
    1 son/daughter brother/sister aunt/uncle grand
    (aunt/uncle)
    great‑
    grand
    (aunt/uncle)

    (great‑)m ‑ 3
    grand
    (aunt/uncle)
    2 grand
    (son/daughter)
    niece/nephew (first) cousin first cousin,
    once removed
    first cousin,
    twice removed

    first cousin,
    (m ‑ 2) times removed
    3 great‑
    grand
    (son/daughter)
    grand
    (niece/nephew)
    first cousin,
    once removed
    second cousin second cousin,
    once removed

    second cousin,
    (m ‑ 3) times removed
    4 (great‑)2
    grand
    (son/daughter)
    great-
    grand
    (niece/nephew)
    first cousin,
    twice removed
    second cousin,
    once removed
    third cousin
    third cousin,
    (m ‑ 4) times removed
    ...
    n (great‑)n ‑ 2
    grand
    (son/daughter)
    (great‑)n ‑ 3
    grand
    (niece/nephew)
    first cousin,
    (n ‑ 2) times removed
    second cousin,
    (n ‑ 3) times removed
    third cousin,
    (n ‑ 4) times removed

    (n == m) ?
    ((n ‑ 1)th cousin) :
    ((min(n, m) ‑ 1)th cousin, |n ‑ m| times removed)
  • Matthew van Eerde's web log

    Spock's chess games from Star Trek Ishmael

    • 1 Comments

    In his post "A chess problem begging for a solution", Michael Kaplan quotes Barbara Hambly's Star Trek novel Ishmael.  In the quoted scene, Spock (AKA Ishmael) plays a couple of chess games against a stranger - rather unusual chess games.  The problem alluded to is to determine the moves of the games given certain information.

    Let's take the second game first.  There are two effective possibilities that meet the "Reverse Fool's mate" and "three moves" criteria:

    Reverse Fool's mate, even material: $200 in 2½ moves

    # Ishmael Stranger
    1. e3 f6
    2. a3 g5
    3. Qh5#

     

    ... and...

    Reverse Fool's mate plus a pawn: $220 in 2½ moves

    # Ishmael Stranger
    1. e4 f5
    2. exf5 g5
    3. Qh5#

     

    The task for the first game, then, is to win either $400 or $380 in seven moves.  Assuming the game ends in mate (this is reasonable) gives us a difference of either $200 or $180.  The first move can not be a capture, so we really only have six moves to capture $200 worth of material - going after the queen is obvious, but the rooks are quite well tucked away, and it is hard to go after them and simultaneously set up the ending mate.

    I believe that the solution that Barbara Hambly had in mind is the following variation of the "other" mate that every chess student learns (Scholar's Mate).  This particular setup is gated by White's need to move his Bishop out of the way, and this nicely satisfies the common convention that players alternate colors in successive games.  Naturally Spock, being a gentleman, would let the stranger take White first.

    Mate, a queen, and four pawns: $380 in 7 moves

    # Stranger
    Ishmael
    1. c4 e6
    2. c5
    Bxc5
    3. d4 Bxd4
    4. e3 Bxe3
    5. Qf3 Qf6
    6. Bc4 Qxf3
    7. Kf1 Qxf2#

     

    However, from a "chess problem" point of view, there's a cook.  It is, in fact, possible to get mate plus a queen plus four pawns in a mere five and a half moves, rather than the seven full moves above:

    Mate, a queen, and four pawns: $380 in 5½ moves

    # Ishmael
    Stranger
    1. e3
    h5
    2. Qxh5
    d5
    3. Qxd5
    Bf5
    4. Qxb7
    Bh7
    5. Qxc7
    Qc8
    6. Qxc8#

     

    Even worse, there is a way to get $400 in a mere four and a half moves.

    Mate, a queen, a bishop, and a knight: $400 in 4½ moves

    # Ishmael
    Stranger
    1. d4
    Nh6
    2. Bxh6
    b7
    3. Qd3
    Ba6
    4. Qxa6
    Qc8
    5. Qxc8#

     

    The problem, as it stands, is therefore underdetermined... Spock and the stranger had a full two and a half moves to play around with in the first game, either to exchange material or perhaps to allow the stranger to pick up a free pawn (and return it in the second game.)

  • Matthew van Eerde's web log

    The more experience I get the more I like to try new things

    • 0 Comments

    There is a general pattern in professional people.  We start out idealistic and adventurous, and as disasters inevitably accumulate we become more circumspect and pessimistic.

    (Pre-emptive snarky response: "you say that like it's a bad thing.")

    While pessimism is invaluable to a tester, it should be tempered with a just sense of hubris.  Larry Wall's saw about the three virtues of any great programmer has a historical antecedent from one of the canonical American authors:

    We should be careful to get out of an experience only the wisdom that is in it -- and stop there; lest we be like the cat that sits down on a hot stove-lid. She will never sit down on a hot stove-lid again -- and that is well; but also she will never sit down on a cold one any more.
        -- Mark Twain, Following the Equator

    Keep your childlike optimism.

  • Matthew van Eerde's web log

    Why a full-scale sine wave has an intensity of -3 dB FS

    • 3 Comments

    I was asked one day why this full-scale sine wave was being measured by our signal analysis tools as -3 dB FS, even though it hits the maximum and the minimum sample values:

     

    The answer is "because it's a sine wave, not a square wave."  The intensity of a signal can be calculated from the following formula:

    The inner integral does not depend on t - it's just the average sample value - so it's usually precalculated:

     

     

    The importance of taking dc into account during analysis can be appreciated if you try to calculate the intensity of a signal with a high dc.

    Exercise: calculate the intensity of x(t) ≡ -0.5 using the formulas above; calculate the "naïve intensity" by using the last formula above and omitting dc. Note the difference.

    Now that we have the necessary formulas, let's analyze our full-scale sine wave signal.  Plugging in a full-scale sine wave and analyzing over a full period we get:

     

    As expected, the average value of the signal over a single period is 0.

    Evaluating the intensity requires finding the antiderivative of (sin(t))2. This can be ascertained most easily by plotting a few values and realizing that (sin(t))2 = (1 - cos(2t))/2:

     

     

     

    This is a dimensionless number that ranges from 0 (signal is a flat line) to 1 (... we'll get to that later.)

    We can convert this into a dB FS measurement using the formula IdB FS = 20 log10 IRMS:

    Et voilà - that's where the -3 dB comes from.

    In contrast to a sine wave, a full-scale square wave centered at 0 has an intensity of 0 dB FS:

    To finish up, a couple of advanced exercises:

    Advanced Exercise: prove that, provided t1 and t2 are sufficiently far apart, the intensity of a general sine wave x(t) = a sin(ωt + φ) + c depends only on a and not on ω, φ, or c.

    Advanced Exercise: completely characterize the set of digital signals that achieve 0 dB FS intensity.  If you have, say, 1000 samples of mono 16-bit integer audio to play with, how many distinct signals achieve 0 dB FS intensity?

  • Matthew van Eerde's web log

    Sample - WASAPI exclusive-mode event-driven playback app, including the HD Audio alignment dance

    • 22 Comments

    Attached to this post is a sample WASAPI exclusive-mode event-driven playback app, including amd64 and x86 binaries, source, and a modification of the ac3.wav Dolby Digital test tone to include a "fact" chunk.

    >play-exclusive.exe -?
    play-exclusive.exe -?
    play-exclusive.exe --list-devices
    play-exclusive.exe [--device "Device long name"] --file "WAV file name"

        -? prints this message.
        --list-devices displays the long names of all active playback devices.

    Plays the given file to the given device in WASAPI exclusive mode.
    If no device is specified, plays to the default console device.

    On the particular system I used to test this, these are the devices I have:

    >play-exclusive.exe --list-devices
    Active render endpoints found: 3
        Digital Audio (S/PDIF) (2- High Definition Audio Device)
        Speakers (2- High Definition Audio Device)
        Sceptre (High Definition Audio Device)

    And this is the output I get when I play the attached ac3.wav test tones to the Sceptre HDMI output:


    >play-exclusive --device "Sceptre (High Definition Audio Device)" --file ac3.wav
    Opening .wav file "ac3.wav"...
    The default period for this device is 30000 hundred-nanoseconds, or 144 frames.
    Buffer size not aligned - doing the alignment dance.
    Trying again with periodicity of 33333 hundred-nanoseconds, or 160 frames.
    We ended up with a period of 33333 hns or 160 frames.

    Successfully played all 460800 frames.

    A word on the "alignment dance" highlighted above... first, this scene from The Pacifier.  (Vin Diesel is so coordinated.)

    The Pacifier: The Peter Panda dance

    Here's the source for the dance (in play.cpp in the attached.)

    // call IAudioClient::Initialize the first time
    // this may very well fail
    // if the device period is unaligned
    hr = pAudioClient->Initialize(
        AUDCLNT_SHAREMODE_EXCLUSIVE,
        AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
        hnsPeriod, hnsPeriod, pWfx, NULL
    );
    // if you get a compilation error on AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED,
    // uncomment the #define below
    //#define AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED AUDCLNT_ERR(0x019)
    if (AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED == hr) {

        // if the buffer size was not aligned, need to do the alignment dance
        printf("Buffer size not aligned - doing the alignment dance.\n");
       
        // get the buffer size, which will be aligned
        hr = pAudioClient->GetBufferSize(&nFramesInBuffer);
        if (FAILED(hr)) {
            printf("IAudioClient::GetBufferSize failed: hr = 0x%08x\n", hr);
            return hr;
        }
       
        // throw away this IAudioClient
        pAudioClient->Release();

        // calculate the new aligned periodicity
        hnsPeriod = // hns =
            (REFERENCE_TIME)(
                10000.0 * // (hns / ms) *
                1000 * // (ms / s) *
                nFramesInBuffer / // frames /
                pWfx->nSamplesPerSec  // (frames / s)
                + 0.5 // rounding
            );

        // activate a new IAudioClient
        hr = pMMDevice->Activate(
            __uuidof(IAudioClient),
            CLSCTX_ALL, NULL,
            (void**)&pAudioClient
        );
        if (FAILED(hr)) {
            printf("IMMDevice::Activate(IAudioClient) failed: hr = 0x%08x\n", hr);
            return hr;
        }

        // try initialize again
        printf("Trying again with periodicity of %I64u hundred-nanoseconds, or %u frames.\n", hnsPeriod, nFramesInBuffer);
        hr = pAudioClient->Initialize(
            AUDCLNT_SHAREMODE_EXCLUSIVE,
            AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
            hnsPeriod, hnsPeriod, pWfx, NULL
        );

        if (FAILED(hr)) {
            printf("IAudioClient::Initialize failed, even with an aligned buffer: hr = 0x%08x\n", hr);
            pAudioClient->Release();
            return hr;
        }
    } else if (FAILED(hr)) {
        printf("IAudioClient::Initialize failed: hr = 0x%08x\n", hr);
        pAudioClient->Release();
        return hr;
    }

    // OK, IAudioClient::Initialize succeeded
    // let's see what buffer size we actually ended up with
    hr = pAudioClient->GetBufferSize(&nFramesInBuffer);
    if (FAILED(hr)) {
        printf("IAudioClient::GetBufferSize failed: hr = 0x%08x\n", hr);
        pAudioClient->Release();
        return hr;
    }

    // calculate the new period
    hnsPeriod = // hns =
        (REFERENCE_TIME)(
            10000.0 * // (hns / ms) *
            1000 * // (ms / s) *
            nFramesInBuffer / // frames /
            pWfx->nSamplesPerSec  // (frames / s)
            + 0.5 // rounding
        );

     

     

    Note the new HRESULT. 

    HD Audio works on a 128-byte aligned buffer size.  This dance ensures that the HD Audio driver is being fed data in chunks of 128 bytes.  It is somewhat complicated by the fact that IAudioClient::Initialize takes a parameter of hundred-nano-seconds, but IAudioClient::GetBufferSize sets a parameter of frames.

Page 1 of 1 (5 items)

April, 2009