======================
IMP3SH advanced README
======================

This file attempts to cover some of the more advanced features of imp3sh. The
CHANGES file also contains details about some of imp3sh's more advanced
features, although it is not organized very well :)

If you haven't read the 'README' or 'README.playlists' files, you should 
probably do so before reading this one.

-----------------
Table O' Contents
-----------------

These are in no particular order:

1)  Job control
2)  Buffering
3)  Aliasing
4)  External players
5)  Event system
6)  Tag editing  
7)  Equalizer 
8)  Audio drivers

   -----------
1) Job control
   -----------

imp3sh has bash-style job control. You can launch programs that use the
console, and you can launch programs in the background (i.e., with an '&')

You can stop programs that control the console with 'CTRL-Z', and the modify
their job state with the 'fg' (foreground) and 'bg' (background) commands.

imp3sh will buffer all output from a process if it is launched in the
background or if it is launched by an event when the console is occupied by
another process or imp3sh's own output buffer.

The output from stdout and stderr is stored until the process terminates, in
which the process's output is flushed to imp3sh's console buffer.

Alternatively, the user can flush the process' buffer by using the 'fjob' 
command. 'fjob <job_number>' will dump the current contents of the 
process buffer for <job_number> to the screen. Current jobs are displayed
by using the 'jobs' command, which was also shows status info about the
job buffers.

The user can bring the buffered process back to the foreground by using
the 'fg' command, however, the process will not be able to recieve input 
from stdin (break [Ctrl-C] and stop [Ctrl-Z] should still work, though.) 

If a process is started in the foreground (no '&') and then stopped (Ctrl-Z),
it can still be sent to the background ('bg') or foreground ('fg') while 
properly transfering control of stdin.

I added job-buffering  because sometimes I am using an app on the console
and I forget that I have events waiting to execute. This way, any event can
run and all the output will be stored for me to look at later.

The job buffers are circular with a maximum of 256 entries of (upto) 8192
bytes each. Each entry allocated as needed.

   ---------
2) Buffering
   ---------

All of imp3sh's internal commands are buffered via the built-in 'Mess' buffer
(The name 'Mess' was inspired from the standard unix commands 'more' and
'less'.)

If you use a built-in command whose output would take more than one screenful,
you will see the following prompt at the bottom of the screen:

	--Mess--(5%)--['\n','q','b','any']--

The percentage refers to how much of the buffered output has been displayed. At
this point, you have four options:

	1) Press 'q' to exit out of the 'Mess' buffer.
	2) Press '\n' (return) to scroll one line down
	3) Press 'b' to scroll one screen backwards, or
	4) Press any other key to scroll one screen forward.

To keeps things pretty, the output buffer will chop any entry that is longer
than the current console width, adding the string "...". If you would like to
see the entire line, you can always resize the terminal window.

The output buffer initially has enough room to store (2048+256) lines of text
(that is the default list size plus 256.) However, if you resize the playlist,
imp3sh will always resize the 'Mess' buffer so it can store at least 256 more
lines than the current playlist size.

imp3sh also has a console-buffer. imp3sh output and messages will be buffered
if the console is in use by another app or imp3sh's own output buffer. The 
buffered console messages are displayed at the next earliest convenience
(simliar to bash.) Output from buffered jobs is also flushed to the console 
buffer (see the Job Control section above.)

All of imp3sh's buffers (including playlists) use a common buffer structure
that tries to get both worlds of efficiency and speed. Initially, all buffers
are empty (no memory allocated except for the node arrays.) When a buffer
recieves a request for an entry for this first time, it will allocate the 
required memory. Every consecutive time that specific entry is used, imp3sh 
will not re-allocate memory unless the newly requested entry is too large.

After an entry has been used once or twice, the chances of imp3sh having to
resize the entry become very slim. So, after the first few times you use the
'Mess' buffer (for example), imp3sh will most likely not have to use many 
(if any) realloc() calls, thus increasing performance. At the same time,
imp3sh does not need to grab a huge, static amount of memory for each 
buffer upon startup.

