FamiTone - music player (WIP)

Discuss NSF files, FamiTracker, MML tools, or anything else related to NES music.

Moderator: Moderators

Locked
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

FamiTone - music player (WIP)

Post by Shiru »

[Old topic; discussion continues here]


This is a continuation of General music and sound solution thread, started by me about two weeks ago. I know very well that if you want something, one of the best ways is to do it yourself, so of course I've started work on my custom solution too, which I want to release to the public.

This is WIP of my custom solution named FamiTone (the name suggested by Memblers). This is not finished, currently it only plays music, without sound effects. It has no DPCM as well, because currently there is no export of DPCM data in FamTracker.

So, what we have:

- Plain 2A03, very limited capabilites, enough to make some game/demo music, however.
- Easy way to make music. You just use FamiTracker following certain limitations, then you use a text exporter plug-in, then a converter, and get an assembly file with data you can use. It is not very comfortable, but currently needed to simplify testing. In future exporter and converter could be merged.
- The player hopefully fast. I haven't compared it with anything, and I'm absolutely not good in 6502 code optimization (so far I've made like ~1500 lines of 6502 code total), but it is very short and simple.
- The code currently NESASM only.
- The code is free to use for any purposes, credit/donate/whatever optional, not obligatory.
- The player uses 7 bytes in zero page and 127 bytes in a RAM page.
- Music data format and converter aren't the most optimal ever, improvements are possible.

Now about limitations:

- Notes C-1..B-5 and Note Cut
- Only Volume, Arpeggio and Pitch envelopes (no Pitch for noise channel), loops are supported
- Pitch envelope accumulate the offset only at conversion time, thus it can't go further -64..63 and can't accumulate the offset with loop
- Only first step of Duty envelope for pulse and noise channels
- No volume column
- No effects except Fxx, tempo is not supported (fixed at 150)
- Bxx (for looping without an intro) and D00 (for shorter patterns) at conversion time

Yes, these are very limited features compared to FamiTracker capabilities, however if you want feature-complete player for FT, you have it already with FT itself, more features means more complex and slower code. So this is a tradeoff. You should not worry, though, because this feature set is about the same that some early chip trackers had, and there was a lot of good music made with them.

Also, I've made a demonstration song within these limitations, compiled ROM is provided (if you run it in Nintendulator or other good emulator, you'll see jumping color area at the top of the screen, it is the time the player takes). The music compiled into NSF with FamiTracker takes ~9K with player, ~5K without, and compiled for FamiTone takes ~6K with player, and ~5K without (so the player is ~1K, and the data compression rate is about the same as with FT).

Download FamiTone WIP

Thanks goes to Gradualore, without the plugin system in FamiTracker it would take a lot of additional time.


Edit: Here is the original post, player was updated since, so information above is not entirely valid (check the thread for updates). Download link is to the latest WIP, though.
Last edited by Shiru on Fri Dec 24, 2010 9:42 am, edited 5 times in total.
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Post by GradualGames »

This is really cool, it appears better than sound engine I provided as an example. I'm glad to have played a role in enabling this to happen. I intend to get DPCM into the plugin interface very soon, and I will update the related threads when I do.
Last edited by GradualGames on Wed Dec 22, 2010 12:24 pm, edited 1 time in total.
User avatar
neilbaldwin
Posts: 481
Joined: Tue Apr 28, 2009 4:12 am
Contact:

Post by neilbaldwin »

Nice work Shiru.
User avatar
clueless
Posts: 496
Joined: Sun Sep 07, 2008 7:27 am
Location: Seatlle, WA, USA

Post by clueless »

These sound projects are indeed awesome.

I humbly suggest that the playback engine (if possible) be built with "if defs" so that unused features can be disabled at assembly time, making the engine smaller and theoretically, more efficient.
Wave
Posts: 110
Joined: Mon Nov 16, 2009 5:59 am

Post by Wave »

It's a good start towards generic solutions for common problems, I like that :)
When the sound engine has multiple songs + sound effects I'll try to adapt it to NESHLA
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru »

The music engine has no unused features, look in the code - it is just ~500 lines. Sound effects part planned to be mostly independent, with disable/enable at compile time. First I've thought to make sound effects as part of music player (common way), but I think it is not the best approach for multi-channel sound effects (I really want them to be multi-channel).

What exactly you mean under 'multiple songs'? Ability to have few songs with shared instruments set? It is useful thing, but I haven't seen FT multi-song support in the plugin inteface, and without this it will be difficult to implement. So I need Gradualore's help on this.
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Post by GradualGames »

I think I can take you as far as exposing DPCM, but it may be a while before I can make any larger improvements to the plugin system. Maybe I can give somebody remote desktop access to my computer so they can use my copy of visual studio to add more features to the plugin interface, :lol:
Wave
Posts: 110
Joined: Mon Nov 16, 2009 5:59 am

