NSFPlay/NSFPlug
===============

This is an NSF player program for Windows, and also a Winamp plugin. The original version of this program was written by Brezza and is still available at pokipoki.org.

To use as a Winamp plugin, simply copy the contents of the plugins folder to your Winamp plugins folder.

Full source code is available at:
- http://rainwarrior.ca/projects/nsfplay/
- http://github.com/bbbradsmith/nsfplay

If you have any questions, comments, or find any bugs, please send them to me.

Brad Smith
nsfplay AT rainwarrior.ca
http://rainwarrior.ca


NSFPlay Keyboard controls
=========================

  Z > Prev
  X > Play
  C > Pause
  V > Stop
  B > Next


Command line arguments
======================

  NSFPlay [filename]
    Open and begin playing NSF file.
    > [filename] NSF or NSFE input file

  NFSPlay [nsf_filename] [wav_filename] (track) (milliseconds) >error.log
    Create WAV file from command line
    > [nsf_filename] NSF or NSFE input file
    > [wav_filename] WAV output file
    > (track) - optional, 1 if omitted
    > (milliseconds) - optional, sets PLAY_TIME

  Because it is a GUI application, errors cannot be reported to the command line
  console, but you can redirect errors to a log file with >.
  (>error.log in the example)

  Optionally any value from the configuration files can be temporarily set with
  an argument beginning with -. If this is done, the configuration will not be
  automatically saved on close, but can still be saved if you manually save
  the new configuration from the info page menu.

  NSFPlay -AUTO_DETECT=0
    > Disables automatic track length detection.

  NSFPlay -REGION=4
    > Force PAL region.

  The default INI configuration files can both be overridden from the command line.
  These will take effect before any other command-line parameters are applied,
  and only one INI/NSFPLAY substitute can be used. They can use an absolute path,
  or one relative to the current directory. If the file does not exist, NSFPlay
  will attempt to create it.

  NSFPlay -INI=override.ini
    > Override default in_yansf.ini file.

  NSFPlay -NSFPLAYINI=override.ini
    > Override default nsfplay.ini file.

Configuration files
===================

The default configuration file is in_yansf.ini, found in the plugins folder.
This will be automatically created when the program is run. If it can't be created
at its default location (e.g. access denied to C:\Program Files\Winamp\Plugins)
it will instead try to use your %APPDATA% directory under an NSFPlay folder.
(You can type %APPDATA%\NSFPlay into the Explorer address bar to find it.)

It will always check the folder next to in_yansf.dll first, so if this file is
present but not writeable, you may not be able to save settings unless it is
deleted to allow the %APPDATA% fallback.

The INI file location can be overridden with -INI.