Clearing a buffer also becomes very quick (simply setting one integer to zero,
no memory is actually freed.)

Sorting is done directly on the buffer entry lists with customized
comparison routines. The result is the ability to sort a playlist with 10,000
entries in 1 second on a Duron 600 (this also includes the overhead of
determining what information to sort (per entry) by looking at the current
list view.)

   --------
3) Aliasing
   --------
 
imp3sh can use aliases for commands or groups of commands. The 'alias' and 
'unalias' commands allow you to manipulate the alias list.

For example, to see colors with the 'ls' command:

	alias ls ls --color=tty

Multiple commands can be aliased to a single command using semicolons. For
example, here is an aliased command that will update your "classical" list:

  alias update editlist classical;delindex *;addiR ~/music/classical/

Notice that the 'alias' command is treated differently with respect to 
semicolons. Normally, the commands seperated by semicolons would all be 
executed immediately. In the above example, however, everything after "update"
is treated as the alias. The 'addevent' command also behaves like this. Because
of their special behavior, the 'alias' and 'addevent' commands cannot be
aliased themselves.

Use 'alias' without any arguments to see the current alias list. 

Use 'unalias' with the name of an alias to remove that alias.

   ----------------
4) External players
   ----------------

imp3sh can use other, command-line players (like 'mikmod', or 'timidity') to
play different file formats. Volume controls, the equalizer, muting, seeking,
and time-stamped prompts are not available when using external players. Use
'addplayer' and 'printplayers' to add/view external players.
 
A '-q' option to 'addplayer' will suppress any console output from the
external player. A '-b' option (instead of '-q'), will buffer all of the
output from the external player. The buffered output is viewable via the
'fjob' command.

When using 'addir' or 'addiR', imp3sh will also add file-types that are 
supported by any external players. These filetypes are defined as an 
argument to the 'addplayer' command (see the 'EXTERNAL.players' file for
examples.)

   ------------
5) Event system
   ------------

imp3sh has an event system that will store commands to be executed at a
specific time, interval of time, or when specific things happen. Here is the 
built-in help as of version 0.2.1a:

:-| Add event-------------> addevent ['-q'] ['-p'] <type_options...> <command>
:-> Use '-p' to make event persistent (repeating)
:-> Use '-q' to disable event alerts (quiet)
:-> For <type_options...>, use one of the following:
	1) -t <seconds>           : TMD (timed) event
	2) -l ('*' | <list_name>) : EOL (end of list) event
	3) -q                     : EOQ (end of queue) event
	4) -s ('*' | <filetype>)  : EOS (end of stream) event
	5) -r ('*' | <filetype>)  : SOS (start of stream) event
	6) -e                     : EXT (exit) event
:-> For <command>, enter command(s) as you would by themselves


Timed events have a one second resolution.

EOL events can only occur in Once, Repeat, and SmartRandom playmodes.

A <file_type> can be given for EOS and SOS events. This string will be matched
against the _end_ of a filename/URL. For example, 

	addevent -p -s .MP3 echo "Hello"

will create an event that prints "Hello" to the console every time a file 
whose last four bytes (length of ".MP3") match ".MP3". 

Please contact me @ kman_can@yahoo.com if you have questions regarding the
event system.

   -----------
6) Tag editing
   -----------

imp3sh can read/write id3 tags from MP3 files.

imp3sh also has the ability to read/write fixed-location string identifiers
from files. Any file type that has an identifier (i.e., song title) in a fixed
location can be supported. Current supported formats are:

	.XM .ULT .STX .S3M .MTM .MOD .M15 .IT .IMF .GDM .FAR .DSM .AMF .669

The 'addiX' commands will attempt to read tag information from files if the
file is determined to be one of the above types.

The 'printtag' command takes a filename or a master-list index and tries to
find any tag information for that file. imp3sh will display the tag info if
it knows how to find it and if it exists in that file.

