Matthew van Eerde's web log

  • Matthew van Eerde's web log

    Forcing Windows to install on a single partition

    • 1 Comments

    If you're installing Windows via a boot DVD, and you choose Custom, you have the option to rearrange partitions.  I like use this to have each drive be one big partition.

    Windows 7 wants to set aside a 100 MB partition for something-or-other.  I'm sure there's a very good reason for this but I am too lazy to look up the team that owns this space and ask them what it is.

    So I'm in the "Where do you want to install Windows?" stage, I've gone into "advanced drive setup", and I've deleted all the partitions.  Fine.  I then create a partition that fills the drive, and I get this popup:

    Install Windows
    To ensure that all Windows features work correctly, Windows might create additional partitions for system files.
    OK | Cancel

    After letting Windows finish installing, I jump into diskpart.exe and sure enough, Windows has created an additional partition.  A small one, to be sure... but an additional partition (horrors!)

    Not being one to let Windows push me around, I decided to experiment, and came up with the following dance to allow me to just have one big partition thankyouverymuch:

    1. Boot from the Windows DVD
    2. Choose Custom (advanced) as opposed to Upgrade
    3. Go into Drive options (advanced)
    4. Delete all partitions on the drive
    5. Create a new partition - you will get the prompt above
    6. Click OK
    7. There will now be two partitions - a small (System) one and a large (Primary) one.
    8. Delete the large one.
    9. Extend the new one to fill the drive.
    10. Install Windows.
    11. Open Windows Explorer
    12. Right-click the C: drive | Properties
    13. Delete the "System Reserved" partition name
    Et voilà, Windows installs perfectly happily on the single partition (confirmed with diskpart.exe post-installation.)
  • Matthew van Eerde's web log

    Tweaks I make every time I install Windows

    • 9 Comments

    As preparation for moving one of my machines from Vista to Windows 7, I'm compiling a list of all the little tweaks I like to make to machines that I use a lot:

    Boot from the Windows DVD.  Delete all partitions; make each hard drive one big partition.  (Hmm... apparently Windows 7 really wants a second 100 MB partition.  Do the partition dance to force it into installing on a single partition.)

    In the "password hint" box, type a misleading hint.

    In "Help protect your computer and improve Windows automatically", choose "Ask me later."

    Once I'm in, create a new limited user (not a member of the Administrators group) and use that as my primary account.

    Control Panel | Hardware and Sound | Mouse
        Pointers | Enable pointer shadow (uncheck)
        Pointer Options
            Enhance pointer precision (uncheck)
            Hide pointer while typing (uncheck)

    Right-click taskbar | Properties | Taskbar
        Use small icons (check)
        Taskbar location on screen (change to "Right")
        Taskbar buttons (change to "Never combine")
        Notification area | Customize
            Turn system icons on or off
                Clock | Off (select)
                Volume | Off (select)
                Network | Off (select)
                ... turn everything off, except sometimes.
                (for example, I might leave Power on for a laptop.)
            Always show all icons and notifications on the taskbar (check)
        Use Aero Peek to preview the desktop (uncheck)

    Windows Explorer | Organize
        Layout | Details pane (uncheck)
        Folder and search options | View | Advanced settings
            Always show icons, never thumbnails (check)
            Always show menus (check)
            Display file icon on thumbnails (uncheck)
            Display file size information in folder tips (uncheck)
            Display the full path in the title bar (Classic theme only) (check)
            Hidden files and folders | Show hidden files, folders, and drives (select)
            Hide empty drives in the Computer folder (uncheck)
            Hide extensions for known file types (uncheck)
            Hide protected operating system files (Recommended) (uncheck, Yes I'm sure)
            Show pop-up description for folder and desktop items (uncheck)

    Control Panel | System and Security | Windows Update | Change settings
        Download updates but let me choose whether to install them (select)
        Allow all users to install updates on this computer (check)

    Elevated command prompt | gpedit.msc | Local Computer Policy
        User Configuration | Administrative Templates | Windows Components
            Windows Explorer | Turn off numerical sorting in Windows Explorer (enable)
        Computer Configuration | Administrative Templates
            System
                Power Management | Video and Display Settings
                    Turn Off Adaptive Display Timeout (Plugged In) (enable)
                    Turn Off Adaptive Display Timeout (On Battery) (enable)
            Windows Components | Windows Update
                Do not display 'Install Updates and Shut Down' ... (enable)
                Do not adjust default option to 'Install Updates and Shut Down' ... (enable)

    Control Panel | View by: Small icons (select)
        AutoPlay | Use AutoPlay for all media and devices (uncheck)
        Indexing Options | Modify | Show all locations
            Offline Files (uncheck)
            C:\Users (uncheck)
            C:\ProgramData\Microsoft\Windows\Start Menu (uncheck)
        Troubleshooting | Change settings | Computer Maintenance | Off (select)
        Windows Defender | Tools
            Automatic scanning | Automatically scan my computer (uncheck)
            Real-time protection | Use real-time protection (recommended) (uncheck)
            Administrator | Use this program (uncheck)

    Right-click Start Menu | Properties
        Customize
            Computer | Don't display this item (select)
            Connect To (uncheck)
            Control Panel | Don't display this item (select)
            Default Programs (uncheck)
            Devices and Printers (uncheck)
            Documents | Don't display this item (select)
            Enable context menus and dragging and dropping (uncheck)
            Games | Don't display this item (select)
            Help (uncheck)
            Highlight newly installed programs (uncheck)
            Music | Don't display this item (select)
            Open submenus when I pause on them with the mouse pointer (uncheck)
            Personal folder | Don't display this item (select)
            Pictures | Don't display this item (select)
            Search other files and libraries | Don't search (select)
            Search programs and Control Panel (uncheck)
            Use large icons (uncheck)
            Number of recent programs to display (set to 20 to make the menu bigger)
            Number of recent items to display in Jump Lists (set to 20 to make the menu bigger)
        Store and display recently opened programs in the Start menu (uncheck)
        Store and display recently opened items in the Start menu and the taskbar (uncheck)

    Right-click everything that is pinned to the taskbar
        Unpin this program from taskbar

    Right-click Recycle Bin | Properties
        For each hard drive in turn (select)
            Don't move files to the Recycle Bin. Remove files immediately... (select)

    Control Panel | Appearance and Personalization
        Personalization | Change desktop icons | Recycle Bin (uncheck)
        Change desktop background
            Picture Location: Solid Colors (select, choose black)

    Control Panel | User Accounts | Change your account picture
        Browse for more pictures
            http://blogs.msdn.com/photos/matthew_van_eerde/images/6831850/thumb.aspx

    Control Panel | Ease of access
        Change how your mouse works
            Mouse pointers | Regular Black (select)
            Prevent windows from being automatically arranged when moved to the edge of the screen (check)
        Change how your keyboard works
            Set up Sticky Keys | Turn on Sticky Keys when SHIFT is pressed five times (uncheck)
        Optimize visual display
            Turn off all unnecessary animations (when possible) (check)

    Make a folder on the desktop named "_"
        Open the following folders simultaneously
            _
            C:\ProgramData\Microsoft\Windows\Start Menu
            C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Start Menu
        Copy various shortcuts from Start Menu over to _
            Notepad
            Paint
            Command Prompt
            Calculator
            ... whatever else strikes my fancy
        ... as I install programs, consider adding them here if I use them a lot

    Right-click the taskbar | Toolbars | New toolbar... | Desktop | _ (Select Folder)
        Right-click the taskbar | Lock the taskbar (uncheck)
        Drag the thumb of the _ toolbar to the top of the taskbar
        Right-click _
            Show Text (uncheck)
            Show title (uncheck)
            View | Small Icons (check)
        Drag the taskbar to be a tiny bit wider so three small icons fit side-by-side
        Drag the view-active-tasks part of the taskbar to be big
        Right-click the taskbar | Lock the taskbar (check)

    Make a 1-pixel-by-1-pixel black .jpg and set it as the LogonUI background

    I'm sure I'm forgetting some other things.  I'll add them later when I run into them.

    I could probably make a series out of this.  Possible candidates for future posts: "Tweaks I make every time I install Office", "Tweaks I make every time I install Firefox"...

    Command Prompt | Alt-Space | Defaults | QuickEdit Mode (check)

  • Matthew van Eerde's web log

    How to calculate a sine sweep - the right way

    • 4 Comments

    Three quarters are better than a dollar because they make noise!
        -- Lilly, Lilly's Purple Plastic Purse

    Last time I talked about how to calculate a sine sweep mathematically.  There's a closed-form solution which is quite elegant but, alas, useless in a practical computer implementation due to the very big numbers that are being fed to the sin(...) function.

    A computer implementation will care only about the discrete samples that need to be generated.  The integral in the previous post turns out to be counterproductive - we're much more interested in the infinite sequence of φi, and more particularly in their residue mod 2π.

    Here are Matlab scripts that implement a sine sweep both ways:

    First, the naïve mathematical solution that just calculates the exponential:

    function signal = sinesweep_nostate( ...
        start, ...
        finish, ...
        seconds, ...
        sample_rate, ...
        amplitude, ...
        initial_phase, ...
        dc ...
    )
    % sinesweep_nostate returns a single-channel sine logarithmic sweep
    %     DO NOT USE THIS FUNCTION IN PRODUCTION
    %     THIS IS A PEDAGOGICAL EXERCISE ONLY
    %     THE SIGNAL THIS PRODUCES GRADUALLY DISTORTS
    %     INSTEAD USE sinesweep
    %    
    %     start: starting frequency in Hz
    %     finish: ending frequency in Hz
    %     seconds: duration of sweep in seconds
    %     samplerate: samples per second
    %     amplitude: amplitude
    %     initial_phase: starting phase
    %     dc: dc

    % echo these interesting intermediate values to the console
    R = (finish / start) ^ (1 / seconds)
    B = 2 * pi * start / log(R)
    A = initial_phase - B

    time = 0 : 1 / sample_rate : seconds;
    phase = A + B * R .^ time;
    signal = amplitude * sin(phase) + dc;

    end % sinesweep_nostate

    Now, the iterative version that adds up the little Δφs to calculate φi iteratively:

    function signal = sinesweep( ...
        start, ...
        finish, ...
        seconds, ...
        sample_rate, ...
        amplitude, ...
        initial_phase, ...
        dc ...
    )
    % sinesweep returns a single-channel sine logarithmic sweep
    %     start: starting frequency in Hz
    %     finish: ending frequency in Hz
    %     seconds: duration of sweep in seconds
    %     samplerate: samples per second
    %     amplitude: amplitude
    %     initial_phase: starting phase
    %     dc: dc

    time = 0 : 1 / sample_rate : seconds;
    frequency = exp( ...
        log(start) * (1 - time / seconds) + ...
        log(finish) * (time / seconds) ...
    );

    phase = 0 * time;
    phase(1) = initial_phase;
    for i = 2:length(phase)
        phase(i) = ...
            mod(phase(i - 1) + 2 * pi * frequency(i) / sample_rate, 2 * pi);
    end

    signal = amplitude * sin(phase) + dc;

    end % sinesweep

    If anything, one would expect the first to be more accurate, since it is mathematically precise, and the second is only an approximation.  But let's see how the signal produced by each of them holds up.

    I calculate, and plot, the same sweep both ways, with a slight dc offset to facilitate seeing the different sweeps on the same plot.  In particular this is a logarithmic sweep from 20 kHz to 21 kHz, over 30 seconds, using 44100 samples per second, an amplitude of 0.2, an initial phase of π, and a dc of 0.25 for one and 0.26 for the other:

    plot(...
        x, sinesweep(20000, 21000, 30, 44100, 0.2, pi, 0.25), 'd', ...
        x, sinesweep_nostate(20000, 21000, 30, 44100, 0.2, pi, 0.26), 's' ...
    )

    (x is just 1:30*44100 - necessary to allow a single plot statement.)

    Note that the approximate method is plotted in diamonds, and will be 0.01 lower on the resulting graph than the "exact" method, plotted in squares.

    (This takes a while to plot because there are a heckuva lot of points...)

    Ah, a nice solid mass of green and blue.  I won't show it here.

    OK, let's zoom in to a very early chunk of the signal - I expect these to match up closely, with only the dc offset separating the points:

    Yup.  Looks pretty good - give or take a pixel (quantization error in the display.)

    Now let's see what happens to the signal towards the end of the 30 seconds.

    Ick.  Something's rotten in the state of Denmark.  This distortion is so bad that it's visible - you don't even have to take an FFT to see it.

    Exercise: take an FFT and look at the distortion.

    Advanced Exercise: demonstrate that the distortion is, in fact, in the "exact" method and not in the iterative method... that is to say, show which clock is right.

    EDIT: On second glance it looks like the second picture is just showing a horizontal shift between the two signals, which is expected.  I'll need to dig deeper if I'm to prove my assertion that the iterative method produces less distortion than the "exact" method.

  • Matthew van Eerde's web log

    Bad Perl: locker problem

    • 0 Comments

    Bad Perl solution to the "print the open lockers" problem:

    perl -e"print join', ',map{$_*$_}1..sqrt pop" 100

    54 characters.  I prefer this to the 53-character solution obtained by omitting the space after the first comma.

    EDIT: 49 characters:

    perl -e"print map{$_*$_,' '}1..sqrt pop" 100

    EDIT: 48:

    perl -e"print map{$_*$_.$/}1..sqrt pop" 100

    EDIT: 47:

    perl -e"map{print$/.$_*$_}1..sqrt pop" 100

    I still think "say" is cheating but it does afford this very short solution:

    perl -E"map{say$_*$_}1..sqrt pop" 100

    EDIT: Apparently I need to learn how to count. Counts above are off. Anyway, 41:

    perl -e"print$_*$_,$/for 1..sqrt pop" 100

  • Matthew van Eerde's web log

    How to calculate a sine sweep - the wrong way

    • 3 Comments

    Suppose you want to generate a continuous sine-sweep from time tstart to time tend. You want the starting frequency to be ωstart, and the ending frequency to be ωend; you want the sweep to be logarithmic, so that octaves are swept out in equal times. (The alternative would be to sweep linearly, but usually logarithmic sweeping is what you want.) For today we're going to have continuous time and sample values, so sample rate and bit depth will not be part of this discussion; in particular, the units of t will be seconds, and our sample values will go from -1 to 1.

    Here's a picture of want we want to end up with:

    Without loss of generality, set tstart = 0. This simplifies some of the math.

    Let ω(t) be the "instantaneous frequency" at time t. Advanced Exercise: Define "instantaneous frequency" mathematically.

    Sweeping ω(t) logarithmically means that log ω(t) is swept linearly from log ωstart to log ωend. So

    Quick check: ω(0) = ωstart, ω(tend) = ωend. Yup.

    Let's define R (the rate of change of the frequency) as (ωend / ωstart)1 / tend. This formula reduces to

    ω(t) = ωstart Rt

    Next step is to look at phase. For a sine wave of constant frequency ω, phase progresses linearly with t on the circular interval [0, 2π):
    φ = k ω t
    for some constant k. If the frequency of a sine wave was 1 cycle per second, the phase would go from 0 to 2π in a single second - this reveals that the correct value of k is 2π:
    φ = 2π ω t

    What happens with a variable frequency? A little calculus provides the answer. Consider a small change Δt, small enough so that ω(t) is almost constant over the interval:
    Δφ ≈ 2π ω(t) Δt
    because over that interval the sine sweep function is well approximated by a sine wave of constant frequency ω(t).

    Starting from an initial phase φstart, let Δt → 0, and:

    Substitute:
    u = τ log R
    τ = u / log R
    = du / log R

    Define:
    B = 2π ωstart / log R
    A = φstart - B
    and we have:

    φ(t) = A + BRt

    Just for fun, here's the explicit solution without intermediate values:

     

    Now, the payoff: the signal is just the sine of the phase, so our sine sweep is:

     

    or, more explicitly:

     

    Ah, beautiful mathematically.

    But useless practically.

    Why useless?

    Well, note that our equation for phase is an exponential. That expression inside the sin(...) gets very big, very quickly. Any practical implementation of sin(...) is going to be utterly useless once its argument gets beyond a certain threshold - you'll get ugly chunky steps before you're halfway into the sweep.

    Nonetheless, there is a practical way to generate (pretty good) sine sweeps. More on that next time.

    EDIT: all logs are base e.

  • Matthew van Eerde's web log

    Bad Perl: Josephus problem

    • 1 Comments

    Another programming contest asks to solve the Josephus problem.

    Bad Perl solution (83 characters... so close...)

    >perl -e"@_=(1..$ARGV[0]);++$c%$ARGV[1]?$i++:splice@_,$i%=@_,1while$#_;print@_" 40 3
    28

    EDIT: got it down to 80.

    >perl -e"@_=(1..shift);++$c%$ARGV[0]?$i++:splice@_,$i%=@_,1while$#_;print@_" 40 3
    28

    EDIT2: 78 dropping the parentheses.

    >perl -e"@_=1..shift;++$c%$ARGV[0]?$i++:splice@_,$i%=@_,1while$#_;print@_" 40 3
    28

    EDIT3: 66, shamelessly cannibalizing others' ideas from the contest (though I refuse to use "say")

    >perl -e"$k=pop;@_=1..pop;@_=grep{++$i%$k}@_ while$#_;print@_" 40 3
    28

  • Matthew van Eerde's web log

    Bad Perl: Russian Peasant multiplication algorithm

    • 1 Comments

    I found this programming contest interesting: here's what I've got.

    perl -e "($a,$b)=@ARGV;map{$c+=$_*$b}grep{$a&$_}map{1<<$_}(0..log($a)/log 2);print$c" 7 19

    I'm calling this a one-liner because the part between the quotes is less than 80 characters (75, to be exact.)  The full command line goes over :-(

    Requires the inputs to be positive whole numbers.

    Perfect example of Bad Perl.  Exercise: rewrite in Good Perl.

    EDIT: got the whole thing down to 80 characters (with single-digit multiplicands.)

    perl -e "($a,$b)=@ARGV;map{$c+=$b<<$_ if$a>>$_&1}(0..log($a)/log 2);print$c" 8 7

  • Matthew van Eerde's web log

    Bug - jack detection on Windows 7 hdaudio.sys mixed capture

    • 5 Comments

    There's a bug that got away from me in Windows 7's HD Audio class driver (hdaudio.sys.)

    Before I explain the bug, a few caveats:

    If you're using Vista, there's no problem.  This only affects Windows 7.

    If you use the third-party audio driver, there's no problem.  This only affects the Microsoft HD Audio class driver (hdaudio.sys.)

    If your recording devices (mic and line in) are independent (can capture from both at the same time) or muxed (can capture from one or the other but not from their sum) then you're fine; this only affects mixed capture (can capture from one, from the other, or from their sum, but not from both sides of the mix independently.)

    If either of your recording devices doesn't support jack presence detection then you're fine; this only affects mixed capture where both sides of the mix support jack presence detection.

    Here's the bug.

    1. There are various ways to "reset" the system and bring the OS recording device state into synchronization with the hardware state
      • reboot
      • reset the HD Audio controller
      • reinstall the audio driver
      • restart the AudioEndpointBuilder service
      • unplug all recording devices in the mix
    2. The first state change (plug or unplug) after a reset works
    3. The second and further state changes are not recognized by the OS until a reset.

    Here's a sample state diagram assuming a mixed Mic and Line In (click to view full-size:)

     

    Workarounds:

    Install the third-party audio driver instead of the HD Audio class driver.

    Use audio extension cables to fool the jack presence detection hardware into thinking something is always plugged in.

  • Matthew van Eerde's web log

    Minimal unsatisfiable regular expression, XPath query

    • 0 Comments

    Regular expressions are a tool for matching generic text.  XPath queries are a tool for matching chunks of XML.  Both are search technologies.

    When using search technologies it is occasionally quite useful to have a query that will never match anything - for SQL, this would be something like "SELECT 1 WHERE 1 = 0".

    My candidates for minimal unsatisfiable regular expression:

    /a\bc/
    \b is a zero-width assertion that matches a boundary at the beginning or end of a word - specifically, it is true between a word-ish character (\w) and a non-wordish character (\W).  Since literal "a" and "c" are both wordish characters, this will never match.

    Or, if you allow Perl extensions:

    /(?!)/
    This is a negative lookahead for an empty string.  Since the empty string always matches everywhere, this will never match.

    My candidate for minimal unsatisfiable XPath query:

    /parent::*
    This matches everything at or under the parent of the root element.  Since, by definition, the root element has no parent, this will never match.

  • Matthew van Eerde's web log

    Why square waves have ears: Gibbs' phenomenon (Wilbraham's phenomenon)

    • 0 Comments

    In a recent post I sung the praises of square waves as a way to get a heckuva lot of power (3 dB more power than a sine wave) into a sample-range-limited signal.  It's time to take them down a notch now.

    A problem with square waves is they're impossible to generate in the analog domain.  In fact, you can't even get close.

    Signals generated in the analog domain are subject to physical laws regarding continuity (no teleportation) and whatnot. A common way to model these is to express (periodic) analog signals using a basis of sine waves with integral periods.  Suppose I want to generate the square wave:

    f(x) = 1, -π < x < 0
    -1, 0 < x < π

    Graphed below are some approximations of this function using sine waves as a basis.  Note that only odd values of n are used in the sums of sin(nx).


     

    The sums converge to +/-1 quite well, but there are definite "ears" at x near 0 where there's overshoot.  This doesn't appear to die down.  A closeup of one of the "ears":


     

    If anything, rather than dying down, the "ears" converge to max(fn) → about 1.18, or about 9% of the "jump" from -1 to 1.  (Dym and McKean, in their 1972 book Fourier Series and Integrals, get the 9% right but incorrectly assert that the convergence is to 1.09.)

    This mathematical phenomenon - Gibbs' phenomenon - is a good illustration of the difference between convergence of a series of functions and uniform convergence.

    In this case, the series of partial sums pointwise converge to the square wave... for any given point x > 0 and ε > 0, the ear will eventually move to the left, and I can choose an N such that fn(x) is within of ε of 1 for all n > N...

    ... but the series does not uniformly converge to the square wave.  The following assertion is false: "for any given ε > 0, I can pick an N such that fn(x) is within of ε of 1 for all n > N and all x > 0."  This can be demonstrated by picking ε = 0.17, say.  For any n, even, say, n = 10100, there is an x close to 0 where f1e100(x) > 1.17.

  • Matthew van Eerde's web log

    Daylight Saving Time and Benjamin Franklin

    • 1 Comments

    Daylight Saving Time is a thorn in my side.

    Politician: What time is it?
    Scientist: What time would you like it to be?

    It is my firm belief that

    1. Daylight Saving Time doesn't do any real good.
    2. Daylight Saving Time does real harm.
    3. Politicians love Daylight Saving Time because it's easy and at least it looks good.
    One of the points that my congresswoman brought up is that Daylight Saving Time was originally proposed by a founding father of the US, and that therefore it must be a good idea.  (Exercise: what logical fallacy is this?)

    Today I decided to actually look up the original proposal and found it quite enlightening.

    Benjamin Franklin's 1784 letter to the Journal de Paris (English translation)

    The full article is well worth reading, but this quote will illustrate my point:

    I believe all who have common sense, as soon as they have learnt... that it is daylight when the sun rises, will contrive to rise with him; and, to compel the rest, I would propose the following regulations...

    let a tax be laid... on every window that is provided with shutters...

    [let] no family be permitted to be supplied with more than one pound of candles per week...

    Let guards also be posted to stop all the coaches, &c. that would pass the streets after sunset...

    Every morning, as soon as the sun rises, let all the bells in every church be set ringing; and if that is not sufficient?, let cannon be fired in every street, to wake the sluggards effectually, and make them open their eyes to see their true interest. 

    Yes, Benjamin Franklin was the first to propose a law encouraging people to get up early.

    But he was joking.

  • 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.

  • Matthew van Eerde's web log

    Sample - WASAPI loopback capture (record what you hear)

    • 102 Comments

    In a previous post I showed how to play silence to a given audio device and hinted at a possible application.

    Attached to this post is a sample WASAPI loopback capture app - amd64, x86 and source included.  This allows you to record the sound that is coming out of your speakers:

    >loopback-capture -?
    loopback-capture -?
    loopback-capture --list-devices
    loopback-capture [--device "Device long name"] [--file "file name"] [--int-16]

        -? prints this message.
        --list-devices displays the long names of all active playback devices.
        --device captures from the specified device (default if omitted)
        --file saves the output to a file (loopback-capture.wav if omitted))
        --int-16 attempts to coerce data to 16-bit integer format

    There are a couple of oddities for WASAPI loopback capture.  One is that "event mode" doesn't work for loopback capture; you can call pAudioClient->Initialize(... AUDCLNT_STREAMFLAGS_LOOPBACK | AUDCLNT_STREAMFLAGS_EVENTCALLBACK, ... ), you can call pAudioClient->SetEventHandle(...), and everything will succeed... but the "data is ready" event will never fire.  So this app creates its own waitable timer.

    Another oddity is that WASAPI will only push data down to the render endpoint when there are active streams.  When nothing is playing, there is nothing to capture.

    For example, play a song, and then run loopback-capture.  While loopback-capture is running, stop the song, and then start it again.  You'll get this output when you start it back up:

    >loopback-capture
    Press Enter to quit...
    IAudioCaptureClient::GetBuffer set flags to 0x00000001 on pass 5381 after 1088829 frames

    Thread HRESULT is 0x8000ffff

    The flag in question is AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY.  When the song stopped, no more data was available to capture.  Eventually the song started up again, and WASAPI dutifully reported that there was a glitch detected.  This app stops on glitches.

    There are a couple of other possible ways to handle this.  One way is to ignore glitches; then if you stop a song, wait a few seconds, and start it again, then the recorded signal will omit the wait and abut the two "audio is playing" portions.

    But my particular favorite way of handling this is to run silence.exe.  That way there are never any "nothing is playing" glitches, because there's always something playing.

    EDIT 11/23/2009: Updated loopback-capture.exe to ignore the glitch flag on the first packet, since Windows 7 sets it.  Also improved the interaction between the capture thread bailing out and the user pressing Enter to finish.

    EDIT 11/5/2014: Go read this new post which has updated source and binaries, as well as links to better samples.

  • Matthew van Eerde's web log

    Sample - playing silence via WASAPI event-driven (pull) mode

    • 10 Comments

    Be vewy vewy quiet - we'we hunting wabbits.
        -- Elmer Fudd

    Attached is a mini-app I've written to play silence to any given playback device using WASAPI event-driven (pull) mode.  Source, x86 binary, and amd64 binary are attached.

    Usage statement:

    >silence -?
    silence
    silence -?
    silence --list-devices
    silence --device "Device long name"

        With no arguments, plays silence to the default audio device.
        -? prints this message.
        --list-devices displays the long names of all active playback devices.
        --device plays silence to the specified device.

    >silence --list-devices
    Active render endpoints found: 2
        Speakers (USB Audio Device)
        Headphones (High Definition Audio Device)

    >silence --device "Headphones (High Definition Audio Device)"
    Press Enter to quit...
    Received stop event after 488 passes

    While it's playing it shows up in the Volume Mixer:

     http://blogs.msdn.com/photos/matthew_van_eerde/images/9191979/original.aspx

    Why would I write such a thing?

    Well, there is the pedagogical exercise of writing a WASAPI event-driven render loop.

    But there is also a practical application of an active silence stream, having to do with loopback capture.  More on this in a future post...

    EDIT: 7/30/2009 - fixed bug where I was treating the GetCurrentPadding value as the amount of free space in the buffer when in fact it's the amount of used space.

    While I was at it, added an icon and exited immediately on errors rather than waiting for the caller to hit Enter.

  • Matthew van Eerde's web log

    Good Perl, Bad Perl

    • 0 Comments

    One of my favorite languages is Perl.  Perl has an ambivalent reputation; some people take to it, some accuse it of being a syntax-complete language.  (There's some truth to this.)

    My view is that Perl gives you a very direct link into the mind of the programmer - much more so than other languages.  Perl is designed very much like a spoken language, perhaps because Larry Wall's background is linguistics.

    There was a little girl
    Who had a little curl
    Right in the middle of her forehead.
    And when she was good,
    She was very, very, good;
    But when she was bad
    She was horrid.
       -- Henry Wadsworth Longfellow

    (In an English accent, "forehead" and "horrid" actually rhyme.)

    Two examples of my own Perl to illustrate my point.  This is in my email signature:

    perl -e "print join er,reverse',','l hack',' P','Just anoth'"

    And this little seasonal gem:

    use strict;
    use warnings;

    sub receive($);

    my @ordinals = qw(
    zeroth
    first second third fourth fifth sixth
    seventh eighth ninth tenth eleventh twelfth
    );

    my @gifts = reverse split /\n/, <<END_OF_LIST;
    Twelve drummers drumming;
    Eleven pipers piping;
    Ten lords a-leaping;
    Nine ladies dancing;
    Eight maids a-milking;
    Seven swans a-swimming;
    Six geese a-laying;
    Five golden ringeds;
    Four colly birds;
    Three French hens;
    Two turtle doves;
    A partridge in a pear tree.
    END_OF_LIST

    for (my $day = 1; $day <= 12; $day++) {
    receive($day);
    }

    sub receive($) {
    my $day = shift;

    print("On the ", $ordinals[$day], " day of Christmas, my true love sent to me:\n");

    for (my $i = $day; $i > 0; $i--) {
    my $gift = $gifts[$i - 1];

    if ($i == 1 && $day != 1) {
    $gift =~ s/^(\s*)A/$1And a/;
    }

    print $gift, "\n";
    }

    if ($day != 12) {
    print "\n";
    }
    }

    The latter kind of Perl I like to call "good Perl".  It's easy to read, I think.  There are a couple of idioms that take getting used to, just like with any new language, but well-written Perl is (I think) easier to read than any other language.

    But flexibility has its dark sides as well.  Black Perl is the canonical example, but there are others such as Perl golf.  This kind of thing (the first sample above is an example) is responsible for at least part of Perl's reputation for opacity; its compatibility with shell scripting, and most particularly its embedded regular expression support, is responsible for much of the rest.

    Exercise: duplicate the output of the second sample above using as short a Perl program as possible.

  • Matthew van Eerde's web log

    xargs start

    • 3 Comments

    Like many programmers, I've messed around in a lot of development environments - including the UNIX/Linux family of operating systems.

    One of the UNIX commands I like is xargs... this is very handy when writing one-off command lines or scripts.

    I like it so much that I miss it terribly when I'm in a Windows OS.  So I wrote an xargs.bat and stuck it in my PATH.  Now instead of writing complicated for loops, I can just pipe to xargs.

    The script is "powered by" the highlighted line:

    C:\Users\MatEer\Desktop\custom-path>type xargs.bat
    @echo off

    setlocal

    if /i (%1)==(/?) goto USAGE

    if /i (%1)==() goto USAGE

    if /i (%1)==(/addquotes) goto ADDQUOTES

    goto NOQUOTES

    :USAGE
    echo usage: something-that-produces-output ^| %0 [/?] [/addquotes] thing-to-run
    echo   xargs.bat by Matthew van Eerde 10/3/2005
    echo.
    echo   something-that-produces-output should write to its STDOUT
    echo   thing-to-run will have each line of the output appended to it,
    echo   then will be run successively
    echo.
    echo   If /addquotes is set, quotes will be added around the line
    echo   before appending the line to thing-to-run
    echo.
    echo   If you call xargs without piping output to it, xargs will wait
    echo   for you to type something in on STDIN.
    echo   Ctrl-Z on its own line to finish.
    goto END


    :ADDQUOTES

    rem eat /addquotes parameter
    shift

    rem Alas, shift doesn't affect %*
    if (%1)==() goto USAGE
    set basecommand=%1
    shift

    :BUILDBASECOMMAND
    if (%1)==() goto DONEBASECOMMAND
    set basecommand=%basecommand% %1
    shift
    goto BUILDBASECOMMAND
    :DONEBASECOMMAND

    rem run the program specified by %*
    rem as many times as there are lines in STDIN
    rem with one extra argument -- defined by each line of STDIN -- in quotes
    rem
    rem all that the find command does is intercept STDIN
    rem
    for /F "usebackq delims=" %%a in (`find /v ""`) do %basecommand% "%%a"

    goto END


    :NOQUOTES

    rem run the program specified by %*
    rem as many times as there are lines in STDIN
    rem with extra arguments defined by each line of STDIN
    rem
    rem all that the find command does is intercept STDIN
    rem
    for /F "usebackq delims=" %%a in (`find /v ""`) do call %* %%a

    goto END


    :END

    endlocal

    This allows wonderfully anaOStic things like findstr /m IFoo * | xargs start

  • Matthew van Eerde's web log

    xkcd finds East and West confusing - what about North and South?

    • 1 Comments

    Stealing from XKCD again:

    Terminology

    I have a similar problem with North and South.  On the globe, there's a clearly marked "North Pole" and a clearly marked "South Pole."

    Fine.

    Magnets also have North and South poles.  These are typically labeled N and S respectively.  Fine.

    But if you consider the Earth as a large magnet (which it is), then you have to stick the N where the penguins live (Antarctica-ish) and the S where the polar bears live (Canada-ish...)

     http://blogs.msdn.com/photos/matthew_van_eerde/images/9064687/original.aspx

    That bugs me.

  • Matthew van Eerde's web log

    The case of the default audio device from the future

    • 3 Comments
    Hover the mouse over each picture (xkcd-style) in turn to get the text that tells the story.

    An amusing behavior of Windows Vista recently came to my attention... sometimes the Sound control panel wants to go back... to the future!



    So far, so good.



    D'oh! Luckily, there's a way to recover...



    Voilà tout.
  • Matthew van Eerde's web log

    How long can the logoff sound be?

    • 0 Comments

    Windows has a customizable soundtrack - when different things happen, sounds play.  You can live with the default sounds, turn all the sounds off, or substitute your own sounds.  All configurable via the Sound control panel:

     http://blogs.msdn.com/photos/matthew_van_eerde/images/9020631/original.aspx

    You can assign short or long, pleasant or annoying sounds to any event in the list.  For example, you could rip a CD to .wav format and assign it to the "Maximize" event.

    There are two events that are a little finicky about how long the sound is, though: the "Exit Windows" and "Windows Logoff" events.  If you assign a sound that is too long to either of these events, it won't play.  It plays when you click the "Test" button, but when you actually log off or shut down, the sound doesn't play.

    How long is too long?

    Before the answer, a quick review of .wav files.

    You can have any number of frames per second.  CDs use a sample rate of 44100 frames per second; DVDs use 48000 frames per second.  This is usually one of (11025, 22050, 44100, 88200, 176400; 48000, 96000, 19200; 8000, 16000, 32000).

    You can have any number of samples in a frame: mono (1 channel), stereo (two channels), surround (four channels), 5.1 (six channels), 7.1 (eight channels), or a different number.

    Each sample is a number.  This can be a floating-point number (32 bits), an unsigned integer (8 bits), or a signed integer (16 bits, 20 bits, 24 bits, 32 bits.)  The 20 bit and 24 bit integers can be either in 24-bit containers or in 32-bit containers.

    The fatness of the samples, and how many there are per second, determines how many bytes a second of .wav data will contain.  The formula is:

    bytes/second = (samples/frame, AKA channels) * (frames/second, AKA sample rate) * (bits/sample) / (bits/byte, always 8)

    For performance reasons, Windows Vista limits the size of shutdown/logoff sounds to 4 MB.

    So how long is 4MB?  Here's the answer in tabular form for most common formats.  Lengths are in seconds.

    unsigned 8-bit int

    sample rate

    mono

    stereo

    surround

    5.1

    7.1

    8000

    524.29

    262.14

    131.07

    87.38

    65.54

    11025

    380.44

    190.22

    95.11

    63.41

    47.55

    16000

    262.14

    131.07

    65.54

    43.69

    32.77

    22050

    190.22

    95.11

    47.55

    31.70

    23.78

    32000

    131.07

    65.54

    32.77

    21.85

    16.38

    44100

    95.11

    47.55

    23.78

    15.85

    11.89

    48000

    87.38

    43.69

    21.85

    14.56

    10.92

    88200

    47.55

    23.78

    11.89

    7.93

    5.94

    96000

    43.69

    21.85

    10.92

    7.28

    5.46

    176400

    23.78

    11.89

    5.94

    3.96

    2.97

    192000

    21.85

    10.92

    5.46

    3.64

    2.73







    signed 16-bit int

    sample rate

    mono

    stereo

    surround

    5.1

    7.1

    8000

    262.14

    131.07

    65.54

    43.69

    32.77

    11025

    190.22

    95.11

    47.55

    31.70

    23.78

    16000

    131.07

    65.54

    32.77

    21.85

    16.38

    22050

    95.11

    47.55

    23.78

    15.85

    11.89

    32000

    65.54

    32.77

    16.38

    10.92

    8.19

    44100

    47.55

    23.78

    11.89

    7.93

    5.94

    48000

    43.69

    21.85

    10.92

    7.28

    5.46

    88200

    23.78

    11.89

    5.94

    3.96

    2.97

    96000

    21.85

    10.92

    5.46

    3.64

    2.73

    176400

    11.89

    5.94

    2.97

    1.98

    1.49

    192000

    10.92

    5.46

    2.73

    1.82

    1.37







    24-bit container: signed 20-bit int or signed 24-bit int

    sample rate

    mono

    stereo

    surround

    5.1

    7.1

    8000

    174.76

    87.38

    43.69

    29.13

    21.85

    11025

    126.81

    63.41

    31.70

    21.14

    15.85

    16000

    87.38

    43.69

    21.85

    14.56

    10.92

    22050

    63.41

    31.70

    15.85

    10.57

    7.93

    32000

    43.69

    21.85

    10.92

    7.28

    5.46

    44100

    31.70

    15.85

    7.93

    5.28

    3.96

    48000

    29.13

    14.56

    7.28

    4.85

    3.64

    88200

    15.85

    7.93

    3.96

    2.64

    1.98

    96000

    14.56

    7.28

    3.64

    2.43

    1.82

    176400

    7.93

    3.96

    1.98

    1.32

    0.99

    192000

    7.28

    3.64

    1.82

    1.21

    0.91







    32-bit container: signed 20-bit int, signed 24-bit int, or float32

    sample rate

    mono

    stereo

    surround

    5.1

    7.1

    8000

    131.07

    65.54

    32.77

    21.85

    16.38

    11025

    95.11

    47.55

    23.78

    15.85

    11.89

    16000

    65.54

    32.77

    16.38

    10.92

    8.19

    22050

    47.55

    23.78

    11.89

    7.93

    5.94

    32000

    32.77

    16.38

    8.19

    5.46

    4.10

    44100

    23.78

    11.89

    5.94

    3.96

    2.97

    48000

    21.85

    10.92

    5.46

    3.64

    2.73

    88200

    11.89

    5.94

    2.97

    1.98

    1.49

    96000

    10.92

    5.46

    2.73

    1.82

    1.37

    176400

    5.94

    2.97

    1.49

    0.99

    0.74

    192000

    5.46

    2.73

    1.37

    0.91

    0.68

     

     

    The most common audio format by far is 44.1 kHz / stereo / 16-bit; if your .wav file is of this format, you get just under 23 seconds before you hit the 4 MB limit.

    If you want to go over this limit, or if you want a multichannel logoff sound, you can get away with downsampling.  If you shoehorn in a longer sound, though, you may run into this:

     http://blogs.msdn.com/photos/matthew_van_eerde/images/9020846/original.aspx

    If you just wait, the sound will play to the end and logoff will continue.

    If you click "Cancel", explorer.exe will exit anyway and you'll be logged in with no shell.

    A trick to get the shell back: Ctrl-Shift-Esc to bring up Task Manager, and File | New Task (Run...) | explorer.exe to reinvoke the shell.  This also allows you to determine which of the notification area icons are well-behaved. :-)

  • Matthew van Eerde's web log

    Rotating a matrix redux

    • 2 Comments

    Vincent Tan picked up on Raymond Chen's "rotate a matrix" interview post.

    As Vincent Tan points out, there is no way to create an n x n matrix R such that RA is a rotated version of A - for example, in the 2 x 2 case:

    There is no 2 x 2 matrix R such that
    R [ a b ] = [ b a ]
    [ c d ] [ c d ]

    Vincent Tan points out that such an R would entail hidden assumptions but asks for a simpler proof.

    Here it is.  I'll go back to the n by n case, assuming n >= 2.  (The 0 x 0 case and the 1 x 1 case are actually trivially solvable using the identity matrix.)

    Assume there is such a matrix R = (rij)i,j∈{1...n} which has the property that RA = B = (bij)i,j∈{1...n} is the rotated version of A for any n x n matrix A = (aij)i,j∈{1...n}.

    To see that this is impossible, consider the matrix with a 1 in the upper-left-hand corner and zeros everywhere else; that is, a1,1 = 1, and aij = 0 for all other combinations of i and j.

    To be the rotated version of this matrix, B should have bn1 = 1 and bij = 0 for all other combinations of i and j.  (My coordinates are such that bn1 is the number in the top right corner of the matrix.)

    But how did that 1 get in the top right hand corner?  The rules of matrix multiplication imply that bn1 = r1,1an1 + r2,1an2 + ... + rn1ann. At first blush, this looks fine... until we realize that bn1 is 1, and all of the anj are 0... so we have the contradiction

    1 = r1,10 + r2,10 + ... + rn10 = 0

    QED.

    But this is not how rotation matrices are applied.  Rotation matrices R are not applied as RA = B; instead, they're applied as RAR-1 = B.  Not that this helps our hapless interviewee; the operation being asked of him ("rotate a matrix") can't be done by a rotation matrix anyway.  That is, there is no magic matrix R that works under this operation either.

    EDIT: A simple way to prove that RAR-1 = B doesn't work either (for n >= 2) is to think about what happens when you choose A to be the identity matrix I (the matrix with 1's on the main diagonal [i = j] and 0's everywhere else.)

    RIR-1 = RR-1 = I; and for n >= 2, I is not its own "rotation."

    We therefore arrive at the paradoxical result that you can't rotate a matrix via matrix rotation.

  • Matthew van Eerde's web log

    The largest prime ever - you saw it here first

    • 0 Comments

    The GIMPS project says they've found the largest prime number ever, but they're keeping quiet about what it is until they've verified it (they expect to be done in a couple of weeks.)

    Pshaw.  I can tell you right now what their prime number is.

    Since I'm a computer scientist I'll write it down in binary.

    GIMPS' LARGEST PRIME NUMBER IS (scroll down / highlight to view:)

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    0b
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111
    ...
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111

    EDIT: On Saturday 9/6 another prime was found.  They're also keeping mum about what this one is.  But I know this one too...

    EDIT2: Every new Mersenne prime also means a new perfect number is discovered; counting these two new Mersenne primes, there are now 46 known perfect numbers, all of them even.  (It is conjectured, but not proven, that all perfect numbers are even.)  To go from a Mersenne prime (which is of the form 0b111...11, where there are a prime number of 1's) to its corresponding perfect number, tack on one fewer number of 0's onto the end of the number: e.g., 0b11 (3, the first Mersenne prime) becomes 0b110 (6, the first perfect number;) 0b111 (7, the second Mersenne prime) becomes 0b11100 (28, the second perfect number) etc. (The proof that such numbers are perfect is simple; there is a more complicated proof that all even perfect numbers are of this form.)

    EDIT: I can now reveal that the number of 1s is 43,112,609.

Page 5 of 6 (141 items) «23456