Sophie

Sophie

distrib > Mandriva > 2007.0 > i586 > media > contrib-release > by-pkgid > 89228aea590c2d84ee0ccfd7ca15ce1a > files > 7

smurf-0.52.6-7mdk.i586.rpm

****** WARNING *******
A lot of this stuff will be out dated, while Smurf undergoes major
changes. Most of the low level sound font functions will be moved to an
external libsoundfont library, and many changes relating to sound font
item access, etc.
	Josh Green
	April 13, 2001
****** WARNING *******

So you want to try to add something.. Fix something.. Figure out something
with the Smurf source code ehh?? Perhaps this document will help you. I
welcome any questions or suggestions relating to the Smurf Sound Font
Editor, so don't hesitate to send me an email.

Other helpful documentation:
----------------

GTK Tutorial
GTK Reference Manual
GLib Reference Manual

These documents can be found at http://www.gtk.org

GLib is heavily used in the Smurf Sound Font Editor and GTK itself uses
it. GLib defines many simple data types like linked lists, hashes,
dynamic arrays and strings etc.; and has routines for effecient memory
management, portability functions and many other nice things. In
short.. It kicks ass. Generally speaking any data type starting with a 'G'
that isn't 'Gtk' is probably from GLib. Don't confuse glib (nice utility
library) to glibc (essential libraries, the heart of Linux programs).


Source file descriptions
----------------

Lets start off by listing all the source files and what they contain. All
permanent source or header files contain a description (at the beginning 
of the file) of what should be found inside it.

src/
----------------
glade_callbacks.c	Currently empty, just to make Glade happy
glade_interface.c	Auto generated by glade, not to be changed directly
midi.c			External MIDI input
sample.c		Audio file and sample related routines
sequencer.c		Sequencer output routines
sfdofunc.c		Undo/Redo item specific functions
sfdump.c		Sound font dump to text file routines (for debugging)
sfload.c		Sound font file loading
sfont.c			Sound font data manipulation
sfsave.c		Sound font file saving
sfundo.c		Undo/Redo system
smurf.c			main() which starts everything
smurfcfg.c		Configuration file routines
splash.c		Intro splash image routines
splash_png.c		Auto generated by tools/cdump of pixmaps/splash.png
uif_help.c		Tips, about, and help (when it becomes available)
uif_menutbar.c		Menu and tool bar
uif_piano.c		Virtual piano keyboard
uif_pianospan.c		Note/Velocity ranges below piano
uif_pref.c		Preferences
uif_sample.c		Sample related user interface routines
uif_samview.c		Sample viewer user interface
uif_selections.c	Operations on multiple sound font items
uif_sfgen.c		Sound font generator user interface (effects)
uif_sfont.c		User interface related sound font routines
uif_sftree.c		Sound font tree
uif_sfundo.c		Undo/Redo user interface
uif_treemenu.c		Right click tree menus
uif_wavegen.c		Sample waveform generator
uiface.c		main user interface routines (ties it all together)
util.c			error handling and other utility functions
wavetable.c		wavetable (patch loading) routines


src/drivers
----------------
midi_alsaraw.c		ALSA external raw MIDI thru driver
midi_alsaseq.c		ALSA sequencer based MIDI thru driver
midi_oss.c		OSS MIDI thru
seq_alsa.c		ALSA sequencer routines
seq_oss.c		OSS sequencer routines
wtbl_awe.c		OSS AWE wavetable routines
wtbl_awefx.c		OSS AWE effects routines
wtbl_awepatch.c		OSS AWE patch loading routines
wtbl_aweunits.c		SF->AWE unit conversion routines
wtbl_gus.c		OSS GUS driver (yeah right, should just kill it)
wtbl_guspatch.c		Patch loading (stupid single sample loading)


src/widgets
----------------
keyspan.c		Note/velocity range widget
piano.c			Piano widget
popdog.c		Pop up dialog convenience widget (is it really?)
ptrstrip.c		Pointers on a strip widget
samview.c		Sample viewer widget


NOTE: If there is a file I didn't list there that you think should be,
its probably new and I just forgot to add it to here.