The 'addtag' command can be used to add/modify the tag information of MP3s and
any other supported fixed-location formats. 'addtag' takes a filename or a
master-list index and file-type-dependant options. The id3 tag options are:

:-| Add/Modify tag info---> addtag (<master_index> | <file_name>) <options>...
ID3 options are:
	-n <name>       : Add/Modify song name
	-a <artist>     : Add/Modify artist name
	-l <album>      : Add/Modify album name
	-y <year>       : Add/Modify year
	-o <note>       : Add/Modify note
	-s <style>      : Add/Modify style
	Year = MAX 4 chars, all other = MAX 30 chars
	ALWAYS double-quote multiple-word entries

You can display/search-through all of the pre-defined id3 style types with the
'printstyles' command. The style option of 'addtag' must be given a style from
this list.

To edit the album, artist, and style  id3 fields of master-list index 14:

	>addtag 14 -a "Nine inch nails" -l "Pretty Hate Machine" -s Industrial

To edit file types with fixed location identifiers, just give the new tag after
specifying the filename or master-list index:

	>addtag /home/ekratzer/moonflowers.xm "Humanoid - Moonflowers"

If imp3sh has tag location information for ".XM" filetypes,  it will make the
change for you. If the tag you entered is too long, imp3sh will warn you and
give you the maximum tag length for that file type.

If you want to add tag-reading abilities for more filetypes, email me the
byte offset, byte length, and format of the identifier for the new filetype and
I will incorporate it.

   ---------
7) Equalizer
   ---------

imp3sh has a 10 band equalizer. Xaudio's 64-band (32 x 2 channels) equalizer 
has been mapped down to one 10-band equalizer. The equalizer only works with
the Xaudio decoder (external players are not mapped throught the equalizer.)
Type 'help eq' to see the equalizer control commands.

Valid vaules for the bands are between -128 and 127.

Equalizer commands:

  'eqprint' - Print the 10 bands and their values

  'eqsetband' - Set a particular band or group of bands. Examples:

	>eqsetband 0 30   # Set band 0 to 30
	>eqsetband * 5    # Set all bands to 5
	>eqsetband 0,1,2,3,7,8,9, 20,15,5,0,5,15,20 # Set bands 0,1,2,3,7,8 and
						      9 to 20,15,5,0,5,15 and
						      20, respectively.

  'eqenable' - enable the equalizer

  'eqdisable' - disable the equalizer

Note: an eqsetband command will enable the equalizer if it is not already
      enabled.

Note: I have found that using larger values for the bands easily produces
      distorted output. I would not recommend using anything over 30 for
      any band.

A message is displayed showing the state of the equalizer when you use the
'status' command.

I do not know what actual frequencies the bands cover (It does not seem to be
documented anywhere.) I can guess however. There are 32 bands. I imagine these
bands equally cover the audible frequency range (20 - 20000 Hz.)

The 32 bands are mapped to imp3sh's 10 bands like this:

	Band 0 == xaudio band 0
	Band 1 == xaudio band 1
	Band 2 == xaudio band 2
	Band 3 == xaudio band 3
	Band 4 == xaudio band 4
	Band 5 == xaudio band 5
	Band 6 == xaudio bands 6-7
	Band 7 == xaudio bands 8-11
	Band 8 == xaudio bands 12-19
	Band 9 == xaudio bands 20-31

The mapping was done this way because the lower (bass) bands have alot more
effect when attenuated.

   -------------
8) Audio drivers
   -------------

imp3sh can specify whether your audio driver can support multiple
controlling processes with the command 'audioprocs'. If your audio driver
can support multiple controlling processes, then you should use this 
command. The only benefit from this feature is that volume and balance
controls will be available when an external player is running.

Be careful! If you enable this feature and your audio driver does not 
support multiple controlling processes, then all your external players will
not work, and you might might witness other, crazy behavior!

When you use the 'status' command, a message is displayed showing the
state of this feature.

I use a soundblaster live (which supports multiple processes) at home, and 
a soundblaster 16 (which doesn't support multiple processes) at work.

