Game_Music_Emu 0.2.7 Notes
--------------------------

Overview
--------
This library is composed of several independent game music emulators
derived from the common Music_Emu interface. Each emulator can load a
game music file and play from any track. To play a game music file, do
the following:

- Determine file's type
- Create appropriate emulator
- Set sample rate
- Load file into emulator
- Start desired track
- When samples are needed, call play()
- When done, delete emulator

See Music_Emu.h for reference.


Information Fields
------------------
Game music files include text fields with information about the game and
track. These are stored in the file's header or in an embedded block.
Text fields in most game music formats do *not* have a nul terminator if
the string completely fills the field. The simplest way to handle this
is to copy the string out and manually add a nul terminator at the end.

This library is currently focused only on actual emulation, so it
doesn't provide a common interface to the different schemes each game
music file format uses. Refer to the file's official specification for
further information.


Modular Construction
--------------------
The library is made of many fairly independent modules. If you're using
only one music file emulator, you can eliminate many of the library
sources from your program. Refer to the files list in readme.txt to get
a general idea of what can be removed. Contact me if you'd like me to
put together a smaller version for a particular use, as this only takes
me a few minutes to do.

If you want to use the sound chip emulators in your emulator, first
check my libraries page since I have released several of them as
standalone libraries and included documentation and examples on their
use:

	http://www.slack.net/~ant/libs/

The "classic" sound chips use my Blip_Buffer library, which greatly
simplifies their implementation and efficiently handles band-limited
synthesis. It is also available as a standalone library with
documentation and many examples.


Frequency equalization
----------------------
Some emulators allow frequency equalization to be adjusted;
Music_Emu::equalizer_t( treble, cutoff, bass ) specifies low-pass and
high-pass filtering.

Low-pass is an exponential rolloff beginning at 'cutoff' Hz and
attenuating by 'treble' dB at 22kHz. For example, with cutoff = 8000 Hz
and treble = -6 dB, the following results:

        cutoff = 8kHz
  0dB -------*__                
	            ~~--__ treble = -6dB
	                  ~~-*__
	                        ~~--__
	                              ~~--__
	                                    ~~--__
-18dB - - - - - - - - - - - - - - - - - - - - - -
	  0      8kHz      22kHz               44kHz ...

High-pass is a steep rolloff which passes -3dB attenuation at
'breakpoint' Hz, where useful frequencies range from 0 to 6000 Hz.  For
example, with breakpoint = 1000 Hz, the following results:

      breakpoint = 1000 Hz
 0dB                 ___________
-3dB      ,_*---~~~~~       
        _~
       /
	  /
      |
      |
-21dB - - - - - - - - - - - - -
	  0   1000 Hz            4000 Hz

Each emulator defaults to a profile that approximates its particular
console's sound quality; this default can be determined by getting the
current equalization just after creating the emulator.


Output sample rate
------------------
All the emulators use internal band-limiting, so there is no reason to
use a sample rate above 48kHz unless the sound hardware demands it;
44-48kHz will yield the best results. You could use the following code
to choose a rate that is both near this range and an integral division
of the native rate:

	long adjust_rate( double native )
	{
		for ( double divider = 1; divider <= 4; divider++ )
		{
			long adjusted = native / divider + 0.5;
			if ( adjusted <= 56000 )
				return adjusted;
		}
		return 44100; // give up; CD rate probably works well enough
	}


Misc
----
Big thanks to Chris Moeller (kode54) for his help with library testing
and feedback, for maintaining the Foobar2000 plugin foo_gep based on it,
and for his original work on openspc++ that was used when developing
Spc_Emu. Brad Martin's excellent OpenSPC SNES DSP emulator worked well
from the start. Also thanks to Mahendra Tallur, Shazz, and Richard
Bannister for testing and using the library in their game music players.

For a full example of using Game_Music_Emu see the source code for Game
Music Box, a full-featured Mac OS game music player:

	http://www.slack.net/~ant/game-music-box/dev.html


Solving Problems
----------------
If you're having problems, check the following:

- If multiple threads are being used, ensure that only one at a time is
accessing objects from the library. This library is not thread-safe.

- Turn the compiler's optimizer is off. Sometimes an optimizer generates
bad code.

- Enable debugging support. This enables assertions and other run-time
checks.

- See if the demo works. If not, contact me.


Error handling
--------------
Functions which can fail have a return type of blargg_err_t, which is a
pointer to an error string (const char*). If the function is successful
it returns blargg_success (NULL), otherwise it returns a pointer to an
error string.

To allow compatibility with older C++ compilers, no exceptions are
thrown by any of the modules. The library is exception-safe, and any
exceptions which occur are not intercepted. Any exceptions thrown by the
standard library or caller-supplied functions are not caught.

The library uses BLARGG_NEW instead of new for allocations. By default,
BLARGG_NEW is #defined to plain new, so if your compiler has exceptions
enabled, failed allocations will result in an exception rather than an
error string. This can be overriden in your config.h file (see below).

Significant violations of the documented interface are flagged with
debug-only assertions. Failure of these usually indicates a caller error
rather than a defect in the library.


Configuration
-------------
The header "blargg_common.h" is used to establish a common environment,
and is #included at the beginning of all library headers and sources. It
attempts to automatically determine the features of the environment, but
might need help.

If HAVE_CONFIG_H is defined in the compiler options, the file "config.h"
is included at the beginning of each library header file, allowing
configuration options for the library to be set. It's fine if other
libraries also use this scheme, as they won't conflict.

I have attempted to design the library so that configuration can be done
*without* modifying any of the library sources and header files. This
makes it easy to upgrade to a new version without losing any
customizations to its configuration.

Some parts of the library might depend on the order of bytes in
multibyte types. If so, they will cause a compilation error if the order
can't be determined (rather than silently fail). If this occurs, define
the appropriate symbol. For big-endian (most significant byte first,
i.e. Motorola 68000, PowerPC), #define BLARGG_BIG_ENDIAN to 1. For
little-endian (least significant byte first, i.e. Intel x86), #define
BLARGG_LITTLE_ENDIAN to 1.

Older C++ compilers might not support bool. Support is provided where
bool is not available, but the compiler's support of bool might not be
properly determined. If errors occur in "blargg_common.h" in the bool
section, #define BLARGG_COMPILER_HAS_BOOL to 1 if your compiler supports
bool, otherwise 0.

If your compiler supports namespaces, blargg_common.h uses standard
headers with the "c" prefix to avoid bringing names from std into the
global namespace. If your compiler supports namespaces but this isn't
being detected by blargg_common.h, #define BLARGG_COMPILER_HAS_NAMESPACE
to 1.

Every library source file has #include BLARGG_SOURCE_BEGIN after all
other #include lines, to allow setting compiler options and disabling
warnings for library sources only. By default, this is #defined to
"blargg_source.h".

In library source files, #include BLARGG_ENABLE_OPTIMIZER is used before
performance-critical code. By default it doesn't do anything, since
enabling compiler options involves compiler-specific #pragma directives.

After you've got the library working, you can enable platform-specific
optimizations by #defining BLARGG_NONPORTABLE to 1. Contact me if you
encounter any problems that only occur when these are enabled.

If you have any problems with "blargg_common.h", contact me.