Global options:
  RATE: samplerate
  QUALITY: oversampling (1-40)
  NCH: 1-2 number of channels
  BPS: 16 bits per sample (don't change this)
  MASK: bitfield channel mask (1 bit mutes channel)
  PLAY_TIME: (ms) default play time
  FADE_TIME: (ms) fade out time
  STOP_SEC: (s) seconds of silence before auto stop
  LOOP_NUM: (#) loops to allow before stopping
  AUTO_STOP: 1=automatically stop after silence
  AUTO_DETECT: 1=automatically detect loop if no track time is given in the file
  DETECT_TIME: (ms) loop detection comparison buffer
  DETECT_INT: (ms) jitter allowed between time comparisons in loop detection
  DETECT_ALT: 1=use alternate loop detection algorithm
  PLAY_ADVANCE: 0=auto play next track, 1=infinite loop, 2=stop after single track
  LPF: 0-400 lowpass filter strength (0=off, 112=default, 400=full)
  HPF: 0-256 highpass filter strength (256=off, 164=default, 0=full)
  TITLE_FORMAT: title string format (see below), default: %L (%n/%e) %T - %A
  VSYNC_ADJUST: 1=ignore NSF frame length setting
  MULT_SPEED: clock multiplier (256 = no multiplier)
  NTSC_BASECYCLES: NTSC master clock speed
  PAL_BASECYCLES: PAL master clock speed
  DENDY_BASECYCLES: DENDY master clock speed
  REGION: 0=auto, 1/2=prefer NTSC/PAL, 3/4/5=force NTSC/PAL/DENDY
  VRC7_PATCH: 0-7 patch set for VRC7 (see below)
  MASTER_VOLUME: 0-255 master volume
  NSFE_PLAYLIST: 1=use playlist data from NSFe when found
  WRITE_TAGINFO: ?
  READ_TAGINFO: ?
  UPDATE_PLAYLIST: ?
  MASK_INIT: 1=clear channel mask on play
  INFO_DELAY: (ms) latency delay for keyboard view
  INFO_FREQ: (Hz) keyboard view update frequency
  GRAPHIC_MODE: 1=display graphical waveforms for FDS/N163
  FREQ_MODE: 1=display Hz in keyboard view, 0=display hexadecimal pitch register
  LAST_PRESET: name of the last sound preset used
  LOG_CPU: log CPU writes to file (0=off, 1=sound only, 2=all writes, 3=all r/w, 4 bank and RAM writes)
  LOG_CPU_FILE: filename of CPU write log
  IRQ_ENABLE: forces IRQ capability to be enabled for all NSFs, not just NSF2.

TITLE_FORMAT text replacement:
  %F/%f > filename
  %P/%p > path
  %T/%t > NSF title
  %A/%a > NSF artist
  %C/%c > NSF copyright
  %L/%l > NSFe song title
  %N > song number, 2-digit hex with leading zero
  %n > song number, 3-digit decimal with leading zeroes
  %S > NSF starting song, 2-digit hex with leading zero
  %s > NSF starting song, 3-digit decimal with leading zeroes
  %E > NSF song count, 2-digit hex with leading zero
  %e > NSF song count, 3-digit decimal with leading zeroes

Device options:
  Devices (XXX) are: APU1, APU2, 5B, MMC5, N163, VRC6, VRC7, FDS
  XXX_VOLUME: 0-255 device volume
  XXX_MUTE: 1/0 mute channel yes/no
  APU1_OPTION0: unmute on reset
  APU1_OPTION1: phase reset
  APU1_OPTION2: nonlinear mixing
  APU1_OPTION3: famiclone swapped duty (1<->2)
  APU2_OPTION0: enable $4011 writes
  APU2_OPTION1: enable periodic noise
  APU2_OPTION2: unmute on reset
  APU2_OPTION3: anti clicking (suppresses $4011 pop without disabling its nonlinear mix)
  APU2_OPTION4: nonlinear mixer
  APU2_OPTION5: randomize noise on reset
  APU2_OPTION6: mute triangle on pitch 0 (prevents high frequency aliasing)
  APU2_OPTION7: randomize triangle on reset
  APU2_OPTION8: reverse bits of DPCM sample bytes
  FDS_OPTION0: (Hz) lowpass filter cutoff frequency (0=off, 2000=default)
  FDS_OPTION1: reset "phase" on $4085 write (works around timing issue in Bio Miracle Bokutte Upa)
  FDS_OPTION2: write protect $8000-DFFF (for some multi-expansion NSFs)
  MMC5_OPTION0: nonlinear mixing
  MMC5_OPTION1: phase reset
  N163_OPTION0: serial multiplexing (more accurate sound for 6+ channels)
  N163_OPTION1: Read-Only phase (for old NSFs that overwrite phase every frame)
  N163_OPTION2: Limit wavelength (for old NSFs that do not set the high bits)

Channel options:
  There are 29 channels, as appear vertically in the channel mixer, numbered (XX) from 00 to 28.
  CHANNEL_XX_PAN: 0-255 panning (0=left, 255=right, 128=centre)
  CHANNEL_XX_VOL: 0-128 volume
  CHANNEL_XX_COL: hex string for keyboard view colour (exactly six characters, no leading space)
  5B_ENVELOPE_COL: keyboard colour for 5B envelope
  5B_NOISE_COL: keyboard colour for 5B noise

VRC7 patch sets: (VRC7_PATCH)
  0 - VRC7 set by Nuke.KYT 3/15/2019 (dumped from VRC7 via special debug mode)
  1 - VRC7 set by rainwarrior 8/01/2012 (used by Famitracker 0.4.0)
  2 - VRC7 set by quietust 1/18/2004 (used by Famitracker 0.3.6)
  3 - VRC7 set by Mitsutaka Okazaki 6/24/2001 (used by Famitracker 0.3.5 and prior)
  4 - VRC7 set by Mitsutaka Okazaki 4/10/2004
  5 - VRC7 set by kevtris 11/15/1999 (second set in vrcvii.txt)
  6 - VRC7 set by kevtris 11/14/1999 (first set in vrcvii.txt)
  7 - YM2413 set by Mitsutaka Okazaki 4/10/2004
  8 - YMF281B set by Chabin 4/10/2004
  9 - YMF281B set by plgDavid 2/28/2021

The NSFPlay application has its own nsfplay,ini file, found next to the .exe,
or in %APPDATA%\NSFPlay if it could not be created there. (Use -NSFPLAYINI to
specify a different location.)

This has a few options to control the loading of the plugin. The last used
volume is saved at exit. NSFPlay could be used with other Winamp plugins, but
only with more basic features.

nsfplay.ini settings:
  PLUGIN: Path to player plugin. Default: plugins\in_yansf.dll
  VOLUME: 0-255 starting volume. Default: 255 (Does not affect WAV export.)
  SAVEVOLUME: 0 = don't save, 1 = save. Default: 1


Playlists
=========

NSFPlug supports Winamp M3U playlists in the same style as NEZplug.
The playlist is a text file with one track per line in the form:

filename::NSF,[song],[title],[time],[loop],[fade],[loopcount]

filename  - relative path to NSF file
song      - track number from the NSF (track 1 is the first track)
title     - title of the track
time      - h:m:s length of the track
loop      - h:m:s loop length, h:m:s- loop start time, - no loop, 0 no loop
fade      - h:m:s fade time
loopcount - number of times to loop, 0 default


Versions
========

NSFPlay 2.6 - 7/03/2023
- NSF2 IRQ vector filled with existing content at $FFFE by default.
- Unicode filename support, UTF8 metadata support.
- Legacy Shift-JIS support for NSF title/author/copyright fields.
- YM2413 emulation update to emu2413 1.5.9. (Gumball2415, okaxaki)
- YMF281B plgDavid patch set option. (Gumball2415m plgDavid)
- Resizable info window.
- Right click info button to open the keyboard track-info window.
- Fix random variation in command line WAV export times.
- Allow multiple instances of command line WAV export.
- Add redirectable diagnostic log to stdout for command line usage. (Use > to send it to a file.)
- Allow command-line configuration overrides.
- Allow command-line INI file overrides.
- Use VS2019 for official builds (still using VS2017 v141_xp toolset).

NSFPlay 2.5 - 10/25/2022
- APU frequency dividers now count down (more accurate pitch change timing).
- Keyboard view speed control setting should reset to normal when the program restarts.
- DPCM bit-reverse option.
- Playback advance options (auto, infinite play, single track).
- Negate sweep init option (compatibility with old SuperNSF, etc. that relies on nonstandard sweep init).
- Option to force VRC7 replacement with YM2413 (OPLL).
- DPCM read delay adjusted (4 cycles is a more accurate approximation than 2).
- Default volume of APU 2 raised to match measured triangle volumes.
- Fixed triangle and noise being logically inverted.
- Fixed error in track selector length when using NSFe playlists.
- Integrated VRC7 (YM2143) emulation update from Mitsutaka Okazaki.
- Linear square mix level now matches nonlinear at 1 full square.
- Fix winamp playlist generator track titles.
- Write protect internal player memory.

NSFPlay 2.4 - 3/30/2019
- Fixed incorrect bytes per second in stereo WAV output.
- Fixed NSFe track title display when using playlist.
- Fixed crash issue with 1MB NSF files. (Bank counting was incorrect.)
- Default NTSC speed changed from 16640 to 16639. (Slightly more accurate to hardware.)
- More bits of precision on fade-out, creates smoother fade.
- 48000Hz is the new default samplerate.
- Fixed keyboard view wave string bias on N163/FDS.
- Fixed frequency rounding for triangle/noise/DMC in keyboard display.
- Fixed intermittent crash with Winamp starting up with NSF in playlist.
- Fixed FDS mod table bit-mask and wavetable read address. (Minor.)
- Fixed broken playback rate for rates < 28 Hz.
- NSFe RATE chunk implemented.
- NSFe regn chunk implemented, including full Dendy support.
- NSFe mixe chunk implemented.
- NSFe taut, psfx chunk implemented.
- Drag and drop will now acknowledge a failed load with a pop-up alert.
- Migrate to VS2017.
- IRQ support.
- Play now runs at next opportunity rather than always at the start of frame, similar to poll based players like PowerPak.
- Other expansions with FDS automatically disables FDS RAM writes, and FDS banking for $6000-7FFF.
- Full NSF2 implementation. (non-returning INIT, suppress play, IRQ, NSFe metadata.)
- Removed non-functional filters, compressors, etc. from the audio chain.
- Removed per-channel quality settings, created a single master quality setting.
- DPCM byte read now takes 2 cycles.
- Improved NES CPU vs APU/audio synchronization (controlled by quality setting).
- Better error messages for files that can't be loaded.
- Fixed broken seek, and restored the "fask seek" option. (Seeks as if quality=1, normally OK.)
- If in_yansf.ini can't be found or created next to in_yansf.dll, will try to save settings to %AppData%\NSFPlay\ instead.
- N163 compatbility options for phase write protect and limited wavelength. (Supports old NSFs that are not hardware accurate.)
- Option to randomize starting triangle phase.
- NSFe VRC7 chunk implemented, provisional support for YM2413 variant.
- VRC7 patch set dump by Nuke.YKT.

NSFPlay 2.3 - 7/19/2013
Emulation:
- All illegal 6502 opcodes are now emulated.
- Audio emulation is now driven by CPU clock cycles, increases timing accuracy.
- FDS emulation completely rewritten for better accuracy.
- N163 emulation completely rewritten for better accuracy.
- APU frame sequencer now correctly driven by $4017, supports 4 and 5 step modes, immediate reset, and IRQ flag.
- MMC5 frame sequencer now independant of APU frame sequencer.
- Time dilation now slows frame sequencer along with CPU rate.
- Replaced PREFER_PAL setting with REGION, containing more options including Dendy support.
- Swapped duty option for APU1.
- More effective implementation of DMC anti-click option.
- Removed useless "frequency limiter" APU option.
- Added optional mute for ultrasonic triangle.
- Fixed broken oversampling filter.
- Adjusted device volumes to match more careful measurements, all centred at 128 now.
Other:
- Better small icon.
- Thinner DPCM address display, does not get truncated.
- Using # instead of + for note names.
- Cosmetic fixes in settings dialog.
- Keyboard frequency display correction for APU/MMC5/VRC6 (were off by 1).
- Keyboard envelope display now shows L for loop.
- N163 waveform display now hides waveform when track is muted with a wave length >= 128.
- Expanded infobox info for NSFe.
- Fixed improper loading of UI DLL, prevents crash in same folder as Famitracker.
- UI DLL now reports version, preventing potential problems if mismatched.
- LOG_CPU option for dumping register writes to file.
- Fixed song wrap where NSFs do not start on song 1.
- Source code cleanup: removing unrelated Z80 emulation code.

NSFPlay 2.2 - 8/31/2012
Audio Emulation:
- Unmute on reset now sets $4015 to $0F instead of $1F.
- PAL noise frequency $1 now 8 instead of incorrectly 7.
- New VRC7 patch set, option to select alternative patch sets via VRC7_PATCH.
- 5B polarity inverted, envelope adjusted, volume tweak.
- MMC5 polarity inverted, length counter runs at double speed, highest 8 frequencies are not muted.
- VRC6 $9003 register implemented (controls halt and frequency multiplier)
- VRC6 polarity inverted, phase reset now functions properly.
- FDS now uses NSF header $76/$77 to set up $6000-7FFF memory range.
- FDS $4087 bit 7 now mutes modulator.
- Enable periodic noise option fixed. (Forced perodic noise by accident.)
Other:
- Fixed improper $4015 read implementation (should return length counter status), also DPCM IRQ was not initialized.
- Default focus in keyboard window now the track list (to prevent accidental mouse scroll time expansion).
- Fixed Winamp visualizer timing inaccuracy, changed default keyboard delay/freq.
- Inverted VRC7 volume display in keyboard view.
- NSFe support.
- Added NSFe extension block 'text', contains null terminated string of any length (NSF text).
- Removed broken ENABLE_DCF config option. HPF=256 now correctly disables HPF.
- Rewrote LPF and HPF, should have a more usable range of options now.
- Removed XXX_FR/XXX_FC options, now XXX_FILTER works like LPF for each device.
- Memory R/W access is now exclusive to the first device that accepts it; prevents FDS multi-expansion write conflicts.
- Title string will automatically remove whitespace at its beginning or end.
- Fixed single instance bug, was failing to open new NSF file when chosen from explorer.
- Fixed conflicts between keyboard commands and other dialogs.
- Removed tag menu from info page. Does not appear to apply to NSFs.
- Fixed incorrect PAL pitch when QUALITY=0.

NSFPlay 2.1 - 3/27/2012
Audio Output:
- Fixed race condition in audio buffering; stand alone NSFPlay would occasionally get stuck stuttering.
- Produces stereo output, channel mixer dialog for panning and per-channel volume control.
- Fixed PCM playback speed; CPU execution was counting requested clocks, not clocks executed.
- Fixed accuracy of seek times.
- Loop detection now accounts for all audio registers, not just a subset of 2A03 and N163.
- N163 wavelength is actually 6-bit, not 3. Now allows sample length up to 256.
- Fixed FDS volume/sweep envelope caps. (Direct register writes can make them louder.)
- Fixed FDS modulation bias calculation and wrapping.
- Set default volume for VRC7 and FDS a little lower (to match expected levels).
- MMC5 PCM support (for both read and write mode).
- Added phase reset option to MMC5.
- MMC5 was missing length counter and audio register reads; rewrote to conform with APU.
- Adjusted phases for APU/MMC5 square channels to match NesDev's description.
- APU/DMC/MMC5 rewrite of envelope/length/sweep behaviour to use a frame sequencer instead of independent timers.
Options:
- Option to randomize noise on reset (on by default).
- Options cleanup, removed unused/deprecated options from .ini file.
- Using global LPF by default instead of on each device (saves CPU, same result).
- Keyboard view channel colour is now customizable in .ini file (CHANNEL_XX_COL).
Keyboard view:
- Fixed crash due to keyboard OnTimer being allowed before Reset() is executed by the PlayThread.
- Double buffering keyboard view to remove flicker.
- Different colours for different expansions in keyboard view.
- Fixed sound lag after seek.
- FME-7 now named 5B, N106 now named N163.
- DPCM now named DMC in keyboard view.
- Fixed 5B volume display (E now correctly indicates envelope, volume is now correct value).
- 5B now displays envelope and noise.
- VRC6 saw volume now displays accumulator register.
- Corrected VRC6 saw pitch in keyboard view.
- Fixed trailing lines on N163 waveform display.
- DMC volume display no longer flipped (is now $4011 register value).
- DMC now shows sample frequency rather than byte frequency.
- Triangle and noise were not showing muting due to length counter of 0.
- Noise now has frequency display (either rate of random samples, or tonal frequency for periodic noise).
- Removed feature that extends the life of key dots beyond the frame the channel is active (frequency can change when key is silent, esp. VRC6 squares, which visibly jump to the wrong pitch)
Other:
- Save WAV button on NSFPlay.
- Command line WAV output for batch processing.
- Added extra NSF header information to "misc" text box, initial banks, load/init/play addresses, etc.
- Fixed thread-safety issue for configuration (was accessed liberally from many threads).
- Removed legacy code for windows versions older than XP.
- CPU trace define in nes_cpu.cpp for debugging.

NSFPlay 2.0 - 2/22/2012
- Restructured sln/vcproj files, and rebuilt for VS9.
- All intermediate files go into common Debug/Release directories.
- Renamed wa2nsf project to in_yansf to match name of the plugin.
- Fixed improperly set WAVEFORMATEX header in libemuwa2 (allows execution on windows Vista/7).
- Corrected pitch of noise channel.
- Updated VRC7 default patch set.
- Added PAL support and pal flags indicator (PREFER_PAL=1 to prefer PAL for dual mode).
- Added about box for determining build version.
- Fixed some menu items in English dialogs.
- Fixed some initial config settings.
- Fixed crash when using playlist menu options with no loaded NSF.

NSFPlay - 12/09/2006
- Written by Brezza > http://www.pokipoki.org/dsa/index.php?NSFplay


Contributors
============

Brad Smith
https://github.com/bbbradsmith
- main developer and maintainer since 2.0 (2012)

Mitsutaka Okazaki
https://github.com/okaxaki
- original developer
- YM2143 emulation updates

John Regan
https://github.com/jprjr
- clang/gcc compile preparation
- infinite track playback
- separated NSFPlay library (contribs)
- nsf2wav tool (contribs)
- MMC5/VRC6 initialization fixes

Marat Fayzullin
https://fms.komkon.org/
- 6502 emulator core

rwtodd
https://github.com/rwtodd
- VS2019 compilation fixes

Admiral H. Curtiss
https://github.com/AdmiralCurtiss
- VS2015 compilation fixes

Gumball2415
https://github.com/Gumball2415
- YM2413 emulation update
- YMF281B plgDavid patch set option

Russell Harmon
https://github.com/eatnumber1
- nsf2flac (contribs)
- nsfmeta converts NSFe data to json (contribs)

Valtteri Heikkilä 
https://github.com/tsone
- nsf2wav fix triangle/noise randomiazation (contribs)


===============
end of document
