Bill Schottstaedt (bil@ccrma.stanford.edu)

Snd is a sound editor modelled loosely after Emacs and an old, sorely-missed PDP-10 sound editor named Dpysnd. It can accomodate any number of sounds at once, each with any number of channels. Each channel is normally displayed in its own window, with its own cursor, edit history, and marks; each sound has a 'control panel' to try out various changes quickly, and an expression parser, used mainly during searches; there is an overall stack of 'regions' that can be browsed and edited; channels and sounds can be grouped together during editing; edits can be undone and redone without restriction ('unlimited undo'); Snd can be customized and extended using a built-in Scheme interpreter (Gnu Guile); and it's free; the code is available via anonymous ftp from ccrma-ftp.stanford.edu as pub/Lisp/snd.tar.gz.

## Contents

Getting Started
File Operations
  The Display
  Other Options
Editing
  The Active Channel and The Cursor
  Marks
  Regions
  The Edit List
  How to ...
  Keyboard Commands
The Control Panel
Customization and Extension
Snd Resources
Planned Enhancements
Index

## Getting Started

Once compiled and loaded (run make in a shell, or get the executable images from ccrma-ftp), fire Snd up with

      snd some.snd

where "some.snd" is any available sound file. You should get a window with the first .1 seconds of the sound displayed as a time domain waveform. Click the file name at the lower left to get some information about the file. Click the "f" button, and an fft window appears alongside the waveform. Drag the upper scale at the bottom of the graph and both graphs are updated as you move through the file. Drag the lower scale to zoom in or out. Drag the outer scale (the wider one) on the left to zoom the y axis in or out. The inner scale moves the y axis up and down; its main use is to move the waveform out of the way of a mix console. Click the "w" button (to unset the button) and the time domain waveform goes away. Click "play" to play the file. "sync" is more complicated -- it is used to group sounds together for simultaneous editing.

Now return to the time domain form (click "w" and "f"), and click on the graph itself. A red cursor (a big "+") appears at that point. The cursor is exactly like an Emacs cursor -- you can delete the sample at the cursor, for example, by typing control D (abbreviated in this document C-d), or move back one sample with C-b. To see all the cursor-related commands, go to the "Help" Menu, and choose "Click for Help". The cursor becomes a question mark. Move the cursor to the graph portion of the window and click, and a help window pops up, telling all about it. You can use the same sequence to get help for anything in the Snd window, even the vertical bar after the file name.

Now click and drag the mouse through some portion of the graph -- the portion dragged is highlighted in some way. When you release the mouse button, the highlighted portion is 'selected' -- it becomes a 'region' that can be deleted, pasted elsewhere (move the mouse and click the middle button), played, and operated on in many ways. You'll notice if you make some change to the data that the file name gets an asterisk, as in Emacs, and the various 'undo' and 'redo' menu options come to life. Just for laughs, cut the selection, then click the right mouse button to get the popup menu, and try Undo followed by Redo.

Next type C-m -- this sets a mark at the current cursor location. C-a goes to the start of the window; C-j jumps forward to the nearest mark. Click and drag the upper horizontal mark portion to move the mark; click the triangular lower portion to play from the mark. Drag the triangular portion to play the data following the mouse.

Finally, go to the View menu and select 'Show controls'. A new portion of the Snd window is opened, containing a number of controls. Try goofing around with them while playing the sound. For the more complex cases, the button on the right side turns the option on or off. The sequence of changes you make while playing can be remembered (the 'Record' button), replayed ('Replay') or applied to the data as a kind of giant editing operation ('Apply').

## File Operations

      File Menu

        Open:    open a new file                                   (C-x C-f)
        Close:   close a file, flush any unsaved edits             (C-x k)
        Save:    save current edits, overwriting previous version  (C-x C-s)
        Save as: save current edits under a new name, stay in current file
        Revert:  flush edits
        Update:  re-read file (data changed behind Snd's back)
        View:    open file read-only
        Mix:     mix file
        New:     create a new, empty file
        Record:  record sound producing a new file
        Print:   produce a Postscript version of current display
        Exit:    leave Snd, flushing all pending edits

Snd operates on sound files. When invoked, Snd scans its arguments for file names, and opens any it finds.

      snd oboe.snd fyow.snd

If there are no arguments, Snd comes up as a bare menu bar. If a name is preceded by "-p" or "-preload", it is treated as a directory name and all sound files found in that directory are preloaded into the previous files list. To load arbitrary Snd customizations (scheme code, or a session file for example) precede the file name with "-l" or "-load".

Each sound file in the argument list can include start up information about the size and location of the initial waveform display.

      snd oboe.snd -s "0.0,0.25,0.75,0.3"

The flag "-s" introduces the size information, followed by a string containing the values of the x position, y position, x zoom, and y zoom scrollbars.

Normally Snd adds each new sound below those currently being displayed. To position sounds horizontally (adding on the right), use the "-h" (or "-horizontal") flag, or the horizontalPanes resource. (This only works on systems with Motif 2.0 or later).

A file can be opened from the File menu via Open or View. View opens the file read-only, whereas Open will allow it to be changed. The equivalent keyboard command is C-x C-f. You can also drag a sound file's icon and drop it on top of the Snd icon or the Snd menubar. If a file cannot be written (either it was opened read-only or you don't have write permission on it), a lock appears next to the file name. Similarly, if Snd notices that the file on the disk no longer matches the original, a bomb appears (this can happen if some other program writes a sound while you are editing an earlier version of it; see also overwrite-check).

In the file selection dialog, there's a button marked 'Sound files only'. This can be set by default (see Customization). If it is set, only files that appear to be sound files are included in the directory listing. Currently Snd uses the file extension to decide whether it is a sound file -- the acceptable extensions are snd, wav, aiff, au, aifc, voc, wve, and perhaps others.

Snd uses CLM's file header and data readers/writers so the file and data types that it can handle are:

read/write (many data formats):
  NeXT/Sun/DEC/AFsp
  AIFF/AIFC
  RIFF (Microsoft wave)
  IRCAM (old style)
  no header
  ----
read-only (in selected data formats):
  8SVX (IFF), IRCAM Vax float, EBICSF, INRS, ESPS,
  SPPACK, ADC (OGI), NIST-SPHERE, AVR, VOC,
  Sound Tools, Turtle Beach SMP, SoundFont 2.0,
  Sound Designer I and II, PSION, MAUD,
  Tandy DeskMate, Gravis Ultrasound, ASF,
  Comdisco SPW, Goldwave sample, omf, quicktime
  Sonic Foundry, SBStudio II, Delusion digital,
  Digiplayer ST3, Farandole Composer WaveSample,
  Ultratracker WaveSample, Sample Dump exchange,
  Yamaha SY85 and TX16, Covox v8, SPL, AVI
  ----
automatically translated to Sun 16-bit, then read/write:
  IEEE text, Mus10 SAM 16-bit (modes 1 and 4), IBM CVSD, AVI
  NIST shortpack, HCOM, Intel and Oki (Dialogic) ADPCM, MIDI sample dump
  G721, G723_24, G723_40, IFF Fibonacci and Exponential

'Linear' here means 2's complement integer. The files can have any number of channels. Data can be either big or little endian. The default output type is settable as the defaultOutputType resource. A raw data file gets its srate, chans, and data format information either from the variables raw-srate and friends (if raw-defaults == 1), or from a dialog window that pops up when such a file is opened. The files listed as "automatically translated" are decoded upon being opened, rewritten in Sun 16-bit format to a new file with an added (possibly redundant) extension .snd, and that form is the one the editor sees from then on.

Each file has its own 'pane', a horizontal section of the overall Snd screen space; within that section, each channel has a pane, and below the channels is the 'control pane', normally hidden except for the file name and 'minibuffer'. At the very bottom (or far right) of the Snd window is the lisp listener, if any (see the View menu "Open listener" option). The panes can all be independently raised and lowered by dragging the pane buttons on the right. The channel that is currently active (receiving keyboard commands) has a thin black border around the display portion. Each channel has the four scrollbars setting what portion of the data is displayed; the 'w' button (normally set) which causes the time domain waveform to be displayed; and the 'f' button (normally unset) which includes the frequency domain (FFT) display. There is a third display settable by user-provided functions; if both the 'w' and 'f' buttons are off and there is no active user-display function, you get an empty display. For each sound there is a control panel containing the file name, in parentheses if the file is actually a link, with an asterisk if there are unsaved edits, a 'minibuffer' for various kinds of text-based interactions, a 'sync' button for grouped display and edit operations, a 'unite' button (if the sound has more than one channel), and a 'play' button to play the current (edited) state of the file. Any number of files can be played at the same time. The rest of the control panel modifies how the file is played.

To open a new, empty file, use the New option.

To close a file (flushing any unsaved edits), use the File menu Close option, or C-x k. This command applies to the file that contains the active channel, or the top file in the display.

To save the current edited state of a file, use the Save option (to overwrite the old version of the file), or Save as (to write to a new file, leaving the old file unchanged). The equivalent keyboard command is C-x C-s (save). Other related keyboard commands are C-x w (save selection as file), and C-x C-w (extract and save the current channel as a file). Normally, if the new file already exists, and it is not currently being edited in Snd, it is silently overwritten. If you try to overwrite a file, and that file has active edits in a different Snd window, you'll be asked for confirmation. If you want Snd to ask before overwriting a file in any case, set the resource overwriteCheck to 1, or include the expression (set-ask-before-overwrite 1) in your Snd initialization file. If you edit a write-protected file and try to save the edits, Snd will try to save the edits in a temporary file and will post a warning that the current file could not be edited. A similar sequence can occur when opening a file on a write-protected directory where the sound file uses some compression scheme that Snd wants to translate before editing.

To undo all edits and return to the last saved state of a file, use the Revert option. The edit history is still available, so you can redo all the edits in order simply by calling Redo repeatedly.

The Print option fires up the Print dialog. You can send the currently active graph directly to a printer, or save it as an "encapsulated Postscript" file. The default name of this file is "snd.eps"; the resource that overrides this default is named 'epsFile'.

To mix files, see "Mix Files". To record a file, see "Record Files".

Finally, to exit Snd cleanly (that is, removing any temporary files, and cleaning up some system stuff), use the Exit option. Unsaved edits are silently flushed.

### The Display

      View Menu

        Show controls:    show/hide the control panel    (C-x C-o, C-x C-c)
        Normalize:        cleanup current Snd display
        Open listener:    show/hide lisp listener
        Channel style:    separate, combined or superimposed channels
        Graph style:      use dots, lines, or filled polygons in the data displays
        Verbose cursor:   describe the current sample every time the cursor moves
        Regions:          a browser to examine the region stack
        Files:            a browser of currently and previously loaded files
        Color:            a browser that sets color schemes
        Orientation:      a browser that sets spectrogram and wavogram orientation
        Groups:           group editor (tracks for mixing)
        Show marks:       show or hide current marks
        Show y=0:         show or hide the y=0 line
        X axis units:     x axis labelled in seconds, samples, percent of total

The file display can be modified in various ways. To use dots rather than connected lines, use the Dots option in the View menu's Graph style option (see also set-dot-size). Similarly, to show (or hide) the line Y = 0, use the y=0 option. The Region browser is described under Regions. To open the control panel, use Show Controls. Similarly, to open or close the lisp listener panel, use Open listener. You can also drag the associated pane button. When many files are displayed, and the pane buttons have been in use, the overall display can become a bit of a mess. To return to a state where each file and channel has a 'normal' amount of space, use the Normalize option.

The Color and Orientation options activate windows that set various aspects of the sonogram, spectrogram, and wavogram displays. There are eight or nine colormaps available along with ways to invert the maps, and scale (darken) them differently according to screen or printer characteristics. And the graphs themselves can be rotated and resized. The color variable default settings produce good output on the SGI but looks cluttered on some Linuces -- you may have to play around with the lightness scaler and so on to find reasonable values for your system.

The Popup menu's Info dialog can be left in view and updated with M-v i to reflect the currently active sound. Except for the header comment, the same information is displayed in the minibuffer when you click the file name.

The Files option fires up the file browser:

The file browser window shown above provides two lists, one of the currently active files in Snd, and the other of previously active files. The currently selected sound is highlighted. The save button saves current edits, if any; the play button plays the file; and the unlist button removes a file from the previous files list. Click a current file name, and that sound becomes the selected sound in the main Snd window. Click a previous file name, and that file is opened in Snd. The 'update' button runs through the previous files list checking for files that have been deleted or moved behind Snd's back. 'Clear' clears the previous files list. The previous files list can be preloaded via the -p switch to Snd, and the extended commands preload and preload-file-browser. By preloading your "working set" of sounds, you can save the bother of picking them up one by one from the clumsy file selection box.

The Regions option is described below.

### Other Options

      Options Menu

        Transform Options:   various transform choices
        Zoom style:      where to focus during zooms
        Subsampling off: graph subsampling on or off
        Save options:    save current state of options
        Session:         save current state or load previous session
        Speed style:     control panel speed scrollbar interpretation

The Options menu sets various preferences. The Transform Options menu applies mainly to the FFT display triggered by setting the 'f' button in the channel window. The dialog that is launched by this menu item has six sections: on the upper left is a list of available transform types; next on the right is a list of fft sizes; next is a panel of buttons that sets various display-oriented choices; the lower left panel sets the current wavelet, when relevant; next is the fft data window choice; and next to it is a graph of the current fft window; when the window has an associated parameter (sometimes known as "alpha" or "beta"), the slider beneath the window list is highlighted and can be used to choose the desired member of that family of windows.

