bbbradsmith / nsfplay Goto Github PK
View Code? Open in Web Editor NEWNintendo NES sound file NSF music player
Home Page: https://bbbradsmith.github.io/nsfplay/
Nintendo NES sound file NSF music player
Home Page: https://bbbradsmith.github.io/nsfplay/
NSFPlay/NSFPlug source code This code is maintained by Brad Smith. It is a fork of NSFPlay/NSFPlug by Brezza. The latest version should be available at: - https://bbbradsmith.github.io/nsfplay/ Unstable preview builds will be automatically generated by Github Actions: - https://nightly.link/bbbradsmith/nsfplay/workflows/build/master This code contains several modifications to original, see nsfplay.txt for a list of changes. I have presumed based on text comments and readme files in the original code that it is distributed freely, and modification and redistribution is permitted. The same permissive license applies to this version of the code I maintain. You may reuse this code without restriction, and no warranty or liability is implied on my part. Feel free to contact me with questions or comments. Brad Smith nsfplay AT rainwarrior.ca http://rainwarrior.ca Original NSFPlay/NFSPlug project available at: http://www.pokipoki.org/dsa/
When using NSFplug's playlist generator (under File/Winamp Playlist,) the resulting m3u file does not format itself correctly. It seems to pull the title formatting from the main settings rather than using the NSFe information present to generate the playlist. I've attached an example of how it looks below. This playlist does play fine within Winamp/WACUP, but of course all of the song information is incorrect.
[playlist]
File1=F:\Music\Game\Original Soundtracks\Proprietary Format\NSFe\NSFe_Collection_Part1_NTSC\Danny Sullivan's Indy Heat.nsfe::NSF,$01,Title Screen (001) - Danny Sullivan's Indy Heat,,
File2=F:\Music\Game\Original Soundtracks\Proprietary Format\NSFe\NSFe_Collection_Part1_NTSC\Danny Sullivan's Indy Heat.nsfe::NSF,$02,Title Screen (001) - Danny Sullivan's Indy Heat,,
File3=F:\Music\Game\Original Soundtracks\Proprietary Format\NSFe\NSFe_Collection_Part1_NTSC\Danny Sullivan's Indy Heat.nsfe::NSF,$03,Title Screen (001) - Danny Sullivan's Indy Heat,,
File4=F:\Music\Game\Original Soundtracks\Proprietary Format\NSFe\NSFe_Collection_Part1_NTSC\Danny Sullivan's Indy Heat.nsfe::NSF,$04,Title Screen (001) - Danny Sullivan's Indy Heat,,
File5=F:\Music\Game\Original Soundtracks\Proprietary Format\NSFe\NSFe_Collection_Part1_NTSC\Danny Sullivan's Indy Heat.nsfe::NSF,$05,Title Screen (001) - Danny Sullivan's Indy Heat,,
File6=F:\Music\Game\Original Soundtracks\Proprietary Format\NSFe\NSFe_Collection_Part1_NTSC\Danny Sullivan's Indy Heat.nsfe::NSF,$06,Title Screen (001) - Danny Sullivan's Indy Heat,,
File7=F:\Music\Game\Original Soundtracks\Proprietary Format\NSFe\NSFe_Collection_Part1_NTSC\Danny Sullivan's Indy Heat.nsfe::NSF,$07,Title Screen (001) - Danny Sullivan's Indy Heat,,
File8=F:\Music\Game\Original Soundtracks\Proprietary Format\NSFe\NSFe_Collection_Part1_NTSC\Danny Sullivan's Indy Heat.nsfe::NSF,$08,Title Screen (001) - Danny Sullivan's Indy Heat,,
File9=F:\Music\Game\Original Soundtracks\Proprietary Format\NSFe\NSFe_Collection_Part1_NTSC\Danny Sullivan's Indy Heat.nsfe::NSF,$09,Title Screen (001) - Danny Sullivan's Indy Heat,,
File10=F:\Music\Game\Original Soundtracks\Proprietary Format\NSFe\NSFe_Collection_Part1_NTSC\Danny Sullivan's Indy Heat.nsfe::NSF,$0a,Title Screen (001) - Danny Sullivan's Indy Heat,,
File11=F:\Music\Game\Original Soundtracks\Proprietary Format\NSFe\NSFe_Collection_Part1_NTSC\Danny Sullivan's Indy Heat.nsfe::NSF,$0b,Title Screen (001) - Danny Sullivan's Indy Heat,,
File12=F:\Music\Game\Original Soundtracks\Proprietary Format\NSFe\NSFe_Collection_Part1_NTSC\Danny Sullivan's Indy Heat.nsfe::NSF,$0c,Title Screen (001) - Danny Sullivan's Indy Heat,,
File13=F:\Music\Game\Original Soundtracks\Proprietary Format\NSFe\NSFe_Collection_Part1_NTSC\Danny Sullivan's Indy Heat.nsfe::NSF,$0d,Title Screen (001) - Danny Sullivan's Indy Heat,,
File14=F:\Music\Game\Original Soundtracks\Proprietary Format\NSFe\NSFe_Collection_Part1_NTSC\Danny Sullivan's Indy Heat.nsfe::NSF,$0e,Title Screen (001) - Danny Sullivan's Indy Heat,,
NumberOfEntries=14
Version=2
Hi,
A few hours ago I updated my NSFPlay copy, but whenever I open files from the Windows explorer, NSFPlay doesn't play anything and it crashes. (I've NSFPlay as the default player)
I deleted all the settings, but that doesn't solved my issue.
But when I open files using NSFP's file explorer, all the NSFs play just fine.
I've re-downloaded the stable version to confirm if it works, and indeed it does.
I'm sorry, I don't have more details. The logs that Windows leaves in the event viewer didn't help much either.
It would be nice to see EPSM support added, It's currently supported in FamiStudio and the Mesen fork Mesen-X
When nsf just uses 1 N163 channel, the volume is too loud! Here's some nsf:
http://www.mediafire.com/file/9ha4ov5xddyy6ff/N163Songs.zip
Brad,
I am using Wine v5.7, pulseaudio and a Realtek audio chipset with Linux v5.6.10 kernel. If "stereo mode" is enabled in v2.5 beta of NSFPlay then the audio file is played back at max speed. If it is disabled, it plays normally.
Oh! And stereo mode seems to be the default configuration on start-up. Until resolved, a dirty fix could be to not include it as a default option.
Please investigate. Thanks!
The debug build of NSFPlay is known to have relatively poor performance. I received an e-mail with some compilation tips that may help:
I managed to reach decent performance of debug build without any changes in code. Main reasons of poor performance are STL (surprisingly) and of course general debug overhead. So maybe future version could use some simple containers instead of STL containers (particularly std::vector) in classes of xgm namespace. What i tried:
https://stackoverflow.com/questions/3362895/visual-studio-application-running-extremely-slow-with-debug Changed /ZI to /Zi compilation flag (big difference!) Changed _DEBUG to NDEBUG (not sure about it) Applied "Enable Windows debug heap allocator (Native only)" option in visual studio (not sure about it) https://stackoverflow.com/questions/15949582/drastic-performance-differences-debug-vs-release Applied "_HAS_ITERATOR_DEBUGGING=0" preprocessor definition to the project (big difference!) Disabled some runtime checks (big difference!) Basic runtime checks: uninitualized variables Security check: disable security check
And voila - now it performs relatively good.
Any version:
Pop noise will be produced when a triangle sound play over, such as intro triangle bong bong bong of Mega Man 4 Bright Man song.
2.5 beta version:
Each time play an nsf, it usually pop 1 time at beginning.
Hello, I would like to make a request, but I'm honestly not sure if it's technically possible. But here I go. I would like to know if it is possible to add a functionality that translates the melodies of the .NSF files to Negative Harmony. It's a relatively new concept that would require knowledge of music composition to program and would depend on many factors, as each game uses a different range of chips. I would like to know how viable it would be. Here I attach two Youtube links as an example of Negative Harmony:
Original:
Contra Jungle Theme
Converted into Negative Harmony:
Contra Jungle Theme NH
Greetings!!!
I'd like to output a WAV file of each sound channel or a grouping of sound channels. Does NSFPlay do this?
It is necessary to increase the max bit depth and sample rate in the new version of NSFPlay 3.0+, add 24-bit/32-bit float/64-bit float and 192000Hz, 384000Hz, 768000Hz, 1536000Hz, 3072000Hz sample rates. This is necessary for the most accurate reproduction and to ensure that as many frequencies as possible are captured in the audio file (as you can see on the spectrogram, many frequencies are still cut off when playing at 384000Hz)
(001.056) BATMAN Return of The Joker.zip
Would it be possible to see a batch export feature sometime before v3? I'd like it to export every track in an NSF/NSFE file to a directory, titling the tracks automatically, with a couple button presses. I downloaded the source and tried to implement it myself, but I couldn't get any changes to work at all, probably because I have no idea what I'm doing.
I think this would be a popular feature, I'm shocked it hasn't been requested already (unless I missed it). I hope to see it implemented sometime before v3.
Hello.
I have poor English, but I would like to let know us the following phenomenon.
I appreciate it if you could fix the following phenomenon.
NSFPlay 2.4 cannot use IRQ on the following condition.
if 0x7C is 0x00, NSFPlay 2.4 can use IRQ.
07C 1 BYTE NSF2 feature flags
bits 0-3: reserved, must be 0
bit 4: if set, this NSF may use the IRQ support features
Hello.
I would like to request as follows.
I appreciate it if you could support YM2413 (OPLL) on TNS-HFX4.
TNS-HFX4 is hardware that can play NSF file on Family computer.
This hardware can insert some cartridge's.
Moreover, this hardware have on-board YM2413.
Therefore, this hardware can play VRC7 and OPLL at the same time.
http://www2s.biglobe.ne.jp/~tns/nr26730801.html
So, we can make the dokamori
NSF that have APU, FDS, MMC5, VRC6, VRC7, SN5B and OPLL.
I've developed this sound driver dor dokamori
.
VRC7: 0x9010 and 0x9030
OPLL: 0x5F90 and 0x5FB0
http://www2s.biglobe.ne.jp/~tns/guideline.html
Thanks and best regards,
This issue is a sort of roll-up of two issues, but one of them apparently has to be fixed by @jprjr and the other can be fixed by someone else.
The first issue is with nsf2wav. It's very explicit Posix assumptions makes it near impossible to compile on Windows, which appears to be the only place nsfconfig_ini
works. Can something be adapted so I can specify something like --config /path/to/in_yansf.ini
to bring custom settings? Especially the setting of master volume? Multi-expansion audio tends to clip in renders and so I need to turn master volume down.
The second issue is related to the way NSFPlay handles being passed wave arguments. Yes I can render a wave file with it, but since it's a GUI application my console returns immediately. Furthermore since it partially initializes the GUI and then completely blocks until the wave file is written then closes it, my screen reader comes to a dead stop until the process is finished. I am a blind PC user with access to MinGW via MSYS2 and Ubuntu via WSL v2, but am unable to batch render some NSFs from Famicompo with the settings I like no matter what I try. The reason my screen reader comes to a dead stop upon rendering a wave file is because accessibility applications send queries to created UIs, and if those UIs don't answer that query they just lock up. This is unfortunately just a part of Windows and cannot be worked around. Perhaps checking for rendering to a wave file before creating the outer window would fix this?
Either way, I just want some way to have a custom config file and use something like xargs to render a batch of NSFs. Can't do batch renders with the Winamp plug-in, no Foobar plug-in, NSFPlay command line breaks my interaction entirely and nsf2wav doesn't except settings. Can anyone do something about one of these?
Half-Linear sounds like real NES(Famicom) and Nestopia's effect (when two 75% square wave plays).
Unfortunately I don't know much about the specifics of this bug or what causes it, but it's made certain recent file releases that use VRC6+N163 completely unplayable in the software due to unintentional earrape.
Here are two examples, please be careful with your ears!
Example 1: Battle! Ho-Oh
Example 2: Freezy Flake Galaxy
nsfmeta compilation with -liconv argument fail, without not fail.
g++ -o nsf2wav .objs/nsf2wav.o libnsfplay.a
g++ -o nsfmeta .objs/nsfmeta.o libnsfplay.a -liconv
/usr/bin/ld: cannot find -liconv
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:176: nsfmeta] Error 1
make[1]: Leaving directory '...../nsfplay/contrib'
make: *** [Makefile:165: debug] Error 2
Debian unstable, gcc info:
gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 10.2.1-6' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-10-Km9U7s/gcc-10-10.2.1/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-10-Km9U7s/gcc-10-10.2.1/debian/tmp-gcn/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-mutex
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.2.1 20210110 (Debian 10.2.1-6)
Hello, would you mind helping me understand how "accurate" the NSF to WAV conversion is when a WAV file is saved from the NSF? Is the WAV an accurate representation of what the NSF is "playing"? Is it a lossless conversion?
I read somewhere that NSF files are equal to a 1-bit WAV file. Is that true? What is the sample rate of an NSF? Does it matter?
I'm asking because I am analyzing WAV files saved from NSF play and am seeing some stuff I didn't expect in my oscilloscope.
Upon loading this NSFe and double-clicking on the song title in Winamp (to open the NSFplug dialog), the song selector states there are 45 tracks -- tracks 0-15 are music, whilst tracks 16-44 are SFX. The Misc area reads Start track: 1 of 45
. There is an NSFe playlist -- NSFe plst order: 12, 6, 0, 1, 8, 5, 4, 2, 3, 9, 14, 11, 13, 7, 10
.
Upon playing the first track/song in the playlist (track 12), the Song Selector slider shows 45 ticks. However, once that song is done, the slider shows a total of 15 song and the Misc area changes to show Start track: 1 of 15
. Closing the NSFplug dialog and re-opening it again shows 45 tracks until the next song plays or next/previous track is chosen.
Also, attempting to switch to an SFX track (ex. 39) when this quirk is present causes NSFplug to switch to a different seemingly-random song.
I do have Use NSFe Playlist checked/enabled in Options -> Settings -> General.
I'm under the impression that this checkbox should basically inhibit any display of the non-NSFe-playlist tracks, i.e. under no circumstance should the Song Selector be showing 45 ticks.
Reported by RushJet1, apparently a specified time longer than the default time setting causes the output to halt at the default time instead, with no fade?
if you specify a time less than the default time: there is no fadeout, it just cuts
if you specify a time more than the default time: it ends the track at the default time instead with the fadeout
i have set the default times in all the render instances of nsfplay to 5000 seconds
also nsfplay doesn't let you run multiple of itself at once so i named the .exe files nsfplay2 nsfplay3 etc
Also:
hey i've noticed that the output for command prompt wav output is inconsistent apparently
yeah even if i make the same instance of the program do the same channel multiple times it has a seemingly random file size
Sawtooth sweep aliasing.zip
This is a linear sawtooth sweep from N163's lowest frequency to the highest
Start at 0:20 I can hear the artifacts of audio aliasing.
Is there a way to eliminate aliasing? LPF before sampling?
No sound output...
Title. I get an error if I try to load any .nsf files that have a Japanese name or are in a folder with a Japanese name.
I've tested this with various NSF players, NEZplug++ seems to be the only player that emulates this NSFplay just ignores it, also I think the volume curve is a bit off?
5B_ultrasound_half_volume_test.zip
I've been working on deciphering how nsfplay's loop detection works. It's not documented, and until I started poking around I'd never seen it work.
This is mostly some disconnected notes from my code diving / debugging sessions with it, but I'm dropping it here because as far as I can tell this is the closest to documentation that's available.
To enable detection, set AUTO_DETECT=1
in in_yansf.ini. "Enable playtime detection" in the settings does this.
There's two detectors: BasicDetector (default) and NESDetectorEX (DETECT_ALT=1
, or uncheck "Use the default loop detection algorithm" in the settings).
I didn't dive too deeply into NESDetectorEX, but it seems to run BasicDetector over every channel separately (e.g. DPCM, SQR0, SQR1, etc.), then joins the results. Everything below is about BasicDetector.
It uses a sliding window as configured by DETECT_TIME
(default 30s). Units are milliseconds. The maximum window is 16 KiB in size, not configurable. How much time this is depends on the playback speed, but there's a fixed maximum DETECT_TIME
due to this.
Every DETECT_INT
milliseconds (no setting in the UI for this, default 5s), the detector matches against the last DETECT_TIME
milliseconds of audio. If it is identical, it is considered a loop.
Detection doesn't even start until a DETECT_TIME
period has passed. After one DETECT_TIME
has passed, on the next detection call (as controlled by DETECT_INT
), a loop is attempted to be detected. I think there's a bug however, as it seems that the immediate next detection call is skipped (so you've actually got to wait two DETECT_INT
periods after the buffer is full).
If a loop is detected however, the time that the loop occurred is not returned. Instead, the loop end time seems to be shifted forward to the time the loop detector that detected the loop ran.
Here's an example:
Config:
AUTO_DETECT=1
DETECT_ALT=0
DETECT_TIME=10000
DETECT_INT=7000
Song is mod_depth_mod.zip, it has a loop at about T+7s.
Behavior:
At T+21s a loop detected to occur at T+12s. The real loop occurred at T+7s, but when the detector ran the first time at T+7s, a DETECT_TIME
period hadn't passed, and when it ran again at T+14s, I think it's a bug. When it ran a third time at T+21s it only looked back as far as T+1s (I suspect an off-by-one error between the T+12s detection time and the T+1s lookback max). It then saw that T+2s to T+12s was a loop, so it set the loop end time to T+12s.
The result of this behavior is the following limitations:
DETECT_TIME
.
DETECT_TIME
is shorter than the song's actual loop time, no loop will be foundDETECT_TIME
is longer than the song's actual loop time, more than two loops of the real song will need to be played for detection to occur.DETECT_INT
and DETECT_WINDOW
setting than they are actually the first time the song looped.Based on all this, I can't really come up with a way to configure the loop detector such that it will find the earliest possible time a song loops, even for songs I know have a loop within a fixed time bound. The only reasonable use I can come up with for the loop detector as-is is as a heuristic way to stop a relatively short looping song from looping so many times it gets annoying (which, not-so-coincidentally, also seems to be the intended use of it).
Hi there, I was looking through the NSFPlay 3.0 Roadmap (#7) and would love to try to help with the Mac/Linux port line items.
Right now I have just one question that could help guide the process - what version of MSVC do you currently target/support? And for 3.0, do you plan on changing the minimum supported MSVC version? I'll try and keep changes compatible.
When playing the song Aquarius by Tappy when the song loops at 1:30 I get a strange high pitched chirping noise not present in the linked video.
I have isolated the different channels and concluded that the sound comes from channel 5 of the VRC7
Attached below is the NSF file.
Entry069.zip
I use your nsfplay quite a lot through wine on linux. I think it would be great to run natively. I'm be willing to try porting to QT so gui is cross platform, and maybe use port audio or some other cross platform audio api. I think then it would also hopefully work on Mac or any other OS, including possibly android (which latest QT supports), if done correctly.
NSFPlay 2.6 will likely be the last version 2 release. NSFPlay 3.0 will be a huge rewrite to address many architectural problems due to the program's age. Cross platform support and performance improvement is the biggest goal here, but also trying to make future maintenance easier.
Work will be done in the nsfplay3 branch: nsplay3
Other stuff that was on 2.5's wishlist:
Visualizer thoughts:
Hi Brad.
Thank you for the lovely software.
I have made .nsf songs longer than 5m:05s before.
Would it be possible for you could make the time of the song unlimited?
The current license text in the readme isn't one of the "standard" licenses, I thought I'd suggest adopting one of the well-known licenses - here's a list of common ones, and a list of even more
I think the BSD Zero Clause license is closest to what's currently in the readme file, or maybe the Unlicense. If you want attribution, MIT is also pretty close.
The main benefit is making decisions easier for other projects - like certain Linux distros get picky about the licenses attached to software. If they can't quickly classify it, they probably just won't package it.
Have to restart a track to get this setting to apply? Otherwise uses the default patch set on first load.
(Pardon my formatting in this request as I did not see a template)
Feature request: A toggle for stopping playback at the end of the track.
Current behavior: At the end of a track, after the set number of loops, the next track is played.
I did not see any other requests, open or closed, for such a feature.
In j0CC-FamiTracker, the user can perform a trick widely used in current day AY music: The envelope half volume trick. By setting the tone registers to ultrasonic levels, the user is able to effectively "halve" the volume of the envelope. j0CC emulates this fine, as do Atari ST and ZX Spectrum emulators. However, it seems that NSFPlay doesn't support this trick, instead it just silences itself in an awkward manner. Issue #7 seems to reference this, albeit under PWM Envelope Volume Control (which makes little sense, since the 5B/AY/YM don't support PWM by default, although it can produce similar effects by mixing tone with envelope).
I usually use NSFPlay to export the channel wav audio files for my oscilloscope videos, but there is one thing that bothers me. I have to go into the channel mask settings and solo a channel, then export the wav file for it. And I have to do this for all other channels + exporting the wav with all the channels at once. This can really be a hassle if one song uses, let's say 8 channels. I know I might be complaining for no reason, but this is basically an issue and request. Can it be added to the next NSFPlay version?
Dumb appveyor deleted the latest preview version like a year ago. Yeah, I could just compile it, but
Hi Brad.
Mat from FamiStudio here.
I'm adding MMC5 support and NSFPlay seems to be the only one creating a loud buzz when playing my NSF. I validated with Mesen and NotSoFatso and both play very clearly. Not sure if its my fault of not. Has anyone reported such issue in the past?
Thanks.
-Mat
Basically what the title says. Would it be possible to add a feature that automatically renders all channels separately for a file, like what OpenMPT has?
The following is a list of planned changes I want to finish before the stable release of 2.5:
How come there is a present waveform offset when NSFPlay plays an NSF or exports a WAV file? Upon opening or recording in Audacity, the waveform out of the NSF is very off-centered why is that?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.