Post by Wave »

Shiru wrote:The music engine has no unused features, look in the code - it is just ~500 lines. Sound effects part planned to be mostly independent, with disable/enable at compile time. First I've thought to make sound effects as part of music player (common way), but I think it is not the best approach for multi-channel sound effects (I really want them to be multi-channel).

What exactly you mean under 'multiple songs'? Ability to have few songs with shared instruments set? It is useful thing, but I haven't seen FT multi-song support in the plugin inteface, and without this it will be difficult to implement. So I need Gradualore's help on this.
Maybe I'm wrong, but channel labels have the same names for all songs, wouldn't that be a problem compiling?
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru »

Well, you can use player with multiple songs without sharing the instruments or other data currently, so it is not absolutely necessary now (would be really needed for a project with a lot of music).

Sound effects are top priority now, DPCM next.

Edit:
Maybe I'm wrong, but channel labels have the same names for all songs, wouldn't that be a problem compiling?
The labels with dot at beginning are local labels in NESASM. They will no overlap if you have few songs, because there is normal label at start of the output file (one you use to tell the player where is the data). As far as I know, there are local labels in all the popular 6502 crossassemblers, although they has different syntax (like @ instead of dot, or 'subroutine' after normal label).
Wave
Posts: 110
Joined: Mon Nov 16, 2009 5:59 am

Post by Wave »

Shiru wrote:Well, you can use player with multiple songs without sharing the instruments or other data currently, so it is not absolutely necessary now (would be really needed for a project with a lot of music).

Sound effects are top priority now, DPCM next.

Edit:
Maybe I'm wrong, but channel labels have the same names for all songs, wouldn't that be a problem compiling?
The labels with dot at beginning are local labels in NESASM. They will no overlap if you have few songs, because there is normal label at start of the output file (one you use to tell the player where is the data). As far as I know, there are local labels in all the popular 6502 crossassemblers, although they has different syntax (like @ instead of dot, or 'subroutine' after normal label).
Aaah, I didn't know, thanks :)
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru »

I've used VirtualNES mod with cycle counting functionality and measured how much CPU time is used by the player on the demonstration song. Don't forget, currently there are no sound effects code and no DPCM channel.

Average is below 2000 cycles, like 1500-1900, and peak is 3866 cycles. The peak grows by jumps while song plays, first it is 3332 and then jumps up in ~three places. So it is ~7-12% for NTSC. Don't know how it compares with other players, because I have no data, would be very interesting to know that.
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Post by GradualGames »

When I ran the demo, the scanline raster effect you're using took up one or two scanlines in your demo in Nestopia, but now I remember that Nestopia obscures some of the upper scanlines. I got around this in my own demo by spinning the CPU before using the monochrome bit trick and running the sound engine, so regardless of whether the upper scanlines are obscured you can still get a good idea how much time the player is using. *edit* I just learned you can adjust this in Nestopia's options, never looked for it before.

FamiTone looks like it is going to be very good and useful when done, much more than I had intended to put in my own sound driver.

*edit*, I just took a screen shot of my demo and looked at the area occupied by the monochrome color, looks like it uses about 13 scanlines for normal music playback, using volume pitch and duty envelopes. so I guess 13/240 is about 5%? I guess that's not bad. It isn't doing as much as FamiTone, though, and that's without a sound effect playing.
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru »

You can measure exact numbers using this VirtuaNES mod build (found on this forum, provided by Memblers). Write something in $401e when music code starts and in $401f when it ends, and you'll get the numbers.

EDIT: Another interesting result I've got with modded NSF plugin is that the demonstration song with FamiTracker's player takes ~2250 average and ~5000 at peak. So my player is faster than FT's one, but not that much.
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru »

Ok, first major update. However, it is not sound effects - Gradualore added DPCM support in the plugin interface, so I've supported it too to test the support. That means there is DPCM channel now, with some limitations, but I don't think they are very limiting. Read 'formats.txt' for details.

I've optimized the code and format a bit, reduced peak time for first demo song by ~500 cycles (if DPCM is switched off), RAM usage reduced as well. The player size is still under 1024 bytes. Had no time to make a DPCM demo song, there is only a pattern, it shows peak time of ~3500 cycles. There are things to optimize, some loops could be unrolled, for example.

The player with DPCM was tested on the real hardware as well, it works.

Download link is the same.

Thanks goes to people from #nesdev who provided some help, answering to my questions, etc. Namely it is kevtris, Gil, B00daW and some others (sorry, log was off, haven't remembered all the names).
Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru »

I just read on this forum that NESASM actually does not use zero page access by default, so all the operations with zero page variables except indirect indexed access were slower than they should. I've changed that in my WIP (not uploaded), it gains ~200 cycles for peak time of DPCM test.
Locked