mirror of
https://github.com/daniel5151/ANESE.git
synced 2025-04-02 10:32:00 -04:00
I started looking into how to make the APU, and boy, let me tell ya, it's going to be a massive undertaking. Undoubtedly a fun undertaking, but still... Since it's a personal goal to get Super Mario Bros 2 running before new years (after all, that game has won game-of-the-year i don't even know _how_ many years in a row), i've decided to just use Blargg's venerable `nes_snd_emu` library for now. It took some wrestling, it it's in, and it works! Almost. I still don't know why enabling the Frame IRQ kills most games, but i'll look into that! Welp, on to bigger and better things! Namely: MMC1, which will give me Zelda and... Super Mario Bros 2!
169 lines
7.1 KiB
Text
Executable file
169 lines
7.1 KiB
Text
Executable file
Nes_Snd_Emu 0.1.7 Notes
|
|
-----------------------
|
|
|
|
Overview
|
|
--------
|
|
The library includes a NES APU sound chip emulator, sound sample buffer,
|
|
support for state snapshots, a Namco 106 sound chip emulator, a Konami VRC6
|
|
sound chip emulator, and a nonlinear sound buffer.
|
|
|
|
The sound chip emulators handle reads and writes to their registers and
|
|
generate samples into one or more sound buffers. Register accesses take a CPU
|
|
clock count, relative to the current time frame. When a time frame is ended all
|
|
samples from it are added to the sound buffer.
|
|
|
|
The sound buffer accumulates samples generated by the sound chips and allows
|
|
them to be read out at any time. The sample rate can be adjusted freely.
|
|
|
|
|
|
Using the APU
|
|
-------------
|
|
Simple_Apu is recommended instead of Nes_Apu when using the library for the
|
|
first time (see Simple_Apu.h for reference). Its source code demonstrates basic
|
|
use of the APU.
|
|
|
|
To use Nes_Apu (or the other sound chips), its output must be routed to a
|
|
Blip_Buffer. Then pass CPU reads and writes to the sound chip, end its time
|
|
frame periodically and read samples from the sound buffer.
|
|
|
|
Nes_Apu apu;
|
|
Blip_Buffer buf;
|
|
|
|
Setup
|
|
buf.sample_rate() Set sample rate and allocate memory for buffer
|
|
buf.clock_rate() Set clock rate (1789773 for NTSC NES)
|
|
apu.output() Route APU output to buffer
|
|
apu.dmc_reader() Set function APU calls to read memory
|
|
|
|
Emulation
|
|
apu.write_register() Emulate write to APU register
|
|
apu.read_status() Emulate reads APU status register
|
|
apu.end_frame() Generate samples for time frame
|
|
buf.end_frame() Make samples for time frame available for reading
|
|
buf.samples_avail() Number of samples in sound buffer
|
|
buf.read_samples() Read samples out of sound buffer
|
|
|
|
|
|
Nonlinear Sound Emulation
|
|
-------------------------
|
|
Nonlinear_Buffer is a special sound buffer which emulates the non-linearity of
|
|
the NES APU sound chip on the triangle, noise, and DMC channels. It can be used
|
|
in place of Blip_Buffer, except that the APU should be assigned using
|
|
buf.enable_nonlinearity( apu ), and other sound chips using
|
|
other_sound_chip.output( buf.buffer() ).
|
|
|
|
|
|
Blip_Buffer
|
|
-----------
|
|
Basic Blip_Buffer operation is covered. Further features like frequency
|
|
equalization and other features are not described. For more information and
|
|
examples of using Blip_Buffer, download the full Blip_Buffer library package
|
|
|
|
|
|
Emulation Accuracy
|
|
------------------
|
|
Nes_Apu accuracy has some room for improvement, especially regarding IRQ
|
|
handling. I am still working on reverse-engineering the NES APU and designing
|
|
an improved APU.
|
|
|
|
Nes_Namco and Nes_Vrc6 accuracy is based on the documentation I have. I have
|
|
made many tweaks to make them sound similar to a couple of samples I've heard
|
|
of the real thing.
|
|
|
|
|
|
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 new (nothrow) so that a failed allocation won't cause
|
|
an exception. 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 doesn't support static_cast<>, #define STATIC_CAST( type ) to
|
|
(type) so that old-style casts are used instead.
|
|
|
|
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.
|
|
|
|
|
|
Boost Compatibility
|
|
-------------------
|
|
Boost is a collection of small, useful C++ libraries which provide basic
|
|
services. If it's not installed in your environment or your environment isn't
|
|
supported, a tiny substitute is included in the "boost/" directory. This
|
|
implements only that boost functionality used, and is written to work with most
|
|
compilers. If boost is already installed, you can delete the included "boost/"
|
|
directory. For more information about boost, see http://boost.org/
|
|
|
|
|