Definitions and terms
----------------
Here is a list of terms I will use throughout this document and a
description of what each means. I'm only going to list terms that are
unique to Smurf or my own terminology.. etc. I'm not going to describe
sound fonts, this info can be found in other documents. I've written
an un-official "Intro to sound fonts" which is on the Smurf web site
(http://smurf.sourceforge.net). You can find more in-depth application
level information in the SoundFont specification which can be found in
PostScript or perhaps PDF format if you can find it. Try
www.soundfont.com or ftp.creaf.com for the official SoundFont
specification.

sound font item		A preset, instrument, sample, preset zone or
			instrument zone
sound font tree		The Smurf GUI sound font tree


Lower level sound font representation - sfont.[ch], uif_sfont.[ch]
----------------
You may want to try to understand how sound fonts are represented
internally in the Smurf Sound Font Editor. I'll attempt to describe that
here.

uisf_sfonts (Linked list)
|
|-[+] (UISFont *) untitled SF 1
|
|-[-] (UISFont *) untitled SF 2
|  |
|  |-- (SFTreeNodes *) nodes (pointers to nodes in the GUI tree)
|  |
|  *-[-] (SFData *) sf
|     |
|     |-- preset (linked list of SFPresets)
|     |-- inst (linked list of SFInsts)
|     *-- sample (linked list of SFSamples)
|
*-[+] (UISFont *) untitled SF 3

SFPreset (SFInst is the same except for extra preset related info)
|-- Name, prenum, bank, etc.
*-- zone (linked list of SFZones)

SFZone (structure)
|-- instsamp (pointer to an instrument or sample)
|-- gen (linked list of generators, effects)
*-- mod (linked list of moderators, MIDI controls modulating effects)


Most of the low level sound font manipulation occurs in sfont.c with
uif_sfont.c being the user interface (GUI) routines.

uisf_sfonts is a linked list of the currently open sound fonts. Each
pointer in this list points to a UISFont structure which essentially
combines the non-GUI SFData structure with SFTreeNodes.

SFTreeNodes is a structure with pointers to nodes in the GTK sound
font CTree widget of the top level branches for that sound
font. Fields: sfont (sfont root node), preset (preset root node),
melodic (preset melodic branch) etc.


Unique sound font item identifiers (not pointers!) - uif_sftree.[ch]
----------------
When dealing with user selections of sound font items and undo/redo
functionality, it becomes necessary to have a unique identifier for each
item. This identifier should not be dependant on a memory location (a
pointer for instance).

Why not pointers you ask? Example scenario when using pointers (skip
if you're in a hurry :)

<scenario>
The user pops a preset rename dialog and gets distracted with
something else. The dialog gets hidden by some other app and the user
forgets all about it. Later when she comes back to editing the sound
font, she decides to destroy that particular preset. All is well
right? Well yes, until she finds that rename dialog again. Not really
thinking about it she just says okay. Smurf seg faults :( Passing
around non-static pointer references in a GUI environment is not a
good idea. The rename dialog used a pointer to a preset that no longer
exists.
</scenario>

Rather than making all dialogs "modal" (all other user interface
functions are frozen until dialog closes) a unique integer is used to
identify each item and a lookup is done to get the pointer to the
data. NULL is returned if a non-existing ID is looked up, allowing
Smurf to handle the situation, instead of crash (most often the item
is just skipped silently).

A GLib "keyed data list" is used to map a unique integer ID to a
pointer to the item data. Each item is assigned a unique ID when it is
added to the sound font tree. This key is removed when the item is
destroyed.

The data type used for the unique integer ID is called a GQuark.


Sound font tree - uif_sftree.[ch]
----------------
The pointer obtained from a GQuark lookup in the sound font item keyed
data list, is a pointer to a GtkCTreeNode in the sound font tree.
A pointer can be stored in each GtkCTreeNode in a CTree.

/* each node in the tree points to one of these */
typedef struct _SFTreeRef
{
  SFNodeType type;		/* the type of node */
  GQuark quarkid;		/* sound font item keyed data list ID */
  gpointer dptr;		/* pointer to data associated with this type */
}
SFTreeRef;

This structure contains a type enum which describes the item's type
(NODE_SFONT, NODE_PRESET, etc), the node's quarkid (the same ID we started
with, so we can get the GQuark id given a GtkCTreeNode *), pointer to data
associated with this node.

'dptr' in SFTreeRef points to different types of data, depending on the 'type'.
Here is what it will point to for different types of nodes:

type		| dptr data type
----------------------------------------
NODE_SFONT	| UISFont *dptr (UISFont struct associated with the sound font)
NODE_PRESET	| GList *dptr->data = SFPreset *
NODE_INST	| GList *dptr->data = SFInst *
NODE_SAMPLE	| GList *dptr->data = SFSample *
NODE_PZONE	| GList *dptr->data = SFZone *
NODE_IZONE	| GList *dptr->data = SFZone *
others		| NULL

Notice that for most item types dptr points to a GList item. These are the same
GLists that are referenced by the SFData structure (described above).

This system essentially binds the GUI related variables (GtkCTreeNode *) and the
lower level SFData, SFPreset, SFInst, etc structures.

Here is an example routine that expects a GQuark sfitem identifier and
closes the sound font that owns the sfitem. We'll use some of the macros
defined in uif_sftree.h to help us.

void
example_close_function (GQuark sfquark)
{
  UISFont *uisf;
  GtkCTreeNode *node;
  SFTreeRef *ref;

  /* look up the quark in the sftree_items keyed data list */
  node = SFTREE_LOOKUP_QUARK (sfquark);

  /* node would equal NULL if item doesn't exist anymore */
  if (!node) return;

  /*
     we now have the (GtkCTreeNode *) which references a node in the GUI sound
     font CTree
  */

  /*
     find this node's root sound font node (type = NODE_SFONT) and fetch the
     UISFont structure from it
  */
  uisf = SFTREE_UPFIND_UISF (node);

  /* close the sound font, sfont_close expects (SFData *) */
  sfont_close (uisf->sf);
}


Smurf undo system
----------------

Smurf has a rather flexible undo system. The undo system is based on a
tree rather than queue or list. This means that, from the user point
of view, multiple changes can be easily tested. Performing an action,
undoing it, then performing another action would cause the state
information for the first action to be destroyed when using a
traditional undo LIST. But with a TREE, another branch is started
instead.

sfundo.c contains the undo system functions.
sfdofunc.c contains the functions for saving/restoring the state of specific
actions.

The word "do" is used to signify things having to do with both
undo/redo stuff.  The tree is based on the GNode glib data type, which
defines a data type and functions for manipulating N-ary trees (a tree
with arbitrary # of branches).

SFDoTree sfdo_tree (structure)
|-- GNode *root (dummy root node of tree, root->data = NULL)
|-- GNode *curpos (current position in undo history)
*-- GList *groups (list of currently active groups and sub groups)

GNode *example_item (an example of an item in the sfdo_tree)
|-- GNode *next, *prev (point to next and previous siblings, i.e. branches)
|-- GNode *parent (parent of this node, NULL for root node)
|-- GNode *children (first child or NULL if last node of this branch)
*-- SFDoEntry *data (actually a gpointer which is equiv to a void *)
  |-- gchar *descr (description of this action)
  *-- GList *items (multiple do items "grouped" by this SFDoEntry)
    |-<list>
    |-[-] SFDoItem *
    |  |-- guint16 type
    |  *-- gpointer state
    *-[+] SFDoItem *

A "do" tree consists of a tree of SFDoEntries which are linked lists
of SFDoItems. The SFDoEntries are groups of SFDoItems essentially and
many operations act on them as a group.  Each SFDoItem has an
enumerated type (generator, sample, sampledata, preset, etc) and a
pointer to the associated "state" data which can be used to restore
the state of that type of object.  Only a new entry (curpos) can be
used for grouping. Groups can be nested.  The same SFDoEntry is used
for nested groups. A list of SFDoItems is kept in the tree, each is a
pointer to the last node of the previous group. This list is temporary
and exists only while the entry is opened as a group.  Therefore sub
groups are only available while they are open.  Sub groups are useful
for operations that call apon other functions that act on many items
and group them. Should one of these functions fail, it would undo its
own group of changes, and return FAIL. The calling routine could then
undo all the other group data.


Bye bye now
------------------
Okay, so that was some info about the Smurf Sound Font Editor source code.
I'm sure there are a lot of other things that would be helpful to put in here,
but I don't want to do it right now. If there is something that you can't figure
out, let me know. Perhaps I'll add it to this document.

Happy hacking..
	Josh Green <jgreen@users.sourceforge.net>