The FFT is taken from the start (the left edge) of the current window and is updated as the window bounds change. If you'd like the fft size to reflect the current time domain window size:

    (set! graph-hook
      (string-append
        "(begin " graph-hook
        " (set-fft-size
            (expt 2
              (ceiling (/ (log (- (right-sample) (left-sample)))
                          (log 2.0))))))"))

The fft data is scaled to fit between 0.0 and 1.0 unless the fft normalization is off. The full frequency axis is normally displayed, but the axis is "dragable" -- put the mouse on the axis and drag it either way to change the range (this is equivalent to changing the variable spectro-cutoff). You can also click on any point in the fft to get the associated fft data displayed; if verbose-cursor is on, you can drag the mouse through the fft display and the description in the minibuffer will be constantly updated.

The harmonic analysis function is normally the Fourier Transform, but others are available, including about 20 wavelet choices, the Hankel and Chebyshev transforms, and perhaps others. (The Hankel transform returns the Bessel function spectrum, the Chebyshev transform returns the Chebyshev polynomial spectrum).

The top three buttons in the transform dialog choose between a normal fft, a sonogram, or a spectrogram. The "peaks" button affects whether peak info is displayed alongside the graph of the spectrum. The "dB" button selects between a linear and logarithmic Y (magnitude) axis. The "log freq" button makes a similar choice along the frequency axis.

The easiest way to change the colormap and graph orientation of the spectrogram, wavogram, and sonogram, is to use the Color and Orientation dialogs from the View menu. You can also use the numeric keypad, or Lisp expressions. The keypad keys are mapped to various variables as follows:

        variable         increase           decrease
      spectro-cutoff    PageUp (9)          PageDown (3)
      spectro-hop       Add (+)             Subtract (-)
      spectro-z-angle   RightArrow (6)      LeftArrow (4)
      spectro-x-angle   Ctrl-UpArrow (8)    Ctrl-DownArrow (2)
      spectro-y-angle   Ctrl-RightArrow (6) Ctrl-LeftArrow (4)
      spectro-z-scale   UpArrow (8)         DownArrow (2)
      fft-size          Multiply (*)        Divide (/)
      dot-size          Delete (.)          Insert (0)

You can rotate the spectrogram around the various axes by holding down the keypad and control keys. You can get arbitrarily small or large ffts with the Multiply and Divide keys. The x and y axis scalers are named spectro-x-scale and spectro-y-scale. The keypad Enter key resets all the spectrogram variables to their default values. (In Linux, use the corresponding numbered keys -- add shift to the key sequences given above). See also the Color and Orientation menu options in the View menu.

If the choice of sizes in the fft size list doesn't include the one you want, you can get arbitrarily small or large ffts with the Multiply and Divide keys. The keypad Enter key resets all the spectrogram variables to their default values. See also the fft-size variable. To interrupt a long transform-related computation, deactivate the 'f' button.

A somewhat frivolous feature, known to Snd as the "wavogram", mimics the spectrogram in the time domain. The same rotation commands apply to this display, with the additional variable wavo-hop which sets the density of the traces. To get this display `M-x (set-wavo 1)`. It is important in this case to get the length of each trace correct so successive peaks more or less line up. The trace length in samples is set by the variable wavo-trace, or the numeric keypad + and - keys.

When large amounts of data are being displayed, Snd may subsample the data to speed up the display process. This can introduce artifacts of the sampling interval on rare occasions. The Subsampling option turns this on or off. If you are displaying large portions of a sound and notice odd periodicities in the overall envelope displayed, try turning off subsampling before drawing any conclusions about the data.

The Save options menu option is best explained as a part of the customization process described below. It basically sets up an initialization file for Snd that sets all the options to their current settings; this is intended to be similar to a .emacs file (its default name is .snd).

The Zoom style option determines the graph point that tries to remain stable in the display during an x-axis zoom. The default is to zoom onto the cursor or the beginning of the current selection if either is visible. You can also have zoom focus on the left edge, right edge, or midpoint of the current window.

## Edit Operations

      Edit Menu
        Undo:              Undo last edit                  (C-x C-u or C-_)
        Redo:              Redo last edit                  (C-x C-r)
        Find:              Global search via find dialog   (C-s, C-r)
        Cut:               Cut (delete) selected portion
        Paste:             Paste (insert) selected portion (C-y, C-x i)
        Mix selection:     Mix (add) selected portion      (C-x q)
        Play selection:    Play selected portion           (C-x p)
        Save selection:    Save selected portion as file   (C-x w)
        Edit Envelope:     Edit or view envelopes
        Edit Header:       Edit or view file header
        Show edit history: Edit or view each channel's edit list

Editing in Snd is modelled after Emacs in many regards. Each channel has a cursor (a big "+"), a set of marks, and a list of edits that have not yet been saved. Most operations take place at the cursor. Operations can be applied simultaneously to any other channels or sounds by using the 'sync' button. And as in Emacs, there is a notion of a region ('selection'), and a list of saved regions. Operations can be applied either to a sample, a region, a channel, a file, or any number of files at the same time. Where an operation has an obvious analog in text editing, I've tried to use the associated Emacs command. To delete the sample at the cursor, for example, use C-d.

The following sections describe how to move the cursor and the window; how to change which channel is active; how to use marks and regions; how to perform various common editing operations. It ends with a description of all the mouse and keyboard editing commands. The 'control panel' provides more complex editing operations, but has a chapter to itself.

### The Active Channel and The Cursor

#### The Active Channel

The cursor (and its associated channel) is activated by clicking on the time domain waveform. The active channel normally has a dark edge around the graphics portion, as a sort of highlight. It is the window that receives keyboard commands. You can also move between windows with C-x o (forwards or backwards).

#### Moving the Cursor

Any mouse click on the waveform causes the cursor to move to that point. To move the cursor from the keyboard, use:

      <      move cursor to sample 0
      >      move cursor to last sample
      C-<    move cursor to sample 0
      C->    move cursor to last sample

      C-a    move cursor to window start
      C-e    move cursor to window end
      C-b    move cursor back one sample
      C-f    move cursor ahead one sample

      C-n    move cursor ahead one 'line'
      C-p    move cursor back one 'line'
      C-v    move cursor to mid-window

      C-i    display cursor info
      C-j    go to mark
      C-x j  go to named mark

All keyboard commands accept numerical arguments, as in Emacs. If the argument is a float, it is multiplied by the sampling rate before being applied to the command, so C-u 2.1 C-f moves the cursor forward 2.1 seconds in the data.

#### Moving the Window

The simplest way to move the window (the portion of the data in the current graph) is to drag the scrollbars with the mouse. The darker scrollbars zoom in and out; the lighter bars move the window along the x or y axis. Because sound files can be enormous, the x axis placement needs some special handling to make it useful in all cases. To move by a single windowful, click the arrows on the scrollbar. To move by smaller amounts, use the left and right arrow keys (or zoom with the up and down arrow keys); the control, shift, and meta keys are multipliers on this movement -- each key adds a factor of .5 to the multiple, so to move by .25 windows, press control, meta, left (or right) arrow. A similar mechanism can be used to zoom quickly onto a particular point; hold the keys and click the mouse in the waveform and you'll zoom an increasing amount into the data at that point.

Various keyboard commands provide much more precise control of the window bounds and placement:

      C-l      position window so cursor is in the middle
      C-x b    position window so cursor is on left margin
      C-x f    position window so cursor is on right margin
      [Down]   zoom out, amount depends on shift, control, and meta
      [Up]     zoom in
      [Left]   move window left
      [Right]  move window right
      C-x l    position selection in mid-view
      C-x v    position window over current selection
      C-x C-b  set x window bounds (preceded by number of leftmost sample)
      C-x C-p  set window size (preceded by size as numeric argument)

As in most other cases, the sample numbers (or sizes) can be floats; if the argument is not an integer, it is multiplied by the sampling rate before being applied to the command. So, C-u .1 C-x C-p makes the window display .1 seconds of data.

### Marks

A mark marks a particular sample in a sound file (not a position in that file). If we mark a sample, then delete 100 samples before it, the mark follows the sample, changing its current position in the data. If we delete the sample, the mark is also deleted; a subsequent undo that returns the sample also returns its associated mark. I'm not sure this is the right thing, but it's a lot less stupid than marking a position.

Once set, a mark can be moved (redefined) by dragging the horizontal tab at the top. Click on the triangle at the bottom to play (or stop playing) from the mark; drag the triangle to play following the mouse.

A mark can be named or unnamed -- the name is displayed above the horizontal tab at the top of the window. The following keyboard commands relate to marks:

      C-m       place (or remove if argument negative) mark at cursor
      C-x /     place named mark at cursor
      C-x C-m   add named mark

      C-j       go to mark
      C-x j     go to named mark

The distance from the cursor to a mark can be used as a numeric argument for other commands by following C-u with C-m. Any number in-between is the number of marks to jump forward before getting the distance.

The current marks assoicated with a sound can be saved in a file that Snd will load automatically later. The session command is the simplest way, but if you want to save just the marks, use the `M-x (save-marks)` command.

### Regions

A region (or selection -- I use the words interchangeably here) is a portion of the sound data. Regions can be defined by dragging the mouse through a portion of the data. If the mouse drags off the end of the graph, the x axis moves, in a sense dragging the data along to try to keep up with the mouse; the further away the mouse is from the display, the faster the axis moves. (One minor caveat: if you drag the mouse too quickly off the end of the graph, making a grand sweeping gesture, the last portion of the graph may be missed because the mouse updates are coalesced to some extent; move deliberately as you near the end of the sound). A region can also be defined with keyboard commands, much as in Emacs. C-[space] starts the region definition and the various cursor moving commands continue the definition.

Once defined, the selection is added to a stack of currently available regions (the stack size is normally 16). In many cases, the numeric argument to the command below chooses which region in that stack to use in the command. Since it can be hard to remember which region is which, especially since they are constantly on the move as the stack changes, there is a region browser, similar to the File browser, invoked from the View menu's Regions option:

The 'save' button here protects the region from deletion as the region stack grows. 'Print' produces a Postscript rendition of the current graph contents, using the default eps output name. 'play' plays the region. The graphical display shows the waveform with arrows to move around in the channels of multi-channel regions.

The keyboard commands that apply to regions are:

      C-y         paste in current selection at cursor
      C-[space]   start keyboard-based region definition
      C-x a       apply amplitude envelope to selection
      C-x c       define selection from cursor to nth mark
      C-x i       insert selection
      C-x n       re-evaluate expression over selection
      C-x p       play selection or region (numeric arg selects region)
      C-x q       mix in selection (float arg = scaler)
      C-x w       save selection as file
      C-x x       evaluate expression over selection

      C-x l       position selection in mid-view
      C-x v       position window over current selection

### The Edit List

The current state of the undo/redo list can be viewed as a scrolled list of strings by choosing the Edit menu's Show edit history option. The list is placed on the left of the associated channel pane. If there are no current edits, it just lists the associated file name (i.e. the zero-edits state). As you edit the sound, the operations appear in the edit list window. Click on a member of the list to move to that point in the edit list (equivalent to some number of undo's or redo's). To move to a given edit point and follow the sync chain (if any), use control-click.

