# Matthew van Eerde's web log

• #### How to calculate a sine sweep - the wrong way

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

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

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

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)

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

Page 1 of 1 (5 items)