Matthew van Eerde's web log

  • Matthew van Eerde's web log

    How to calculate a sine sweep - the wrong way


    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:

    u = τ log R
    τ = u / log R
    = du / log R

    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

    How to calculate a sine sweep - the right way


    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
    %     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);

    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:

        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

    Forcing Windows to install on a single partition


    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


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

    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 _
            Command Prompt
            ... 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

    Bad Perl: locker problem


    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

Page 1 of 1 (5 items)

August, 2009