Use edit-history-width to change the edit list's width. examp.scm has key bindings that might make this process simpler. If Guile is loaded, the function save-edit-history saves the current edit list as a loadable program (assuming the base sounds haven't changed in the meantime). The file can be edited (it's just a text file with comments). (more to come...)

### How to...

Save, open, close, print
Delete, insert, mix
Multi-channel operations
Amplitude envelopes and scaling
Find
Change samples
Undo, redo, revert
Play
Mix Files
Keyboard macros
Change file format
Extend a file
Record a file
Edit or view an envelope
Edit, add, or remove the header
Center a tiny signal with DC
Save state for later restart
Miscellaneous commands

#### Save, open, close, print

Most of these kinds of operations are accessible from the File menu. They can also be invoked from the keyboard:

      C-x k     close currently selected file
      C-x w     save selection as file
      C-x C-d   print
      C-x C-f   open file
      C-x C-s   save file
      C-x C-w   save currently selected channel as file

The Print command produces a PostScript file which can be sent to directly a printer or saved for later use.

#### Delete, insert, mix

The fastest way to delete a section is to drag the mouse through it and call the Edit menu's Cut option. Any active region can be pasted or mixed in using C-x q and C-x i with a numeric argument (the region number); the current selection (region 0) can be pasted in by clicking the middle mouse button. The associated keyboard commands are:

      C-d      delete sample at cursor
      C-k      delete a 'line' -- line-size (128) samples
      C-w      delete current selected portion

      C-o      insert a zero sample at cursor
      C-x i    insert selection at cursor (arg = region number)
      C-x C-i  insert file

      C-y      paste in current selection at cursor

      C-x q    mix in region (float arg scales mix, int arg = region number)
      C-x C-q  mix in file

#### Multi-channel operations

Normally each operation applies only to the currently active channel. If, however, its 'sync' button is on, the operations apply to every sound or channel that also has the sync button set. A multichannel sound also has a 'unite' button to the left of the 'sync' button. If this button is set, all channels are displayed in one graph; the x and y-axis scrollbars apply to all the channels at once, as do the 'f' and 'w' buttons; two new scrollbars appear on the right of the window; the furthest right scrollbar affects the placement of the window within the overall set of graphs, and the scrollbar on its left zooms in and out of the overall graph. For stereo files, this is user-interface overkill, but the hope is to accomodate sounds with many channels, making it easy to focus on particular portions and so on. The View menu Channel style option has the same effect but applies to all active multichannel sounds. Control-click the unite button to get superimposed channels. If the channels are not combined (the default), control-click the 'f' or 'w' button in one channel to affect all channels at once.

To get multi-channel selections, set the sync button, then define the selection (by dragging the mouse) in one channel, and the parallel portions of the other channels will also be selected.

#### Amplitude envelopes and scaling

An envelope in Snd is a list of x y break-point pairs. The x axis range is arbitrary. For example, to define a triangle curve: '(0 0 1 1 2 0). There is no (obvious) limit on the number of breakpoints. Envelopes can be defined with defvar and referred to thereafter by name. This can save much typing. Use the envelope editor to draw envelopes with the mouse.

To apply an envelope to a sound, use the extended command C-x C-a. If this command gets a numeric argument, the envelope is applied from the cursor for that many samples. Otherwise, the envelope is applied to the entire file.

      C-x a     apply amplitude envelope to selection
      C-x C-a   apply amplitude envelope to channel

You can also specify an envelope name to the C-x C-a prompt.

To scale a file or selection by or to some amplitude, use the lisp functions:

      scale-by args
      scale-to args
      scale-selection-by args
      scale-selection-to args

scale-by scales the current sync'd channels by its arguments, and scale-to scales them to its arguments (a "normalization"). The arguments in each case are either a list of floats corresponding to each successsive member of the current set of sync'd channels, or just one argument. In the latter case, scale-by uses that scaler for all its channels, and scale-to normalizes all the channels together so that the loudest reaches that amplitude (that is, (scale-to .5) when applied to a stereo file means that both channels are scaled by the same amount so that the loudest point in the file becomes .5).

#### Find

Searches in Snd refer to the sound data, and are, in general, patterned after Emacs. When you type C-s or C-r, the minibuffer below the graph is activated and you are asked for the search expression. The expression is a piece of C-like code that describes which sample satisfies the search. For example, to look for the next sample that is greater than .1, we could type: y > .1. The cursor then moves to the next such sample, if any. Successive C-s's or C-r's repeat the search. C-x C-s can redefine the search pattern, which is also cleared by various other commands, much as in Emacs.

The search (and C-x C-x) expression syntax includes most of C's operators, the standard math library, as well as a few variables internal to Snd. To get at the current sample's value (the sample that the cursor is sitting on), use 'y'. 'y(n)' refers to the sample n samples from the current one. Similiarly, each of the other channels besides the current one is accessible as y1..8(n) (where the offset argument is optional); the channels are assigned to these yn functions in the order they occur in the Snd display (sounds from top to bottom, channels in order within a sound). As an example, say you want to find where two channels differ:

      C-s y != y1

Or you want to find where the current channel has three consecutive zeros:

      C-s (y == 0.0) && (y(1) == 0.0) && (y(2) == 0.0)

Normally, the search applies only to the current channel. To search all active files at once, use the Edit menu's find option.

The available C operators are:

    + - * / > >= < <= == !=
    ( ) { } += *= /= -= = || && ? : !

The available functions are:

    log log10 exp cos sin abs (i.e. fabs) pow sqrt
    atan acos asin cosh sinh tanh fmod ceil floor

      y:             value at cursor (y(n) also)
      y1..8:         value ar cursor (y1(n)) in channel n (counting sounds from top)

The search commands are:

      C-r   find backwards
      C-s   find forwards

#### Change samples

The simplest changes are:

      C-z       set current sample to zero
      C-x C-z   smooth data using cosine

C-x C-x y = .1 sets the sample at the cursor to .1. To set several samples to zero, define a selection over the desired samples, then C-x x y=0. Or use C-u preceding the C-x C-x command. For more complex operations, you need to use lisp expressions, described under Lisp.

Another way to use expressions is to make new sounds from existing ones. Say we want to make a new sound that is the difference of two others: make a new file (via the File menu New option, or `M-x (new)`), make room in it (via C-u 1.0 C-o or whatever), then:

      C-u 1.0 C-x C-x y = y1 - y2

In this particular case, a simpler way would be to scale the first by -1, then mix in the second.

#### Undo, redo, revert

Snd supports 'unlimited undo' in the sense that you can move back and forth in the list of edits without any obvious limit on how long that list can get. The data displayed is always the edited form thereof. Each editing operation extends the current edit list; each undo backs up in that list, and each redo moves forward in the list of previously un-done edits. Besides the Edit and Popup menu options, there are these keyboard commands:

      C-x r     redo last edit
      C-x u     undo last edit
      C-x C-r   redo last edit
      C-x C-u   undo last edit
      C-_       undo last edit

Revert is the same as undoing all edits.

#### Play

To play a sound, click the 'play' button. While it is playing, you can click the button again to stop it, or click some other file's 'play' button to mix it into the current set of sounds being played. To play from a particular point, set a mark there, then click its 'play triangle' (the triangular portion below the x axis). To 'rock the reels', that is to play while dragging the mouse back and forth, drag the mark's play triangle. The Edit menu 'Play' option plays the current selection, if any. The Popup menu's 'Play' option plays the currently selected sound. And the region and file browsers provide play buttons for each of the listed regions or files. If you hold down the control key when you click 'play', the cursor follows along as the sound is played. If you stop the play in progress, the cursor remains where you stopped it, but otherwise returns to its original position. Type space (without control) to pause and continue during playback.

In Linux, the soundcard input lines are sometimes left active by default, causing an amazing amount of hum and whatnot. To try to turn these off, call the function clear-audio-inputs.

The color of the play button corresponds to the state of the playback: normal: not playing, blue: playing, green: playing and tracking with the cursor (if any), red: playback paused.

The keyboard commands for playing are:

      C-q    play current channel starting at the cursor
      C-t    stop playing
      C-x p  play selection or region (numeric arg selects region)

In a multi-channel file, C-q plays all channels from the current channel's cursor if the sync button is on, and otherwise plays only the current channel. Except in the browsers, what is actually played depends on the control panel.

#### Mix Files

Since mixing is the most common and most useful editing operation performed on sounds, there is relatively elaborate support for it in Snd. To mix in a file, use either the File Mix menu option or the command C-x C-q. Currently the only difference between these two is that the Mix menu option tries to take the current sync state into account, whereas the C-x C-q command does not. To mix a selection, use C-x q. The mix starts at the current cursor location.

Each individual mix portion has a "mix console", a small box displayed above the waveform containing various controls. These consoles follow the sync buttons where relevant. More importantly, consoles can be edited together by collecting related mix portions into a group, then firing up the Group Editor (via the View menu Groups option). In a sense, a group can be viewed as Snd's way of implementing a more normal mixer's "tracks".

##### The Mix Console

When a section or file is mixed into the current file a mix console is associated with it, each output channel getting its own console. The console is displayed at first as a row of widgets giving the input file name, the begin and end times of the mixed-in portion (click to change from seconds to samples), then three icons:

      a speaker:   while pushed, the input is played
      an 'x':      click to remove the console permanently
      a box:       click to open (or close) the console

You can drag the widgets to change the position of the mix. Once opened, each console presents a pane with an amplitude slider for each input channel, and a speed control (srate change on the input). The initial state of the console sets the speed to 1.0, and all the input amplitudes 0.0 except the channel that matches the current output channel, which is set to 1.0 (a straight mix). To return to this state at any time, click the 'amp:' label. To turn the mix off ('mute' it, set all amps to 0.0), double click the label; to return to the last settings you made, click it with control or meta down. Similarly, click the 'speed:' label to reset it to 1.0, and click it with control or meta to return to your last settings. Each time you release the mouse button (or click the amp label) counts as another 'edit' of the file, so it is usually better to use 'undo' and 'redo' in this context, rather than repeated clicks and shift-clicks. The srate scale is interpreted in the same way as the sound pane speed control -- as a float normally, but also, if you like, quantized to semitones or integer ratios.

To change the scale interpretation, set the variables mix-amp-scaler, mix-speed-scaler, and in the group editor mix-tempo-scaler; all default to 1.0 which gives a scaling range from 0 to around 12. These numbers actually scale an exponent, so (for example) if mix-amp-scaler is set to 0.5, the scale goes from 0.0 to around 3.5; similarly if mix-tempo-scaler is 0.025, its scale goes from around .95 to 1.05.

To reduce the mix console to the single letter 'M', double click the file name. Double click the 'M' to return to the original row of icons. Since screen space is at a premium, this minimal form of the console can reduce clutter. You can still drag the 'M' to reposition the mix.

When any edit is performed that changes the file within the mixed portion, the affected mix consoles are removed from the display, and the only way to return to them is to undo the offending edit. That is, if you mix a portion, then cut some part of that portion, the mix will be locked in place from then on, as if you had clicked the 'x' button on the mix console.

To turn off the constant graphics updates (which can slow down old machines like mine, and which can also be annoying when you know what you're doing), set the variable movies to 0 (it is also accessible in the Group Editor).

When a sound is mixed into a file that has its sync button on, the separate channels are tied together so that as long as the sync button is on, if you move one mix console the other sync'd consoles move with it. Similarly, any speed change is reflected automatically in the other consoles; amplitude changes however, are not copied. To make the sync'd consoles independent, turn off the sync button. Once unsync'd, the consoles remain independent unless you 'undo' enough edits to return to the sync'd state.

Normally the console is lined up with its left edge at the beginning of the mixed segment. You can move the console anywhere within the segment by setting its "anchor" to the position (sample) within the mix that should correspond to the console's left edge. See mix-anchor.

To get an indication of the start and end points of the mix segment, set the group editor "show duration" button, or set the Snd variable mix-duration-brackets to 1.

##### Grouped Mixes

To tie together an arbitrary collection of mix consoles, use the 'group' buttons in the upper right corner of the mixer. Any mixers that share a button can be changed in parallel using the Group Editor (the Groups option under the View menu). The group editor gives amplitude control over each output channel that has a mix that is a member of the group. The speed control affects the sampling rate, and the tempo control affects the spacing of the individual members of the group. The play button plays just the group members.

The group editor envelope fields use the same syntax as other Snd envelopes: '(0 0 1 1) is a ramp, for example, and '(0 0 1 1 2 0) is a sort of pyramid. The envelope data in a given field only takes effect after the field has been "activated" (normally by a carriage return). The tempo envelope is interpreted in terms of the current group times using the placement of the given mix within the group to find the parallel place on the (arbitrary) tempo envelope x axis. The value of the envelope at that point becomes another tempo multiplier; that is, these envelopes are not time maps (perhaps someday!). Since a tempo value of 2 makes things happen twice as slowly (it essentially multiplies begin times), the tempo envelope causes things to go faster as it gets closer to zero -- weird! The speed envelope changes the overall speed of a given segment, but doesn't change within that segment.

The underlying mix consoles have independent envelopes, but my original plan to include envelope text fields in the consoles made them too big, cluttered, and unwieldy; an attempt to make each console a scrollable (or paned) window failed due to unfortunate limitations in Motif. These could be overcome, but would require much more programming than I think the issue is worth. I'm interested in better ideas, if anyone has any. One idea I'm goofing around with makes the mix matrix entries visicalc-like expressions.

To move the cursor from one mix to the next, in the same manner as C-j moves through marks, use C-x C-j.

##### Group Changes and Undo

Since a mix is viewed in Snd as just another edit which you can undo and redo, and since one mix console can be participating in any number of groups, and since any number of files can have these grouped mixes active at once, and since you can ungroup a mix, then undo the related edit, it becomes a bit of a pain to describe what each sequence of actions will do. In general, think of a group as simply another kind of 'sync' button. The Group Editor itself does not follow the undo/redo chains (edits in Snd are considered to be local to each channel, but the group editor affects all mixes together, possibly across many channels). Each change to a group control immediately affects all mixes associated with that group, in each case as a single edit of each participating channel. Each change to the mix console takes into account the state of the groups that it is a member of. Undo of any edit simply undoes the edit -- the mix console will back up one state, but if the group controls have changed in the meantime, the two are now out of sync. Similarly, if you remove a mix from a group, the group's effect upon the mix is removed as well. If it joins a group with current state, that causes an immediate change in the mixed portion's state. The tempo control, however, only affects mixes that are under its control when it is changed (does that make sense? -- the idea is that you might want to leave a group briefly to fix a local mix position or speed, then rejoin the group, but in that process you don't want the tempo control to cause the mix to jump about randomly in time). Similar complications affect the group envelopes. You can choose whether the envelope is applied over the entire output duration, or just the group duration; in the latter case, you need to be aware that adding or removing mixes can change that duration, changing the effect of the envelope. Group state changes by themselves are not edits (i.e. if a group has no members, undo and redo will not notice that you've been fiddling with its amp scalers). If a mix is participating in several groups, all associated groups affect the mix together (group states are multiplied, and envelopes are "melded" into something resembling a gathering of the various envelopes). If a mix is synced to others, and joins or leaves a group, all the synced mixes follow its lead. All of this can be summarized: groups act like the sync buttons. And if it's confusing, consider the alternatives; or better, decide once and for all which mixes are grouped together, and use only one group per mix. Then everything should be "intuitive".

#### Keyboard macros

As in Emacs, C-x ( begins keyboard macro definition, C-x ) ends it, and C-x e executes the last keyboard macro. Unlike Emacs, C-x C-e prompts for a name for the last defined macro; M-x name invokes the macro "name", the function save-macros saves all current named macros, and save-macro saves one (named) macro in the initialization file (normally .snd). See the lisp section for more details.

#### Change file format

To change the sound file's header or data format, use the File or Edit menu Save as option:

Choose the header type you want, then the data format, (the data format list will change depending on the header choice). The File version saves the current selected file. The Edit version saves the currently selected region.

#### Extend a File

Normally Snd keeps the current cursor, and therefore most actions you can perform on the current channel, within the current channel's bounds. The easiest way to extend the file is to pad it with zeros. Go to the end of the file, via the C-> command, then use the C-u command with a float argument, giving the number of seconds to add to the end of the file, followed by C-o (insert zeros): for example, to add a second, C-> C-u 1.0 C-o. The same sequence can be used to add silence to the start of a file.

#### Record a File

To make a recording, choose "Record" from the File menu. A window opens with the various recording controls:

The top three panes display the status of the input and output lines. If a channel is active, its meter will glow yellow. If some signal clips during recording, the meter will flash red. The numbers below the channel buttons indicate the signal maximum since it was last reset. The sliders underneath the meters scale the audio data in various ways before it is mixed into the output. The vertical sliders on the right scale the line-in and microphone signals before the meter, and the output signal before it gets to the speaker (these are needed to avoid clipping on input, and to set the 'monitor' volume of the output independent of the output file volume).

The fourth pane has information about the current output file (its name and so on), and the layout of the window. The buttons on the right can be used to open and close panes painlessly. If the button is not square (a diamond on the SGI), the underlying audio hardware can't handle input from that device at the same time as it reads other "radio" button devices. So, in that case, opening the panel via the button also turns off the other incompatible device. The 'autoload' button, if set, causes the recorded file to be loaded automatically into Snd.

The fifth pane contains a history of whatever the recorder thought worth reporting. The duration field gives the current output file's duration. The bottom row of buttons dismiss the window, start recording, cancel the current take, and provide some help. There's also a slider on the far right that controls the speaker output volume (independent of the output file volume).

To make a recording, choose the inputs and outputs you want; for example, to record channel A from the microphone to channel A of the output file, click the Microphone panel's A button and the Output panel's A button. Then when you're ready to go, click the Record button. Click it again to finish the recording. The default is to provide up to two channels of output; if you want to write output files with more channels, set the recorder-out-chans variable before invoking the recorder.

If the record window's VU meters are too big (or too small) for your screen, you can fool around with the variable vu-size which defaults to 1.0. Similarly the variable vu-font-size tries to change the size of the numbers on the label, and vu-font chooses the family name of the font used (normally "courier").

#### Edit or View an Envelope

The Edit Envelope dialog (under the Edit menu) fires up a window for viewing and editing envelopes. The dialog has a display showing either the envelope currently being edited or a panorama of all currently loaded envelopes. The current envelope can be edited with the mouse: click at some spot in the graph to place a new breakpoint, drag an existing breakpoint to change its position, and click an existing breakpoint to delete it. The Undo and Redo buttons can be used to move around in the list of envelope edits; the current state of the envelope can be saved with the 'save' button, or printed with 'print'.

Envelopes can be defined using defvar, and loaded from a separate file of envelope definitions via the Session dialog's Load command. For example, the file:

      (defvar ramp '(0 0 1 1))
      (defvar pyramid '(0 0 1 1 2 0))

defines two envelopes that can be used in Snd wherever an envelope is needed (e.g. C-x C-a). You can also define a new envelope in the dialog's text field; '(0 0 1 1) followed by return fires up a ramp as a new envelope.

In the overall view of envelopes, click an envelope, or click its name in the scrolled list on the left to select it; click the selected envelope to load it into the editor portion, clearing out whatever was previously there. To load an exisiting envelope into the editor, you can also type its name in the text field; to give a name to the envelope as it is currently defined in the graph viewer, type its name in this field, then either push return or the 'save' button.

Once you have an envelope in the editor, it can be applied to the currently active sounds via the 'Apply' or 'Undo&Apply' buttons; the latter first tries to undo the previous edit, then applies the envelope. The envelope can be applied to the amplitude, the spectrum, or the sampling rate. The choice is made via the three buttons marked 'amp', 'flt', and 'src'. The filter order is the variable filter-env-order which defaults to 40. To interrupt the application of the envelope, click the 'Stop' button.

The two toggle buttons at the lower right choose whether to show a light-colored version of the currently active sound (the 'wave' button), and whether to clip mouse movement at the current y axis bounds (the 'clip' button). The 'linear' and 'exp' buttons choose the type of connecting lines, and the 'exp base' slider at the bottom sets the 'base' of the exponential curves, just as in CLM.

#### Edit, add, or remove the header

The Edit menu's Edit Header option fires up a dialog to edit, add, or remove the sound's header. No change is made to the actual sound data; the new header is blindly written out; any unsaved edits are ignored. If you specify 'raw' as the type, any existing header is removed. This dialog is aimed at adding or removing an entire header, or editing the header comments; anything else is obviously dangerous. If you don't mess with the data location, it will be updated to reflect any header changes; that is, unless you intervene, the resultant header will be syntactically correct. After writing the new header, you should either close or update the associated sound.

#### Sessions

At any time you can save the current state of Snd by calling `(session name)` where name is a file name. You can start in this state by calling Snd with this file name and the "-l" switch: snd -l name. This is called a session file, but it is in exactly the same format as the initialization file discussed above, and can be edited, renamed, or whatever. To load such a file after startup, use the command load: `M-x (load name)`. Currently, mix consoles are not saved, but the associated edits are.

#### Center a tiny signal with DC

Due to the quantized nature of the y-axis position scroller, a tiny signal that is not centered on 0 can be a pain to position in the window. Use the set-y-bounds function to set the y axis bounds to some small number, then use the position scroller to find the signal. For example, if your signal is a very soft recording setting only the lowest two bits of a 16 bit signal but with DC offset due to the recording conditions, M-x (set-y-axis -.01 .01) and try the scroller.

#### Miscellaneous commands

C-g at any point aborts the current keyboard command sequence, as does any mouse click. C-g can also interrupt some long computations (search, eval expression, and the various envelope applications).

C-u introduces a numeric argument. Besides the integer and float cases mentioned several times above, you can also use marks to set the argument. If the (optional) number after C-u is followed by C-m, the resultant number passed to the command is the distance (in samples) from the cursor to the n-th successive mark. That is C-u C-m C-f is the same as C-j.

C-x introduces an 'extended command'. It can be preceded by a numeric argument or aborted with C-g. C-x halts any on-going region definition.

C-x d prompts for the temporary directory name. Snd saves some editing operations in temporary files, rather than in-core buffers. If the temporary directory has been set (in various ways), it is used; otherwise Snd looks for the TMPDIR environment variable; if it is not found, or is null, the directory /var/tmp is used.

C-x C-c closes the control panel. C-x C-o opens the panel.

C-x C-x evaluates an expression; C-x C-n re-evaluates it.

To change a key binding, use global-set-key.

### Keyboard Commands

There are two types of keyboard commands in Snd: those associated with the Meta ('Alt') key, used as mouse equivalents for various menu options, and all the rest. The menu-related commands are shown underlined in the menubar. You type the underlined letter with Meta, then just the letter (no Meta) of the option you want. The menu-related commands are:

     File Menu        Edit Menu             View Menu             Options Menu               Help Menu

    M-f o: Open     M-e u: Undo            M-v s: Show controls  M-o s: Transform Options  Click for help
    M-f c: Close    M-e r: Redo            M-v n: Normalize             Speed style        Overview
    M-f s: Save     M-e f: Find                   Open listener         Focus style        FFT
    M-f a: Save as  M-e c: Cut             M-v c: Channel style  M-o o: Subsampling off    Find
    M-f r: Revert   M-e p: Paste           M-v d: Graph style    M-o a: Save options       Undo and Redo
    M-f m: Mix      M-e m: Mix Selection          Verbose cursor        Session            Sync
    M-f u: Update   M-e p: Play Selection  M-v r: Regions                                  Speed
    M-f n: New      M-e s: Save Selection  M-v b: Files                                    Expand
           Record          Edit Envelope          Color                                    Reverb
    M-f v: View            Edit Header     M-v o: Orientation                              Contrast
    M-f p: Print           Edit History           Groups                                   Envelope
    M-f x: Exit	                       M-v m: Show marks                               Marks
                                           M-v y: Show y=0                                 Mixing
                                                  Hide consoles                            Formats
                                                  X axis units                             Customization
                                                                                           Recording

The rest of the keyboard commands refer to the currently active graph, and any graphs that are currently sync'd to it. In general, commands are analogous to Emacs where such an analogy exists; in other cases, an extended command followed by a key with control affects the current channel whereas the same key without control affects the selection. Case is not significant.

Most of the commands accept a numeric argument which can be either an integer or a float; an integer causes the command to be repeated that many times; the float is usually multiplied by the sound's sampling rate, then applied that many times. So, for example, C-u 1.0 C-f causes the cursor to move ahead one second in the sound. The argument can be negative to reverse the sense of the command, as in Emacs. It is often useful to use the distance to a mark as a count. If the C-u n command is followed by C-m, the 'n' determines how many marks to move to, then the count returned is the distance from the cursor to that mark. For example, C-u C-m returns the number of samples between the cursor and the next mark, so C-u C-m C-z zeros all the samples between the cursor and the next mark.

The commands are:

      [Down]  zoom out
      [Up]    zoom in
      [Left]  move window left
      [Right] move window right
      [Home]  update current file (re-read data from disk)
      [Space] cancel and deselect selection, return to pre-select position
              if playing, pause or continue playback
      <:      move cursor to sample 0
      >:      move cursor to last sample
      C-<:    move cursor to sample 0
      C->:    move cursor to last sample
      C-a:    move cursor to window start
      C-b:    move cursor back one sample
      C-d:    delete sample at cursor
      C-e:    move cursor to window end
      C-f:    move cursor ahead one sample
      C-g:    abort current command
      C-h:    repeat external function call
      C-i:    display cursor info
      C-j:    go to mark
      C-k:    delete one line's worth of samples
      C-l:    position window so cursor is in the middle
      C-m:    place (or remove) mark at cursor location
      C-n:    move cursor ahead one 'line'
      C-o:    insert one zero sample at cursor
      C-p:    move cursor back one 'line'
      C-q:    play current channel(s) starting at cursor
      C-r:    repeat last search backwards
      C-s:    search according to an expression
      C-t:    stop playing
      C-u:    start count (numerical argument) specification
      C-v:    move cursor to mid-window
      C-w:    delete current region
      C-x:    start extended command (see below)
      C-y:    paste in region
      C-z:    set current sample to 0.0
      C-_:    undo last edit
      C-[Space]: start region definition (arg<0 => cancel and deselect)

The extended commands (preceded by C-x) are:

      a:    apply envelope to selection
      b:    position window so cursor is on left margin
      c:    define selection from cursor to nth mark
      d:    get temp dir name
      e:    execute keyboard macro
      f:    position window so cursor is on right margin
      i:    insert region
      j:    go to named mark
      k:    close file
      l:    position selection in mid-view
      n:    re-evaluate expression over selection
      o:    move to next or previous graph
      p:    play selection or region n
      q:    mix in region
      r:    redo last undone edit
      u:    undo last edit
      v:    position window over current selection
      w:    save selection as file
      x:    evaluate expression over selection
      z:    smooth selection
      /:    place named mark
      (:    begin keyboard macro definition
      ):    end keyboard macro definition

      C-a:  apply amplitude envelope
      C-b:  set x window bounds (preceded by first sample number)
      C-c:  hide ("close") controls
      C-d:  print
      C-f:  open file
      C-g:  abort command
      C-i:  insert file
      C-j:  go to mix console
      C-m:  add named mark
      C-n:  re-evaluate expression
      C-o:  show ("open") controls
      C-p:  set window size (preceded by size)
      C-q:  mix in file
      C-r:  redo last undone edit
      C-s:  save file
      C-u:  undo last edit
      C-v:  set window size as percentage of total
      C-w:  save current channel in file
      C-x:  evaluate expression
      C-z:  smooth using cosine

## The Control Panel

The control panel is the portion of each sound's display beneath the channel graphs. It is normally hidden, except for the upper portion that shows the file name, the sync and play buttons, and the minibuffer (the portion in between that opens into a text window when activated).

The controls are: amp, speed, expand, contrast, reverb, and filter.

'Speed' here refers to the rate at which the sound data is consumed during playback. Another term might be 'srate'. Snd normally uses linear interpolation to perform the speed change; to use sinc interpolation instead, use src or the envelope editor. The arrow button on the right determines the direction we move through the data. The scroll bar position is normally interpreted as a float between .05 and 20. The Options Speed Style menu (or the speed-style variable) can change this to use semitones (actually microtones) or just-intonation ratios. The number of equal divisions to the octave in the semitone case is set by the variable speed-tones (normally 12).

'Expand' refers to a kind of granular synthesis used to change the tempo of events in the sound without changing pitch. Successive short slices of the file are overlapped with the difference in size between the input and output hops (between successive slices) giving the change in tempo. This doesn't work in all files -- it sometimes sounds like execrable reverb or is too buzzy -- but it certainly is more robust than the phase vocoder approach to the same problem. The expander is on only if the expand button is set.

The reverberator is a version of Michael McNabb's Nrev. In addition to the controls in the control pane, you can set the reverb feedback gain and the coefficient of the lowpass filter in the allpass bank (see below). The reverb is on only if the reverb button is set. The reverb length field takes effect only when the reverb is set up (when the DAC is started by clicking 'play' when nothing else is being played).

'Contrast enhancement' is my name for a somewhat weird waveshaper or compander. It phase-modulates a sound, which can in some cases make it sound sharper or brighter. For softer sounds, it causes only an amplitude change. To scale a soft sound up before being 'contrasted', use the variable contrast-amp. The function maxamp returns the channel's maximum amplitude, so the inverse of that is a good first guess for contrast-amp. Contrast is on only if the contrast button is set.

The filter is an arbitrary order FIR filter specified by giving the frequency response envelope and order in the text windows provided. You can also specify the filter coefficients in a file of floats, then load them into the Snd filter by typing the file name in the filter envelope text window. The filter is on only if the filter button is set.

There are many variables that reflect or control the panel's various sliders; each also has a default or initial value. The reverb and expand functions also have several aspects that aren't brought out to sliders or buttons on the panel, but that can be accessed through these variables. See the lisp section for details.

The 's' (for 'Save') button saves the current control panel state for a subsequent 'Restore'. The 'r' (for 'Restore') button returns the control panel to the state at the time of the last save, or the initial state if there has been no save.

Except for the filter setting and the reverb length setting, the controls can be changed as the sound plays. You can record the changes you make by setting the 'Record' button, and replay the new version later with 'Replay'. The latter actually takes effect only when play is set in motion. 'Replay' and 'Record' can be set at the same time, allowing you to add more changes or override previous ones. To take all the current recorded changes and turn them into a giant 'edit' of the file, click the 'Apply' button. Apply may change the length of the file; for example, if reverb is on, the reverb decay length is added onto the end. Once Apply has taken effect, the controls section is reset to its clean state (so a subsequent 'play' plays the unmodified newly edited version).

Snd's control panel is not intended to replace mixers or CLM -- I view it as a quick-and-dirty 'cartooning' facility. After finding useful settings, you'll want to save the recorded changes and run them through CLM or some other hi-fi signal processing system.

The keyboard commands associated with the control panel are:

      C-x C-o   show ("open") control panel
      C-x C-c   hide ("close") control panel

## Customization and Extension

Constants
Variables
  Hooks
Functions
  Sndlib
Examples
Dynamically Loaded C Code

Nearly everything in Snd can be set in an initialization file, loaded at any time from a session file, specified via inter-process communciation from any other program, invoked via M-x in the minibuffer, imbedded in a keyboard macro, or dealt with from the lisp listener panel. The syntax used is lisp; if the Guile library is loaded, the underlying language is actually Scheme, these entities are fully incorporated into lisp, and all of them can be used in arbitrarily complicated functions. I've tried to bring out to lisp nearly every portion of Snd, both the signal-processing functions, and much of the user interface. You can, for example, add your own menu choices, editing operations, or graphing alternatives. These extensions can be loaded at any time.

Currently, if the listener exists, and some sound is selected, any characters typed while in the sound graph which it can't handle are passed to the listener; to exit the listener without using the mouse, type C-g.

In the following, optional arguments are in italics, functions available only if Guile is loaded are bold face. Channels are numbered from 0. If a channel argument is omitted, the currently active channel is used, if any; otherwise channel 0. Each sound has an associated "index" used to refer to it in all the functions. This somewhat arbitrary number is more or less related to the sound's position in the display of sounds. If the index is omitted, the currently active sound is used; if none, the top sound (or leftmost if you're using the horizontal panes).

This lisp interface is brand-new as of August-98; I'm very interested in feedback, and most willing to change anything. At least for the near future, backwards compatibility is not an issue.

### Constants

    Sndlib (selected header and data format types):
      next-sound-file    aiff-sound-file     riff-sound-file  snd-16-linear-little-endian
      snd-16-linear      snd-8-mulaw         snd-8-linear     snd-32-linear-little-endian
      snd-32-linear      snd-8-alaw          8-unsigned   32-float-little-endian
      snd-64-double      snd-24-linear       snd-32-float

    FFT style (the Transform Options Display choice):
      normal-fft         sonogram            spectrogram

    Transform type:
      fourier-tranform   wavelet-tranform    hankel-tranform  chebyshev-tranform   legendre-tranform

    FFT Window type:
      rectangular-window hanning-window     welch-window      parzen-window
      bartlett-window    hamming-window     blackman2-window  blackman3-window
      blackman4-window   exponential-window riemann-window    kaiser-window
      cauchy-window      poisson-window     gaussian-window   tukey-window

    Zoom Focus style:
      focus-left         focus-right        focus-active      focus-middle

    X-axis Label:
      x-in-seconds       x-in-samples       x-to-one

    Speed Control style:
      speed-as-float     speed-as-ratio     speed-as-semitone

    Channel Combination style;
      channels-separate  channels-combined  channels-superimposed

    Envelope Editor target:
      amplitude-env      spectrum-env       srate-env

    Graph Line style:
      graph-lines        graph-dots         graph-filled

    Keyboard action choices:
      cursor-in-view     cursor-on-left     cursor-on-right   cursor-in-middle
      cursor-update-display cursor-no-action cursor-claim-selection keyboard-no-action

### Variables

These variables are accessed as though each were a function of no arguments, and set using a function with "set-" prepended to the variable name. For example, auto-resize's current value can be accessed via (auto-resize), and set to a new value via (set-auto-resize #t). (I can't use normal Scheme variables here because set! would not affect the user-interface that reflects the variable; I need the "set-" forms anyway, so making everything a function makes for less confusion, I hope).

      ask-before-overwrite  0     (Save-as): ask before overwriting an existing file
      auto-resize           1     should Snd window resize upon open/close (see AutoResize)
      channel-style         channels-separate
                                  The default state of the 'unite' button in multi-channel files.
                                  Other values are channels-combined and channels-superimposed.
      color-cutoff          0.003 In spectra, sets the lowest data value that will be colored.
      color-inverted        1     The 'invert' button in the color dialog, negated.
      color-scale           0.5   The darkness setting in the color dialog, divided by 100.
      default-amp           1.0   These 'default' settings refer to the value given the control
                                  panel widgets when a sound is opened.  default-amp is the
                                  amplitude setting.  See amp).
      default-contrast      0.0   Initial contrast value.
      default-contrast-amp  1.0   Initial contrast scaler (see contrast-amp).
      default-contrasting   0     Initial contrast button value (contrasting?.
      default-expand        1.0   Initial expand value (expand).
      default-expand-hop    0.05  Initial expand hop value (expand-hop).
      default-expand-length 0.15  Initial expand segment length (expand-length).
      default-expand-ramp   0.4   Initial expand ramp length (expand-ramp).
      default-expanding     0     Initial value of expand button (expanding?).
      default-filter-order  2     Initial control panel filter order (filter-order).
      default-filtering     0     Initial filter button value (filtering?).
      default-output-type   next-sound-file
                                  The default header type when a new or temporary file is created (defaultOutputType resource).
      default-reverb-feedback 1.09 Initial reverb feedback coefficient (reverb-feedback).
      default-reverb-length 1.0   Initial reverb delay length scaler (reverb-length).
                                  This scales the length of all the delay lines used in the reverberator,
                                  so higher numbers give longer initial delays and a more cavernous
                                  effect.  In the control panel it is the scaler labelled "len:".
      default-reverb-lowpass 0.7  Initial reverb lowpass coefficient (reverb-lowpass).
      default-reverb-scale  0.0   Initial value of the reverb volume scaler (reverb-scale).
      default-reverbing     0     Initial reverb button value (reverbing?).
      default-speed         1.0   Initial speed (srate) scaler value (speed).
      dot-size              1     Size in pixels of dots when graphing with dots.
      edit-history-width    50    width (pixels) of edit history portion of channel pane.
      enved-base            1.0   Envelope editor exponential base value
      enved-clipping        0     Envelope editor 'clip' button
                                  If clipping, the motion of the mouse is restricted to the current graph bounds.
      enved-exping          0     Envelope editor 'exp' and 'lin' buttons
                                  If exping, the connecting segments use exponential curves rather than straight lines.
      enved-target          amplitude-env
                                  Determines how the envelope is applied to the current data
                                  This chooses one of the 'amp', 'flt', and 'src' buttons in the Envelope editor.
                                  The other (named constant) choices are srate-env and spectrum-env.
      enved-waving          0     Envelope editor 'wave' button
                                  The wave shown is the time domain display, even when filtering.
      eps-file              nil   Name of the Postscript file produced by the File Print option.
                                  See also the epsFile resource.
      fft-beta              0.0   The fft data window parameter, if relevant.  If any of the FFT
                                  variables is set to a new value, call update-ffts to see the effect.
      fft-log-frequency     0     If 1, the spectrum frequency axis is logarithmic, not linear.
      fft-log-magnitude     0     If 1, the spectrum magnitude axis is in decibels.
      fft-size              256   FFT size.
      fft-style             normal-fft
                                  The other choices are sonogram and spectrogram.
      fft-window            blackman2-window
                                  FFT data window. See the long list above for other choices.
      filter-env-order      40    The order of the Envelope editor's FIR filter.
      fit-data-on-open     -1     If 1, the initial time-domain display of a sound shows
                                  its entire duration, with the Y-axis set to show its maxamp.
                                  If -1 (the default), 32-bit linear sounds are fit, but no others.
                                  If 0, no files are fit.
      graph-style           graph-lines
                                  The only other choice currently is graph-dots.  This is
                                  equivalent to the View Lines/Dots menu option.
      initial-x0            0.0   Initial time domain window left bound (seconds).
      initial-x1            0.1   Same, but on the right; actual x1 is the lesser of this and the sound's duration
      initial-y0           -1.0   Initial window y axis minimum.
      initial-y1            1.0   Same, but maximum.
      line-size             128   Number of samples considered to be a 'line' (C-n and C-p commands).
      mix-amp-scaler        1.0   Multiplier on amp scales in mix consoles (see mix consoles).
      mix-duration-brackets 0     If 1, mixer consoles include brackets showing mixed sound duration.
      mix-speed-scaler      1.0   Multiplier on speed scales in mix consoles (mix consoles).
      mix-tempo-scaler      1.0   Multiplier on tempo scales in group consoles.
      mixer-group-max-out-chans 4 Maximum number of output scalers in mix console.
      mixer-groups          6     Number of mixer groups available.
      movies                1     If 1, the mix graphs are updated constantly as the mouse drags the mix console.
      normalize-fft         1     If 1, spectral data is normalized to 1.0 before display.
                                  If 0, you get the raw data values, which can reflect amplitude changes.  Snd tries
                                  to choose a y axis limit that makes successive displays move smoothly.
      normalize-on-open     1     When a new sound is added to the Snd window, the resultant
                                  set of graphs can start to dangle off the bottom or end of the screen.
                                  If normalize-on-open is 1, Snd tries to do something reasonable in this case.
      prefix-arg            nil   This is the keyboard C-u style argument (as in Emacs).
      print-length          12    In the listener, print-out of lists and vectors that are longer
                                  than print-length is truncated.
      raw-chans             1     The "raw-" variables refer to sound data interpretation choices made
                                  when a sound is opened that appears to be headerless.
                                  raw-chans sets the default number of channels.
      raw-format            16-linear
                                  The default data format in a headerless sound.  Other possibilities
                                  are given above, or you can use the Sndlib macros directly.
      raw-srate             44100 The default headerless sound sampling rate.
      raw-type              next-sound-file
                                  The default headerless file header type (for subsequent saves and so on).
                                  Snd only writes NeXT/Sun, AIFF, RIFF ('wave'), IRCAM, or raw files; the
                                  corresponding Sndlib macros are given above.
      recorder-autoload     0     The 'autoload' button in the recorder dialog.
      recorder-buffer-size  4096  The size of the recorder input buffer (there's a trade-off
                                  between responsiveness and clicks in some cases).
      recorder-file         nil   Default recorder output file name.
      recorder-in-format    16-bit linear
                                  Incoming data format for the recorder.  It's not currently safe to mess with this.
                                  It defaults to the host byte order.
      recorder-out-chans    2     Recorder output file channels.
      recorder-out-format   same as recorder-in-format
      recorder-srate        22050 Recorder sampling rate.
      reverb-decay          1.0   The length (seconds) of the reverberation after the sound has finished.
                                  The sound-local (control panel) version of this is reverb-length.
      save-state-on-exit    0     If 1, Snd saves its current state in session-file.
      session-file          nil   The default session file name.
      show-edit-history     0     If set, include edit history window in channel pane.
      show-fft-peaks        0     If set, fft peak information is included in the fft display.
                                  (This is the 'peaks' button in the Transform options dialog).
      show-marks            1     If 1, marks are displayed.  This is the 'Show marks' View menu option.
      show-mix-consoles     1     If 1, mix consoles are displayed.  This is the 'Show consoles' View
                                  menu option.
      show-y-zero           0     If 1, the y=0 axis is displayed.  This is the 'Show Y=0' View menu option.
      sinc-width            10    Width (in samples) of the sampling rate conversion sinc interpolation.
                                  The higher this number, the better the src low-pass filter, but the slower src runs.
      spectro-color        0      Colormap choice for spectrum display (see the Color Editor).
                                  This should be an integer between -1 and 8.  The maps (from 0 to 8) are:
                                  gray, hsv, hot, cool, bone, copper, pink, jet, prism.  -1 means black and white.
      spectro-cutoff        1.0   The amount of the frequency domain to include in the spectrum display.
                                  This number changes as you drag the frequency axis, for example.  This is the
                                  slider labelled '% of spectrum' in the View Orientation dialog.
      spectro-hop           4     The distance (samples) moved between successive spectrogram traces.
                                  This is the slider labelled 'hop' in the Orientation dialog.
      spectro-x-angle       90.0  Default spectrogram x-axis viewing angle.
      spectro-x-scale       1.0   Default scaler (stretch) along the spectrogram x axis.
      spectro-y-angle       0.0   Same for y-axis.
      spectro-y-scale       1.0   Same for y-axis.
      spectro-z-angle      -2.0   Same for z-axis
      spectro-z-scale       0.1   Same for z-axis.  For all of these variables, the easiest way to
                                  see what they refer to is to run the Orientation dialog with a spectrogram displayed.
      speed-style           speed-as-float
                                  In the control panel, the 'speed' control can be interpreted as a continuum
                                  (speed-as-float), as a just-intonation ratio of relatively small integers
                                  (speed-as-ratio) or as a step in a microtonal scale (speed-as-semitone).
                                  The default is 12 tones to the octave.  See the Speed style Options menu option.
      speed-tones           12    The number of tones per octave in the speed-as-semitone speed style.
      subsampling           1     To speed up the time domain display, Snd sub-samples the data.
                                  This can introduce confusing artifacts of the sampling process.
                                  (See the Options Subsampling menu).
      temp-dir              nil   Name of directory for temporary files.  nil usually means "/var/tmp".
      transform-type        fourier-transform
                                  The spectrum transform type.  Other types are given above.
      use-raw-defaults      0     If 1, the "raw-" variables' values are used automatically
                                  when a headerless file is encountered.  If 0, Snd fires up the
                                  raw file dialog to find out how to interpret the data.
      verbose-cursor        0     If 1, the cursor's position and other information is
                                  constantly displayed in the minibuffer.  This is the View menu's Verbose cursor option.
      vu-font               nil   The "vu-" variables refer to the VU meters in the recorder.
                                  vu-font is the font used to label the meters.  It is normally "courier".
      vu-font-size          1.0   This sets the recorder VU meter label font size.
      vu-size               1.0   This sets the overall size of the recorder VU meters.
      wavelet-type          0     If transform-type is wavelet-transform, wavelet-type selects which
                                  wavelet is used.  The list of available wavelets is in the Transform Dialog.
                                  There are currently 20 choices, so this variable goes from 0 to 19.
      wavo                  0     If 1, the time domain waveform is displayed as a 'wavogram'.
      wavo-hop              3     This sets the distance upward between wavogram traces; that is,
                                  the smaller this number, the more traces can be displayed.
      wavo-trace            64    This sets the length (samples) of each wavogram trace.
      window-height         0     The current Snd window height in pixels.
      window-width          0     The current Snd window width in pixels.
      window-x             -1     The current Snd window left side in pixels.
      window-y             -1     The current Snd window upper side in pixels (X numbering starts at 0 at the top).
      x-axis-style          x-in-seconds
                                  The x axis labelling of the time domain waveform can be in seconds
                                  (x-in-seconds), in samples (x-in-samples), or expressed
                                  as a percentage of the overall duration (useful in envelope definitions).
                                  The latter is x-to-one. This is the View menu 'X-axis units' option.
      xmax                  0.0   Sets the x axis maximum (truncates the display if the sound is longer).
                                  That is, you can display anything below xmax normally, but
                                  Snd refuses to go past that point.  Not sure why you'd want this...
                                  The default of 0.0 turns off this feature.
      xmin                  0.0   Sets the x axis minimum.
      ymax                  1.0   Sets the y axis maximum (useful to narrow the range of slider action).
      ymin                  1.0   Sets the y axis minimum.
      zero-pad              0     fft zero pad.
      zoom-focus-style      focus-active
                                  This determines what a zoom action focuses (centers) on.  See Zoom options.

#### Hooks

The hooks provide a way to customize various situations that arise through user-interface manipulations. Each is a string containing whatever lisp code should be evaluated. See the Examples section and the file examp.scm for examples.

      open-hook             called each time a file is opened (before the actual open).
                            If it returns #t, the file is not opened.
      close-hook            called each time a file is closed (before the close takes effect).
                            If it returns #t, the file is not closed.
      fft-hook              called just after an FFT (or spectrum) is calculated.
      graph-hook            called each time a graph is updated or redisplayed.
                            If it returns #t, the display is not updated.
      exit-hook             called upon exit.
                            If it returns #t, Snd does not exit.
      start-hook            called upon start-up.
                            If it returns #t, snd exits immediately.
      mouse-press-hook      called upon mouse button press within lisp graph
      mouse-release-hook    called upon mouse button release within lisp graph
      mouse-drag-hook       called upon mouse motion (with button pressed) within lisp graph
      key-press-hook        called upon key press while mouse is in lisp graph.
                            If it returns #t, the key press is not passed on to the main handler.

When these hooks are invoked, the following variables are set:

      open-hook-filename     name of file about to be opened
      close-hook-sound       index of sound about to be closed
      fft-hook-sound         index of sound just transformed
      key-hook-sound         index of sound when user-defined key binding is invoked
      graph-hook-sound       index of sound about to be displayed
      fft-hook-channel       channel of sound just transformed
      key-hook-channel       channel of sound when user-defined key binding is invoked
      graph-hook-channel     channel of sound about to be displayed
      fft-hook-scaler        multiplier used to scale  fft values
      graph-hook-y0          time domain graph y0 at time of call (set by vertical sliders)
      graph-hook-y1          time domain graph y1 at time of call (set by vertical sliders)
      graph-hook-x           lisp graph x position of mouse
      graph-hook-y           lisp graph y position of mouse
      graph-hook-button      button pressed (usually 1 or 2)
      graph-hook-state       control/meta/shift state upon button or key press
      graph-hook-key         key pressed (after keycode translations)

### Functions

These functions give lisp access to most of Snd's data structures and functions. In the argument lists below, snd as an argument refers to the sound's index, and defaults to the currently selected sound. Similarly, chn is the channel number, starting from 0, and defaults to the currently selected channel. So if there's only one sound active, and it has only one channel, (cursor) (cursor 0), and (cursor 0 0) all refer to the same thing.

      active-sounds     ()            return number of currently active (displayed) sounds.
      add-mark          (sample snd chn) add mark at sample.
      add-to-main-menu  (menu-label)  add new top-level menu named menu-label, return menu index.
                                          (add-to-main-menu "Tools") -> 5
      add-to-menu       (top-menu menu-label callback)
                                      add menu menu-label to top top-level menu whose index is
                                      top-menu with the lisp callback string callback.  The built-in
                                      Snd menus are numbered from 0 ('File') to 4 ('Help'). see also remove-from-menu.
                                          (add-to-menu 5 "Denoise" "(report-in-minibuffer \"denoise\")")
      amp               (snd)         return current amp (control panel slider) value.
      append-to-minibuffer (msg snd)  append msg to whatever is in snd's minibuffer.
      backward-graph    (count)       move back (up or left) count graphs (C-x C-o).
      backward-mark     (count)       move back count marks (C-j).
      backward-mix      (count)       move back count mix consoles (C-x C-j).
      backward-sample   (count)       move back count samples (C-b).
      change-menu-label (top-menu old-label new-label)
      channels          (snd)         return number of channels in snd.
      chans             (snd)         same as channels (the forgetful programmer's friend).
      clear-audio-inputs()            in Linux/OSS, try to reduce soundcard background  racket.
      clm-dialog        (msg)         fire up CLM dialog posting msg.
      close-sound       (snd)         close snd (same as File menu Close).
      color-dialog      ()            fire up the Color dialog.
      comment           (snd)         return snd's comment, if any.
      contrast          (snd)         return current contrast (control panel slider) value.
      contrast-amp      (snd)         return snd's contrast-amp (control panel variable).
      contrasting?      (snd)         return #t if snd has contrast turned on (control panel)
      control-panel-restore (snd)     same as pushing the control panel 'r' button.
      control-panel-save(snd)         same as pushing the control panel 's' button.
      cursor            (snd chn)     return cursor location (samples) of channel chn of snd.
      cursor-follows-play (snd)       return #t if cursor is following along in the sound as it plays.
      cut               ()            cut the current selection (a no-op if no active selection).
      data-format       (snd)         return snd's data format (sndlib).
      data-location     (snd)         return snd's data location (bytes).
      delete-mark       (samp snd chn) delete the mark at sample samp in snd's channel chn (- C-m).
      delete-region     (reg)         delete region number reg (which defaults to 0).  This removes the
                                      region from the region stack; it doesn't edit the corresponding file(s).
      delete-sample     (samp snd chn) delete sample samp in snd's channel chn.
      delete-samples    (samp samps snd chn) delete samps samples starting at sample samp.
      edit-header-dialog()            fire up Edit Header dialog.
      edits             (snd chn)     return a vector with number of undo-able edits and redo-able edits.
      env               (envelope samp samps env-base snd chn)
                                      apply (in amplitude) envelope to snd's channel chn starting
                                      at sample samp for samps samples with connecting segments
                                      based on env-base.  env-base defaults to 1.0 (line segments).
                                      samp defaults to 0.  samps defaults to the full duration.
                                      envelope is a list or vector containing the breakpoint values (as in CLM).
                                          (env '(0 0 1 1 2 0))
      env-selection     (envelope env-base snd chn)
                                      apply envelope to the currently selected portion of snd's channel chn.
      enved-dialog      ()            fire up the Envelope editor dialog.
      exit              ()            exit Snd.
      expand            (snd)         return current expansion amount (control panel).
      expand-hop        (snd)         return snd's expansion hop amount (seconds).
      expand-length     (snd)         return snd's expansion segment length (seconds).
      expand-ramp       (snd)         return snd's expansion ramp amount (between 0 and .5).
                                      This affects the smoothness of the grain overlaps -- .001 is a rattling effect.
      expanding?        (snd)         return #t if snd's expand button is on.
      fft               (rl im sgn)   perform an FFT on rl and im (the real and imaginary parts
                                      of the input data, both vectors whose length is some power of 2).
                                      sgn is 1 for an FFT, -1 for an inverse FFT; it defaults to 1.
      ffting?           (snd chn)     return #t if snd's channel chn is displaying a spectrum (the 'f' button).
      file-dialog       ()            fire up the list of current and previous files (not the file browser).
      file-name         (snd)         snd's complete file name.
      filter            (env order snd chn)
                                      apply an FIR filter of order order and frequency response env
                                      to snd's channel chn.  Currently, Snd uses frequency sampling to
                                      choose the filter coefficients, so be sure to make the filter order high enough
                                      to accomodate the narrowest band: (filter '(0 0 .01 1 .02 0 1 0) 200)
      filter-env        (snd)         snd's filter envelope (control panel).
      filter-order      (snd)         snd's filter order (control panel).
      filtering?        (snd)         return #t if snd is filtering (control panel filter button).
      find-mark         (samp snd chn) return index of mark at sample samp.  Marks are numbered
                                      from 0.  Return #f if there isn't a mark at sample samp.
      find-sound        (filename)    returns the index of filename (used as snd throughout).
                                      return #f if no sound is found that matches filename.
      forward-graph     (count)       move forward (down or right) count graphs (C-x C-o).
      forward-mark      (count)       move forward count marks (C-j).
      forward-mix       (count)       move forward count mix consoles (C-x C-j).
      forward-sample    (count)       move forward count samples (C-f).
      global-set-key    (key state code) cause key (integer) with modifiers state to evaluate code.
                                      When called, the variables key-hook-sound and key-hook-channel are set,
                                      as in the hook functions: (global-set-key (char->integer #\a) 4 "(set-edit-history-width 250)")
                                      The modifier state is a combination of shift: 1, control: 4, meta: 8, so this call
                                      causes C-a to set the edit-history windows' width to 250.  The value returned should
                                      be one of the cursor choices telling Snd what action (if any) to take after
                                      evaluating code.
      global-unset-key  (key state) cause key with modifiers state to be a no-op.
      graph             (data xlabel x0 x1 y0 y1 snd chn)
                                      Display a graph of data in a separate display per channel.  The x axis
                                      is labelled xlabel, the x axis units go from x0 to x1 (default 0 to 1.0),
                                      the y axis goes from y0 to y1 (default fits the data), and the display is
                                      associated with channel chn in snd.  data should be a vector.
                                          (graph #(0 .1 .2 .3 .4 .3 .2 .1 0) "roof")
      graphing?         (snd chn)     return #t if graph data is being displayed.
      group-amp         (group chan)  return group's chan-th output amplitude.
      group-beg         (group)       return group's begin time.
      group-dialog      ()            fire up the Groups browser.
      group-end         (group)       return group's end time.
      group-ok?         (group)       return  #t if group is active (i.e. has a member mix).
      group-speed       (group)       return group's speed.
      group-tempo       (group)       return group's tempo.
      groups            ()            return how many groups are currently active.
      guile             ()            return 1 if guile is loaded.
      header-type       (snd)         return (type . name)
      help-dialog       (subject help) fire up the help dialog with title subject and body help.
                                          (help-dialog "xyzzy" "are we having fun?")
      hide-listener     ()            close the lisp listener pane.
      insert-sound      (file in_chan snd chn)
                                      insert channel in_chan of file at the cursor in snd's channel chn.
      insert-region     (reg snd chn) insert region reg at the cursor in snd's channel chn.
      insert-sample     (samp value snd chn)
                                      insert sample value at sample samp in snd's channel chn.
      insert-samples    (samp samps data snd chn)
                                      insert samps samples of data starting at sample samp in snd's channel chn.
      key               (key state)   execute the keyboard command key with modifier keys state.
                                      shift: 1, control: 4, meta: 8 (see /usr/include/X11/X.h ControlMask et al).
      left-sample       (snd chn)     return the position in samples of the left edge of the time domain
                                      waveform for snd's channel chn.
      make-region       (beg end snd chn)
                                      create a new region spanning samples beg to end in snd's channel chn.
      mark-name         (mark snd chn) return name of mark.
      mark-sample       (mark snd chn) return position of mark.
      marks             (snd chn)     return number of marks in snd's channel chn.
      max-sounds        ()            return current size of sound array (grows as required, may contain holes).
      maxamp            (snd chn)     return max amp of snd's channel chn.
      mix               (file samp in_chan snd chn)
                                      mix file's channel in_chan starting at samp in snd's channel chn.
      mix-amp           (mix chan)    return amplitude of mix's channel chan.
      mix-anchor        (mix)         return anchor position (within the mix) of mix.
      mix-groups        (mix)         return a bit-wise indication of the groups mix is participating in.
                                      That is, group 0 is bit 0, etc.  If mix is in groups 3 and 4, this returns 24.
      mix-length        (mix)         return length in samples of mix.
      mix-position      (mix)         return position (sample number) of mix.
      mix-region        (samp scaler reg snd chn)
                                      Mix in region reg at sample samp (defaulting to the cursor sample),
                                      scaled by scaler (defaults to 1.0) in snd's channel chn.
      mix-speed         (mix)         return speed of mix.
      mix-state         (mix)         return console state of mix (0=open, 1=title bar, 2='M').
      new-sound         (name)        create a new (empty) sound named name.
      normalize-view    ()            normalize Snd display as in View menu Normalize option.
      ok?               (snd)         return #t if snd (an index) is active.
      open-sound        (name)        open name as in File menu Open option.
      open-alternate-sound(name)        close the currently selected file, if any, and opens name.
      orientation-dialog()            fire up the Orientation dialog.
      peaks             (snd chn)     display fft peak information for snd's channel chn (in popup window).
      play              (samp snd chn) play snd's channel chn starting from sample samp.
      play-region       (reg)         play region reg.
      preload-directory (dir)         preload sound files from directory dir (see -p).
      preload-file      (file)        preload file (see View menu's View Files option).
      print             ()            create Postscript description of current display (see eps-file).
      protect-region    (reg protect) protect/unprotect region reg from deletion in the region browser.
      read-only?        (snd)         return #t if snd is read-only, #f otherwise.
      record-dialog     ()            fire up recorder window.
      recorder-gain     (gain)        return recorder input (soundcard-audio) gain gain.
      recorder-in-amp   (in out)      return recorder input channel in to output channel out amplitude.
      recorder-out-amp  (out)         return recorder file output channel out amplitude.
      redo              (edits snd chn) redo edits edits (default is 1) in snd's channel chn.
      region-chans      (reg)         return number of channels in region reg.
      region-dialog     ()            fire up region browser (a no-op if no regions).
      region-length     (reg)         return number of samples (per channel) in region reg.
      region-maxamp     (reg)         return maximum amplitude of region reg.
      region-sample     (samp reg chn) return value of sample samp in region reg in snd's channel chn.
      region-samples    (samp samps reg chn)
                                      return vector of samps samples starting at samp in region reg's channel chn.
      region-srate      (reg)         return original (nominal) sampling rate of region reg.
      regions           ()            return number of regions in the region stack.
      remove-from-menu  (top-menu menu-label)
                                      remove menu menu-label from the top top-level menu whose index is top-menu.
      report-in-minibuffer (msg snd)  post msg in snd's minibuffer.
      reverb-feedback   (snd)         return snd's reverb feedback coefficient.
      reverb-length     (snd)         return reverb delay line length scaler (control panel).
      reverb-lowpass    (snd)         return reverb low pass filter coefficient.
      reverb-scale      (snd)         return reverb amount (control panel).
      reverbing?        (snd)         return #t if snd's reverb button is on.
      revert-sound      (snd)         revert snd to saved state (undo all edits).
      right-sample      (snd chn)     return position (samples) of right edge of time domain waveform.
      sample            (samp snd chn) return value of sample samp in snd's channel chn.
      samples           (samp samps snd chn)
                                      return vector of samps samples starting at samp in snd's channel chn.
      save-sound        (snd)         save snd; same as File menu's Save option.
      save-sound-as     (filename snd) save snd as filename (same as File Save as option).
      save-edit-history (filename snd chn) save current edit list(s) in filename.
                                      If chn is omitted, all snd's channels are saved; if snd is omitted,
                                      all edit list are saved.  If the underlying files are not subsequently
                                      changed, you can load this file to restore the current edit list state.
                                      Returns #t if successful (file opened ok); #f is something went wrong.
      save-envelopes    (filename)    save envelope editor contents in filename.
      save-macros       ()            save keyboard macros in Snd's init file (.snd).
      save-marks        (snd)         save snd's marks, writing a file <name>.marks.
      save-options      (filename)    save options in filename.
      save-region       (reg filename) save region reg in filename.
      save-state        (filename)    save current state of Snd in filename.
      scale-by          (scalers snd chn)
                                      scale amplitude of snd by scalers.  Unlike most of these functions,
                                      scale-by follows the 'sync' buttons and affects all currently sync'd channels.
                                      scalers can be either a float or a vector of floats.  In the latter case,
                                      the values are used one by one, applying each as scale-by moves through the channels.
                                      If 'sync' is off, channel chn is scaled (defaults to the currently selected channel).
      scale-selection-by(scalers)     scale the current selection by scalers which can be either a float, or a vector of floats.
      scale-selection-to(scalers)     normalize the current selection to scalers which can be either a float, or a vector of floats.
      scale-to          (scalers snd chn) normalize snd to scalers.
      select-channel    (chn)         select channel chn.
      select-region     (reg)         select region reg (i.e make it region 0).
      select-sound      (snd)         select sound snd.
      selected-channel  (snd)         return selected channel in snd.
      selected-sound    ()            return selected sound (index).

      ;;	 The notation "(default #t)" below means the default value of the boolean argument
      ;;     is #t; normally the default value of the associated boolean itself is #f.  This
      ;;     means that the command (set-contrasting) turns on contrasting, rather than
      ;;     turning it off (doesn't that make more sense?).

      set-amp           (amp snd)           set snd's amp to amp (control panel).
      set-contrast      (contrast snd)      set snd's contrast amount to contrast (control panel).
      set-contrast-amp  (contrast-amp snd)  set snd's contrast-amp (control panel).
      set-contrasting   (contrasting snd)   set snd's contrast button to contrasting (default #t).
      set-cursor        (samp snd chn)      place snd's channel chn's cursor at samp.
      set-cursor-follows-play (cursor-follows snd)
                                     if #t, the cursor runs alongside the waveform as the sound if played (default #t).
      set-expand        (expand-amount snd) set snd's expansion amount to expand-amount.
      set-expand-hop    (expand-hop snd)    set snd's expand-hop to expand-hop.  This is the amount the
                                     expander moves forward in the output on each segment.  If hop > length,
                                     you get a series of individual (isolated) grains.
      set-expand-length (expand-length snd) set snd's expand-length (segment length) to expand-length.
                                     This is the length (seconds) of each grain.
      set-expand-ramp   (expand-ramp snd)   set snd's expand-ramp (ramp time) to expand-ramp.
      set-expanding     (contrasting snd)   set snd's expand button (default #t).
      set-ffting        (on snd chn)        set snd's channel chn's 'f' button (default #t).
      set-filter-order  (filter-order snd)  set snd's filter-order.
      set-filter-env    (filter-env snd)    set snd's filter frequency response envelope (a list).
      set-filtering     (filtering snd)     set snd's filter button (default #t).
      set-graphing      (on snd chn)        if #t (1), snd's channel chn's displays any lisp-generated
                                     graphics data (see graph-hook and graph).
      set-group-amp     (group chan amp)    set group's channel chan amplitude to amp.
      set-group-beg     (group beg)         set group's begin time to beg (moves all associated mixes).
      set-group-end     (group end)         set group's end time to end (moves all mixes to accomodate).
      set-group-speed   (group speed)       set group's speed to speed.
      set-group-tempo   (group tempo)       set group's tempo to tempo.
      set-just-sounds   (just-sounds)       set just-sounds button in file browser (default #t).
      set-left-sample   (samp snd chn)      set snd's chn's left sample (the window bound) to samp.
      set-mark-name     (mark name snd chn) set mark's name to name (in snd's channel chn).
      set-mark-sample   (mark sample snd chn) set mark's position to sample (in snd's channel chn).
      set-menu-sensitive(top-menu label sensitive)
      set-mix-amp       (mix chan amp)      set mix channel chan's amplitude to amp.
      set-mix-anchor    (mix anchor)        set mix's anchor to anchor.
      set-mix-groups    (mix groups)        set mix's associated groups (bit-wise) to groups.
      set-mix-length    (mix length)        set mix's length (samples) -- this can be dangerous!
      set-mix-position  (mix samp)          set mix's position (begin time in samples).
      set-mix-speed     (mix speed)         set mix's speed.
      set-mix-state     (mix state)         set mix'e title/console display state (0=open, 1=title, 2='M').
      set-read-only     (read-only snd)     set snd's write-protection to be read-only (default #t).
      set-recorder-gain(gain amp)           set recorder's hardware gain gain to amp.
      set-recorder-in-amp(in out amp)       set recorder's input in to output out amp to amp.
      set-recorder-out-amp(out amp)         set recorder's file output channel out to amp.
      set-reverb-feedback(feedback snd)     set snd's reverb feedback coefficient to feedback.
      set-reverb-length(length snd)         set snd's reverb delay line length scaler to length.
      set-reverb-lowpass(lowpass snd)       set snd's lowpass coefficient to lowpass.
      set-reverb-scale(scale snd)           set snd's reverb amount to scale.
      set-reverbing     (on snd)            set snd's reverb button (default #t).
      set-right-sample  (samp snd chn)      set snd's channel chn's right sample position to samp.
      set-sample        (samp value snd chn) set snd's channel chn's sample samp to value.
      set-samples       (samp samps data snd chn) set snd's channel chn's samples satrting from
                                    sample samp for samps samples to the values in data.
                                    (If samp is beyond the end of the file, the file is first zero-padded to reach it).
      set-showing-controls (showing snd)    open or close the control panel (default #t).
      set-speed         (speed snd)         set snd's speed to speed (control panel).
      set-syncing       (syncing snd)       set snd's 'sync' button (default #t).
      set-uniting       (style snd)         set snd's 'unite' button (default channels-combined).
      set-waving        (on snd chn)        set snd's channel chn's 'w' button (default #t).
      set-x-bounds      (x0 x1 snd chn)     set the display window x axis bounds to x0 and x1 (seconds).
      set-y-bounds      (y0 y1 snd chn)     set the display window y axis bounds to y0 and y1.

      short-file-name   (snd)          return the brief (no directory) form of snd's filename.
      showing-controls? (snd)          return #t if snd's control panel is open.
      show-listener     ()             open the lisp listener pane.
      snd-length        (snd chn)      return snd's length (per channel) in samples.
      speed             (snd)          return current speed (control panel).
      srate             (snd)          return snd's sampling rate.
      src               (num-or-env base) sampling rate conversion using 'warped sinc interpolation'.  The
                                       argument num-or-env can be either a number or an envelope.  In
                                       the latter case, base sets the segment base (default is 1.0 = linear).
                                       A value greater than 1.0 causes the sound to be transposed up.
      stop              (snd)          if snd is playing, stop.
      syncing?          (snd)          return #t if snd's 'sync' button is on.
      transform-dialog  ()             fire up the Transform window (Option menu's Transform Options choice).
      transform-sample  (bin slice snd chn)
                                       return the current value of the transform (if any) in bin and (if a
                                       sonogram or spectrogram) slice in snd's channel chn.
      transform-samples (snd chn)
                                       return the transform data currently in snd's channel chn.
      undo              (edits snd chn) undo edits edits (default 1) in snd's channel chn.
      uniting?          (snd)          0 if channels are not superimposed or combined ('unite' button is off).
      update-sound      ()             update the currently selected file.
      update-ffts       ()             cause all fft's to be recalculated.
      update-graphs     ()             cause all graphs to be updated.
      version           ()             return Snd version (a string).
      view              (filename)     open filename read-only.
      waving            (snd chn()     return the state of snd's channel chn's 'w' button.
      x-bounds          (snd chn)      return (x0 . x1) -- current x axis time domain bounds in seconds.
      y-bounds          (snd chn)      return (y0 . y1) -- current y axis bounds.
      yes-or-no-p       (ques)         modal error dialog, returns #t if user clicks "ok", otherwise #f.

      defvar            (var val)      same as (define var val) except that the envelope editor keeps track
                                       of var thereafter and treats lists as envelopes. (defvar is a macro).
      save-defvar       (var-name)     tell the envelope editor that some variable's value has changed
                                       (once the envelope dialog is running it won't otherwise notice these
                                       changes). var-name in this case is the name of the variable (a string).
      load              (file)         load file (containing lisp code -- this is Scheme's load function if Guile is loaded).

#### Sndlib

Some of the underlying sound library (Sndlib) functions are available in lisp (and more could be made available, if they're needed).

      sound-samples (filename)        samples of sound according to header (can be incorrect)
      sound-datum-size (filename)     bytes per sample
      sound-data-location (filename)  location of first sample (bytes)
      sound-chans (filename)          number of channels (samples are interleaved)
      sound-srate (filename)          sampling rate
      sound-header-type (filename)    header type (e.g. aiff-sound-file)
      sound-data-format(filename)     data format (e.g. 16-linear)
      file-length (filename)          true file length (bytes)
      sound-type-specifier (filename) original header type identifier
      sound-type-name (type)          e.g. "AIFF"
      sound-format-name (format)      e.g. "16-bit big endian linear"
      sound-comment (filename)        header comment, if any
      bytes-per-sample (format)       bytes per sample
      audio-error ()                  returns error code indicated by preceding audio call
      audio-error-name(err)           string decription of error code
      set-oss-buffers (num size)      in Linux (OSS) sets the number and size of the OSS "fragments"

### Examples

These examples are simplified to make the exposition cleaner; see examp.scm for more robust versions. The following function computes the rms amplitude of a region:

    (define region-rms
     (lambda (n)
      (let* ((data (region-samples 0 0 n))
    	 (len (length data))
    	 (sum 0.0))
       (do ((i 0 (1+ i))) ((= i len) (sqrt (/ sum len)))
        (set! sum (+ sum (* (vector-ref data i) (vector-ref data i))))))))

To get the data currently displayed in the time domain window:

    (define window-samples
     (lambda ()
      (let ((wl (left-sample))
    	(wr (right-sample)))
       (samples wl (+ 1 (- wr wl))))))

Now we can use window-samples and graph-hook to show a running graph of the time domain energy:

    (define display-energy
     (lambda ()
      (let* ((data (window-samples))
    	 (len (length data)))
       (do ((i 0 (1+ i))) ((= i len))
        (vector-set! data i (* (vector-ref data i) (vector-ref data i))))
       (graph data))))

    (set! graph-hook "(display-energy)")

As the time domain window is moved, the lisp window automatically updates itself. The same thing can show the spectral energy (via transform-samples).

Say we want Snd to refuse to exit if there are unsaved edits.

    (define unsaved-edits?
      (lambda (ind)
        (and (< ind (max-sounds))
    	 (or (and (ok? ind)
                      (> (vector-ref (edits ind) 0) 0)
    	          (report-in-minibuffer "there are unsaved edits")
                      #t)
    	     (unsaved-edits? (+ ind 1))))))

    (set! exit-hook "(begin (report-in-minibuffer \"\") (unsaved-edits? 0))")

Say we are so annoyed by the X/Motif file browser that we want Snd to exit back to the shell if its file argument is not found (this code obviously has to be in the init file):

    (define no-startup-file?
      (lambda (ind)
        (if (= ind (max-sounds))
    	(begin
    	  (write (string-append "can't open " open-hook-filename) (current-error-port))
              (newline (current-error-port))
    	  #t)
          (if (ok? ind)
    	  #f
    	(no-startup-file? (+ ind 1))))))

    (set! start-hook "(if (> (length open-hook-filename) 0)
                          (no-startup-file? 0)
                        #f)")
    ;; open-hook-filename is set whenever Snd tries to open a file
    ;; but we don't want to exit if the invocation has no file.

And just for completeness, here's an example of using the fft-hook. Since fft's in Snd are asynchronous and interruptible, there are times when the function transform-samples returns nil (the fft in question is still in progress, for example).

    (define fft-peak
      (lambda ()
        (let ((samps (transform-samples)))
         (if samps
             (let* ((len (length samps))
    		(mx (vector-ref samps 0))
    		(peak (do ((i 1 (+ i 1))) ((= i len) (/ (* 2 mx) (fft-size)))
    		       (let ((val (abs (vector-ref samps i))))
    			(if (> val mx) (set! mx val))))))
    	  (report-in-minibuffer (number->string peak)))))))

    (set! fft-hook "(fft-peak)")

### Dynamically Loaded C Code

Guile code is pretty fast, but sometimes you need the speed of straight C code. Here's an example of dynamically loading some C code into Guile. First you need to build Snd with -lguile (that is, load it with the guile shared library, not libguile.a); if the loader can't find libguile.so.2 (or whatever), add its directory to your LD_LIBRARY_PATH; for example, if it's on /usr/local/lib, `setenv LD_LIBRARY_PATH /usr/local/lib`. Next compile your code into a shared object (this example is for Linux):

      cc -c cscm.c
      ld -shared -o cscm.so cscm.o -lguile

where we're using the name cscm.c for our C file -- it contents might be:

      #include <math.h>
      #include <stdio.h>
      #include <stdlib.h>
      #include <guile/gh.h>
      int hiho (int a) {return(1+a);}
      SCM hiho_wrapper(SCM a) {return(gh_int2scm(hiho(gh_scm2int(a))));}
      void init_hiho() {gh_new_procedure1_0("hiho",hiho_wrapper);}

Now go to Snd's lisp listener and,

      (define lib (dynamic-link "/home/bil/cl/cscm.so"))
      (dynamic-call "init_hiho" lib)
      (hiho 3)

The function we actually want loaded into Guile here is "hiho". We define a wrapper for it to handle the translation between Guile (Scheme) variable types and C ("hiho_wrapper"), and a procedure to define hiho in Guile ("init_hiho"). Once loaded ("dynamic-link"), we can call the initialization function ("dynamic-call"), and thereafter treat "hiho" as though it had been defined in Guile to begin with.

### Snd resources

There are a few X-style resources that Snd explicity looks for (see Snd.ad):

    initFile       "~/.snd"
    epsFile        "snd.eps"
    overwriteCheck 0
    groups         6
    autoResize     1
    groupOutChans  4
    horizontalPanes 0

    buttonFont     -*-times-medium-r-*-*-14-*-*-*-*-*-iso8859-1
    boldbuttonFont -*-times-bold-r-*-*-14-*-*-*-*-*-iso8859-1
    axisLabelFont  -*-times-medium-r-normal-*-20-*-*-*-*-*-iso8859-1
    axisNumbersFont -*-courier-medium-r-normal-*-14-*-*-*-*-*-iso8859-1
    helpTextFont    9x15
    listenerFont    default

    useSchemes      none
    lightestcolor   ivory1
    basiccolor      ivory2
    darkcolor       ivory3
    darkestcolor    ivory4
    textcolor       lightsteelblue1
    cursorcolor     cyan ! (in Linux: red)
    selectioncolor  ivory4
    mixercolor      lightgreen
    groupcolor      red
    lightbluecolor  aliceblue

If you have the XmHTML widget loaded, the following resources are also available:

    htmlDir                  "."  ! also the variable html-dir
    htmlWidth                600
    htmlHeight               400
    htmlFontSizeList         "14,10,24,24,18,14,12"
    htmlFixedFontSizeList    "14,10"

You can experiment with other choices by using the -xrm command line argument:

      snd -xrm '*Lightestcolor: Red' oboe.snd
      snd -xrm '*AxisNumbersFont: 6x10' oboe.snd
      snd -xrm '*overwriteCheck: 1' oboe.snd
      snd -xrm '*useSchemes: all' -xrm '*scheme: Pacific'
      snd -xrm '*fontList: 9x15' oboe.snd
      snd -xrm '*listenerFont: 6x10' oboe.snd

The color names can be found in /usr/lib/X11/rgb.txt. If you use SGI color schemes, the color resources mentioned above are ignored. If overwriteCheck is 1, Snd asks before overwriting existing files. The AutoResize resource determines how Snd acts when files are added or removed from its overall display. The default (1) causes Snd to expand or contract the main window's size to accomodate the sounds; if autoResize is 0, the outer window size remains the same, and the sounds try to fit as best they can. See also the variable auto-resize. The resource groupOutChans sets the number of output channels in a mixer group. Until the groups are created (upon invoking the mixer), this number grows as needed to reflect the maximum number of channels seen in any file read by Snd. The horizontalPanes resource is equivalent to the -h flag; if 1, sounds are layed out horizontally rather than vertically.

### Planned Enhancements

On my list of things to do: support use of the emacs widget in place of Motif's text widget; integrate Snd much more closely with CLM; enable multiple views of the same file; add escape-to-Snd applets to this document; make separate sounds superimposable; add mark-oriented annotations; add user-defined controls to the control panel; add log scales to the envelope editor; finish the autoconf junk; add more compression translators; support the new X/Motif printer widget; add fft-filtering; include the mix/group console state in the save-state mechanism.

## Index

Index
Action | Menu | Keyboard | Lisp | Other
--- | --- | --- | --- | ---
abort command |  | Cg |  | mouse click
amp env | Edit: Edit Env | Cx Ca, Cx a | env | scale-to, scale-by
axis bounds |  | Cx Cb, Cx Cp | [xy]-bounds | -s switch to Snd
axis fits data |  |  | fit-data-on-open |
brighten file |  |  |  | see 'contrast' control
center cursor |  | Cl, Cv |  |
center selection |  | Cx l |  |
center tiny signal |  |  |  |
change key binding |  |  | global-set-key |
change pitch |  |  |  | see 'speed' control
change samples |  | Cz, Cx Cz | set-samples |
change srate | Edit: Edit Env |  | src | see 'speed' control
change tempo |  |  | set-expand | see 'expand' control
close file | File: Close | Cx k | close-sound |
color | View: Color |  | color-dialog | color-scale,color-cutoff
combine channels | View: Channel style |  | channel-style |
compare files |  |  |  |
continue session | Options: Session |  | load | -l switch to Snd
control panel | View: Show controls | Cx Co, Cx Cc | set-showing-controls | drag pane sash
count matches |  |  |  |
create new file | File: New |  | new-sound |
cut selection | Edit: Cut | Cw | cut |
define mark |  | Cx /, Cx Cm | add-mark | also Cm
define selection |  | C[space], Cx c | make-region | mouse drag
delete mark |  | - Cm | delete-mark |
delete samples | Edit: Cut | Cd, Ck | delete-samples |
describe file | Popup: Info |  |  | Edit: Edit Header
describe sample | View: Verbose cursor | Ci | set-verbose-cursor |
dots or lines | View: Dots |  | graph-style | dot-size: numberpad '.', '0'
edit env | Edit: Edit Env |  | enved-dialog |
edit header | Edit: Edit Header |  | edit-header-dialog |
evaluate expression |  | Cx Cx, Cx Cn |  | over region: Cx x, Cx n
examine selections | View: Regions |  | region-dialog |
exit Snd | File: Exit |  | exit | mwm menu: close or exit
extend file |  | Co |  |
extract channel |  | Cx Cw |  |
fft in dB | Options: Transform |  | fft-log-magnitude |
fft log freq | Options: Transform |  | fft-log-frequency |
fft normalization | Options: Transform |  | normalize-fft |
fft peaks | Options: Transform |  | show-fft-peaks | M-x peaks for full info
fft size | Options: Transform |  | fft-size | fft-size: numberpad: '*', '/'
fft window | Options: Transform |  | fft-window |
fft window parameter | Options: Transform |  | fft-beta |
fft/sono/spectrogram | Options: Transform |  | fft-style |
file formats | File: Save as |  | raw-format | defaultOutputType
file lists | View: Files |  | file-dialog |
filter | Edit: Edit Env |  | filter-env | see filter controls
find | Edit: Find | Cs or Cr |  |
horizontal panes |  |  |  | -h switch to Snd
insert file |  | Cx Ci | insert-sound |
insert selection | Edit: Paste | Cy or Cx i | insert-region |
insert zeros |  | Co, Cz | insert-samples |
interrupt Snd |  | Cg | stop | edit env
keyboard macros |  | C(, Cx e | key |
load session | Options: Session |  | load |
max amp |  |  | maxamp |
mix file | File: Mix | Cx Cq | mix |
mix selection | Edit: Mix | Cx q | mix-region |
move cursor ahead |  | Cf, Cn, Ce | forward-sample | also >
move cursor back |  | Cb, Cp, Ca | backward-sample | also <
move mixed file |  |  | set-mix-position | see mix doc
move to mark |  | Cj, Cx j | forward-mark | Cx j -> named mark
move to mix |  | Cx Cj | forward-mix |
move window ahead |  | [Left], Cx f | set-right-sample | scroll bars
move window back |  | [Right], Cx b | set-left-sample | scroll bars
multichannel ops |  |  | syncing | sync button
normalize display | View: Normalize |  | normalize-view | Popup: Normalize
numeric arguments |  | Cu | prefix-arg | see marks as args
open file | File: Open | Cx Cf | open-sound | Files dialog: click file
open file read-only | File: View |  | view-sound |
orientation | View: Orientation |  | orientation-dialog |
overwrite check |  |  | ask-before-overwrite | overwriteCheck
play channel |  | Cq, Ct | play |
play file | Popup: Play |  | play, stop | File or main window: 'play'
play selection | Edit: Play | Cx p | play-region |
preload directory |  |  | preload-directory | -p switch to Snd
print file | File: Print | Cx Cd | print | epsFile resource
record sound | File: Record |  |  |
redo edit | Edit: Redo | Cx Cr | redo | Popup: Redo
reverberate file |  |  |  | see 'reverb' controls
revert file | File: Revert |  | revert-sound |
save channel |  | Cx Cw |  |
save control state |  |  | control-panel-save | 'save' button
save file | File: Save | Cx Cs | save-sound | Popup: Save
save file as | File: Save as |  | save-sound-as | see also overwriteCheck
save macros |  |  | save-macros |
save marks |  |  | save-marks | also session
save options | Options: Save options |  | save-options |
save selection | Edit: Save selection | Cx w | save-region |
save session | Options: Session |  | save-state |
save state | Options: Session |  | save-state | save-state-on-exit
select sound |  | Cx o | select-sound | File dialog: click file
show edit list | Edit: Show edit history |  | show-edit-history |
show freq domain |  |  | ffting | 'f' button
show marks | View: Show marks |  | set-show-marks |
show time domain |  |  | waving | 'w' button
smooth samples |  | Cx Cz |  |
smooth selection |  | Cx z |  |
sonogram | Options: Transform |  | fft-style | spectro-color,spectro-cutoff
spectrogram | Options: Transform |  | fft-style | orientation, scaling
speed units | Options: Speed style |  | speed-style | speed-tones
subsampling | Options: Subsampling |  | set-subsampling |
temp directory |  | Cx d | temp-dir | TMPDIR or /var/tmp
undo edit | Edit: Undo | C_ or Cx Cu | undo | Popup: Undo
update file | File: Update | [Home] | update |
view envs | Edit: Edit Env |  | enved-dialog |
wavelets | Options: Transform |  | wavelet-type |
wavogram |  |  | wavo | wavo-trace, wavo-hop
X axis units | View: X axis units |  | x-axis-style |
y=0 line | View: Show y=0 |  | set-show-y-zero |
zoom focus | Options: Zoom style |  | set-zoom-focus-style |
zoom window |  | [Up],[Down] | set-x-bounds | control keys intensify