Pently: a flexible, space-efficient NES music player

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Pently: a flexible, space-efficient NES music player
by on (#160168)
Pently is a music engine for NES designed to combine musical flexibility with space efficiency.

Latest tagged version is 0.05wip11
Bleeding edge features in the GitHub repository

----

There's demand to package the music engine of Concentration Room, Thwaite, Zap Ruder, DABG, RHDE, and Sliding Blaster. But before I go wild adding a pointy-clicky ooey-GUI façade, I need to get what I have into releasable shape. This means I'll need to document it, make example files exercising all features, benchmark it, and announce it. For now, let me know if any of the draft manual is hard to understand.

Later releases may include a translator for an MML-like language, a player with piano roll display, and a tracker.
Re: Pently music player is coming
by on (#160207)
Here's some feedback on your draft manual.


Overview unclear

What language is this library for? What kind of file do Pently commands go into? How do you include the Pently stuff into an NES development project?

After I read the manual, I gather Pently is made of the following pieces, but I don't understand how they all fit together.

    methods
    sound effects table and its entries
    instruments table and its entries
    songs table and its entries
    conductor track and its commands
    patterns and their rows of commands

Maybe you could write an Overview section that describes how these pieces fit together, then have sections for each piece with more details.


Pitch codes

The first place you mention the pitch codes N_C and N_CH, I was confused what they were because they hadn't been explained yet:

Pitch values such that the pattern code N_C produces a C are [...] For example, [...] N_CH produces a middle C and N_C produces the C an octave below it.


Later you mentioned N_BB, and I wasn't sure what the BB represented:

For example, to play a short note for 4 frames followed by a note that is as long as a quarter note minus 4 frames, do GRACE,4,N_CH, N_BB|D_Q4.


You finally imply the pitch code meanings at the end:

The following are all the symbols that are valid in pattern bytecode:
Notes, low octave: N_C, N_CS, N_D, N_DS, N_E, N_F, N_FS, N_G, N_GS, N_A, N_AS, N_B
Notes, high octave: N_CH, N_CSH, N_DH, N_DSH, N_EH, N_FH, N_FSH, N_GH, N_GSH, N_AH, N_ASH, N_BH
Note, top of range: N_CHH
Notes, enharmonic synonyms: N_DB, N_EB, N_GB, N_AB, N_BB, N_DBH, N_EBH, N_GBH, N_ABH, N_BBH


Maybe the pitch codes should be briefly explained somewhere, and any early references should mention or link to where they're explained later.

For example, you might briefly explain how the pitch codes work (maybe insert those four lists of note codes) after this point:

Each note is specified as a pitch relative to the transposition base. Only one note can be played on a channel at once. To stop a note without playing another, use a REST.



Fine meaning

fine [...] This command stops music playback.

In sheet music, the Fine notation means you stop the second time you encounter it. I'm confused if Pently's fine means "stop unconditionally" or "stop the second time".


Noise values

Pitch on a noise channel is $03 (highest) to $0F (lowest) for ordinary noise

I thought there were 16 possible noise values. Are you excluding some on purpose?


Why < and - ?

TRANSPOSE,<-12 moves down an octave

Why do you need both a < and a - here?


Missing symbols

Many of the symbols show up as boxes in my browser (Internet Explorer 11 on Windows 8.1). I can see the sharp and flat symbols, but not the "final barline", segno, and note symbols.
Re: Pently music player is coming
by on (#160217)
Thank you for the feedback. I have updated the manual to address some of the issues you brought up.

Quote:
What language is this library for?

It's written in assembly language but should work with any language that runs on the NES and can link to assembly language subroutines. I've added the names of the essential files.

Quote:
Maybe you could write an Overview section that describes how these pieces fit together

Good idea. I've slipped "The file musicseq.s contains the sound effects, instruments, songs, and patterns that you define." into the API section.

Quote:
The first place you mention the pitch codes N_C and N_CH, I was confused what they were because they hadn't been explained yet: "Pitch values such that the pattern code N_C produces a C are"

That's a forward reference. Do I always need to use the word "below" on every forward reference?

Quote:
Later you mentioned N_BB, and I wasn't sure what the BB represented: "For example, to play a short note for 4 frames followed by a note that is as long as a quarter note minus 4 frames, do GRACE,4,N_CH, N_BB|D_Q4."

Another forward reference. Will change to "For example, to play a short C note for 4 frames followed by a B flat that is as long as a quarter note minus 4 frames, do"

Quote:
You finally imply the pitch code meanings at the end:

I'll explain them explicitly with a table at the start of the "Patterns" section.

Quote:
In sheet music, the Fine notation means you stop the second time you encounter it. I'm confused if Pently's fine means "stop unconditionally" or "stop the second time".

I changed the explanation to lead with what it means: "Stops music playback. Use this at the end of a piece." To make an A-B-A form, you'd repeat the play and wait commands for A and then add a fine command. But in video game music, if you have an A-B-A form, it's usually one that you'll be looping.

Quote:
"Pitch on a noise channel is $03 (highest) to $0F (lowest) for ordinary noise"

I thought there were 16 possible noise values. Are you excluding some on purpose?

I added the explanation: "Values $00 through $02 are also valid, but they sound identical to quieter versions of $03."

Quote:
Why < and - ?

"TRANSPOSE,<-12 moves down an octave"

The - denotes negative, and the < works around ca65's lack of support for signed bytes.

Quote:
Many of the symbols show up as boxes in my browser (Internet Explorer 11 on Windows 8.1). I can see the sharp and flat symbols, but not the "final barline", segno, and note symbols.

Many systems ship with fonts with glyphs for the flat and sharp symbols; fewer support the Musical Symbols block. On my Xubuntu laptop, Pango is pulling those symbols out of the "FreeSerif" font by default, and Character Map says they're also available in "Symbola". And those are pretty much the only real fonts that support them according to Font Support for Unicode Block 'Musical Symbols' on FileFormat.Info. (LastResort doesn't count because it's an OS X internal font that has the same glyph for all characters of each Unicode block.) See also Test for Unicode support in Web browsers: Musical Symbols (U+1D100 – U+1D1FF) by Alan Wood.

On GNU/Linux distributions descended from Debian, the administrator can install the Symbola font using sudo apt-get install ttf-ancient-fonts. As for proprietary operating systems, I'm surprised that they fail to include Musical Symbols fonts despite racing to support new emoji characters in each Unicode version.
Re: Pently music player is coming
by on (#160526)
With no further feedback for nearly a week, I think I have something you can bang on. Let me know if you can get it to do anything.
Re: Pently music player is coming
by on (#160527)
I see you're using ca65. I don't see a .cfg file. Can ld65 run without a .cfg?

Honestly, without a GUI/Tracker, I don't know if I would be able to do much with it. I do like some of the features. But, at current, the learning curve might be too high for most users (or maybe it's just me).


Quote:
No pitch bends or vibrato.


This might be a deal breaker for me.
Re: Pently music player is coming
by on (#160528)
dougeff wrote:
I see you're using ca65. I don't see a .cfg file.

The NES shell is currently using a Zap Ruder-era (fourth quarter 2011) version of my project template, where I hadn't yet renamed the linker configuration file from nes.ini to nrom128.cfg.

Quote:
Honestly, without a GUI/Tracker, I don't know if I would be able to do much with it. I do like some of the features. But, at current, the learning curve might be too high for most users (or maybe it's just me).

Would the learning curve likewise be too steep (X=proficiency, Y=time) for MML or LilyPond? RampantWonder asks the same question.

Quote:
Quote:
No pitch bends or vibrato.

This might be a deal breaker for me.

True, it currently operates on a "fretted" pitch model, where all pitches are quantized to semitones. But it has the equivalent of FamiTracker's arpeggio envelopes, used to create the bass instrument in "stairs". It also has "legato" and "grace note" effects, which can be used for appoggiatura (pitch change at the beginning of a note) such as in "Happy Flappy Crappy".
Re: Pently music player is coming
by on (#160547)
It's obvious you put a lot of work into this. I will try to use it sometime this week.

Quote:
learning curve


Imagine you are new to nesdev, and you just wrote a game, now how do I add music? Famitracker to Famitone2 would be easier. So, they would do that...and get used to it, and probably keep using it. Maybe yours is TONS better than Famitone2, but without an easy to use interface (Famitracker), people may not use it.

If you made a famitracker-text-export to Pently conversion tool, it might help.

Edit: oh, I see you are going to write a tracker...
Quote:
Later releases may include a translator for an MML-like language, a player with piano roll display, and a tracker
Re: Pently music player is coming
by on (#160561)
Quote:
Imagine you are new to nesdev, and you just wrote a game, now how do I add music?

First you have to find someone to compose original music because the royalties for licensing an existing song for use of a cover version in a game would likely exceed what a hobbyist can afford.

Quote:
If you made a famitracker-text-export to Pently conversion tool, it might help.

Say you want to base the Pently authoring model on conversion from FamiTracker. I can see three ways this might play out:
  1. How would you key into FamiTracker a composition using a feature supported by Pently but not FamiTracker? We recently had a topic about such features.
  2. Or is it worth it just to make an exporter that handles those features supported by both Pently and FamiTracker and have composers ignore those features supported by Pently but not FamiTracker, treating Pently as essentially an alternative to FamiTone?
  3. Or did you mean create the basic outline of the composition in FamiTracker, export it from FamiTracker, convert it to a file in Pently's MML-like language, edit the result of conversion to drop FamiTracker-only features and add Pently-only features, and then make all further changes in this file rather than in FamiTracker?
If your answer is "any of the above; it's up to you", what are the pros and cons of each? If it sounds like I'm asking a lot of questions, it's because I want to make something that people are actually likely to use.

Quote:
Edit: oh, I see you are going to write a tracker...

This will take time. Before I get around to making my own tracker, I'll need to define the tracker's native format. I plan on making it a textual format somewhat like MML or LilyPond for two reasons: to bring on board composers familiar with those environments before I finish the tracker, as well as to allow files to be usefully checked into version control with diff support.
Re: Pently music player is coming
by on (#160563)
Re: Famitracker to Pently.
Just getting the notes to convert to Pently syntax would be helpful. But, if you are making a tracker, this might be unnecessary. As long as there is some quick/easy way to input music.

I've never used MML or LilyPond, so I'm not familiar.
Re: Pently music player is coming
by on (#160573)
Apparently, musescore can import/export MIDI and to Lilypond format, and others.

I don't know if that's helpful, but supporting Lilypond syntax might make sense.
Re: Pently music player is coming
by on (#160598)
It seems to me that support for both tracker and MML would be a good thing to have. MML does not seem to me to be a very good format for the native document format of a music tracker (Csound numeric score seems a better format for this purpose, which can even add support to the tracker for some advanced stuff; I have also written a program to compile MML into Csound numeric score format), but with comments to annotate it could be done (another alternative would be for the GUI to use annotated assembly language as its document format).

However, neither of these seem suitable for the way Pently is working using conductor track. A GUI could easily represent it though, by having the patterns and other conductor commands placed into a grid. For text format, a variant kind of MML can be done. You can have "Full MML" which supports ABCDEZ tracks, and "Conductor MML" which is a subset of Full MML that supports only the Z track; a compiler can optimize and convert Full MML into Conductor MML, which is then compiled into assembly language.

Patterns can be defined by lines starting by stuff like !1 and so on (you could do something like !1,2,3 to add the same notes to multiple patterns simultaneously, somewhat like ABC in common MML); the MML compiler then automatically determines the length and base transpose value for each pattern (and base instrument if the pattern begins with an instrument selection), and then in the Z track you might specify (A1B3) to play pattern 1 on the first square wave channel and pattern 3 on the second square wave channel, and then emit a waitRows command (looping or not looping patterns that are too short based on notations in the pattern itself). You could use !A1 to begin a pattern in ostinato mode (not emitting waitRows at this time) and then perhaps !A. to stop ostinato mode. Loops in the Z track can automatically be compressed as necessary (example could be something like [(A1B2C5)(A1B3C5)(A1B4C6)]4).

These are just some idea about it; there can be more possibilities too.
Re: Pently music player is coming
by on (#160625)
So I'm looking through the code for how it handles NTSC/PAL speed and pitch (fortunately it looks trivial to hack in my conception of how the tvSystem var should be). Am I correct to say that the pitch compensation is handled by just playing 1 semitone higher? If so, I guess a 28 cent difference isn't too bad of a trade off for omitting another 160 or 128 byte table.
Re: Pently music player is coming
by on (#160632)
43110 wrote:
So I'm looking through the code for how it handles NTSC/PAL speed and pitch (fortunately it looks trivial to hack in my conception of how the tvSystem var should be).

0: NTSC or RGB; 1: PAL NES; 2: Dendy

Quote:
Am I correct to say that the pitch compensation is handled by just playing 1 semitone higher? If so, I guess a 28 cent difference isn't too bad of a trade off for omitting another 160 or 128 byte table.

Yes. And the pitch is even closer between PAL NES and Dendy: about 12 cents higher on Dendy.

Right now I'm trying to figure out how to implement alpha-to-gray in SDL 2 so I can get rolling on building a GUI framework for the tracker. Reply if you have experience with SDL 2. Or I could try learning GTK+ or Qt instead? If GTK+ or Qt, is there a good way to abstract over audio in Linux, Windows, and OS X?
Re: Pently music player is coming
by on (#160638)
tepples wrote:
If GTK+ or Qt, is there a good way to abstract over audio in Linux, Windows, and OS X?

Qt does come with QAudioOutput built in, although I remember having some trouble with it (can't remember exactly what, but it was something fairly minor). Not sure how good it would be for a latency-sensitive application.
Re: Pently music player is coming
by on (#160731)
The two popular textual music description languages that I'm aware of (MML and LilyPond) express durations (half note, quarter note, eighth note) of successive notes differently. In MML, setting a duration on a note affects only that note: l8 c d e4 f g makes the E a quarter note but all the rest eighth notes. In LilyPond, on the other hand, setting a duration affects all later notes: c8 d e4 f g makes the C and D eighth notes and the rest quarter notes. I'm supporting both behaviors in Pently's music compiler tool, selected with the command durations temporary or durations stick. But I wonder which to make the default.
Re: Pently music player is coming
by on (#160992)
tepples wrote:
I'm supporting both behaviors in Pently's music compiler tool, selected with the command durations temporary or durations stick. But I wonder which to make the default.
If you can change it easily then it isn't really important which is the default, although in my opinion the MML style should be default since some people (including myself) may have used ppMCK to write music (while LilyPond is mainly for sheet music instead).
Re: Pently music player is coming
by on (#161327)
Just as a reality check, would this be any easier to understand?
Code:
# Twinkle test
# by Damian Yerrick

durations stick
notenames english

# Drum kit ########################

sfx noisekick on noise
  pitch 10 0
  volume 10 10 8 6 4 3 2 1

sfx trikick on triangle
  pitch e' c' a f# e
  volume 15 15 15 2 2

sfx closedhihat on noise
  pitch 12
  timbre | 0 1
  volume 5 3 2 1 1

sfx openhihat on noise
  pitch 12
  timbre | 0 1
  volume 6 5 4 4 3 3 3 2 2 2 1 1 1 1 1

drum kick noisekick
drum tkick noisekick trikick
drum clhat closedhihat

# Instruments ######################

instrument fiddle
  timbre 1
  volume 3 6 7 6 6 5
  detached

instrument bass

# twinkle ######################
song twinkle
  time 6/8
  scale 8

  pattern melody with fiddle on pulse2
    orelative
    c'4. c g g a a g2.
    f4. f e e d d c2.
    g4. g f f e e d2.
    g4. g f f e e d2.

  pattern bassline with bass on triangle
    orelative
    c' g e g f c e c
    d f c e g b, c' g
    e g d f c e g d
    e g d f c e g g,

  pattern bassfinal with bass on triangle
    c'2.

  pattern beat
    kick4. clhat kick clhat4 clhat8

  at 1
  tempo 90
  play melody
  play beat
  play bassline

  at 23
  tempo 75

  at 24
  tempo 60
  play bassfinal

  at 24:2
  stop drum

  at 25
  fine


And this is what it's supposed to represent:
Attachment:
twinkle.png
twinkle.png [ 4.57 KiB | Viewed 10123 times ]
Re: Pently music player is coming
by on (#161331)
That looks like OK. It doesn't seem to quite match other formats but I think it is OK anyways; it is good for this music engine.
Re: Pently music player is coming
by on (#161446)
So let's see if you can figure it out.

No significant changes to the player itself, just the tools around it:
  • Experimental music preprocessor with syntax inspired by MML and LilyPond
  • Ported all data conversion tools to Python 3
  • NES shell: Hold Select to speed up by factor of 4
Re: Pently music player is coming
by on (#161561)
I've been meaning to give the new Pently version a try, but I have a lot on my mind this week. I do appreciate that you included Python 3 stuff.
Re: Pently music player is coming
by on (#161754)
After this, I guess my next step is to make a FamiTracker text export to Pently input converter. It won't aim for fidelity as much as just being able to get patterns out. Here are the compromises that I had planned to make:

  • Custom frame rates are used only for tempo processing, not for envelope processing.
  • The first VRC6, MMC5, or Sunsoft 5B channel is mapped to the attack track.
  • The noise and DPCM channels are ignored entirely.
  • The volume column is ignored.
  • Recognized effects include arpeggio (0xx -> ENxx), portamento to target pitch (3xx -> legato on/off), grace note wait before row (Gxx), grace note before rest (Sxx), pattern break (D00), note slide (Qxy or Rxy), song end (C00 -> fine), pattern jump (Bxx -> segno and dal segno), speed (Fxx), and tempo (Fxx). Others are ignored.
  • Portamento to target pitch is reinterpreted as legato when nonzero (301 through 3FF) and not-legato when zero (300).
  • Note slide (Qxy or Rxy) is treated as a slide to a legato note y semitones up or down one row later.
  • Pattern break (Dxx) is always assumed to jump to row 00.
  • It is not recommended to include a lot of tempo/speed changes in a single pattern, as each will expand to a setTempo in the conductor track.

I'm not sure how to handle the noise channel, as FamiTracker allows playing a noise instrument at any pitch, while Pently assumes that all drum instruments use what FT calls "fixed" envelopes. In addition, all drums in Pently have finite length, while FT allows volume envelopes that end on a volume other than 0 (constant sustain). Should I treat each pitch at which a drum instrument is played as a separate drum?

And how would I go about figuring out the time signature in order to set the scale (whether a row means an eighth, sixteenth, or thirty-second note) and calculate measure numbers for at commands?

And is there demand for a way to assemble an NSF or NES program without having to have ca65 and ld65 installed?
Re: Pently music player is coming
by on (#161760)
Quote:
volume column is ignored

Is there no volume control in Pently??

Quote:
Should I treat each pitch at which a drum instrument is played as a separate drum?

Yes.

Quote:
And how would I go about figuring out the time signature

Ask the user to enter input, or command line argument

Quote:
And is there demand for a way to assemble an NSF or NES program without having to have ca65 and ld65 installed?

I'm fine with ca65, but it might limit the # of users.
Re: Pently music player is coming
by on (#161772)
dougeff wrote:
Quote:
volume column is ignored

Is there no volume control in Pently??

Volume envelopes work; just not the volume column.

Quote:
Quote:
Should I treat each pitch at which a drum instrument is played as a separate drum?

Yes.

Hopefully that doesn't run into the 25 drum limit for too many projects.

The key signature (which controls choice of say D# vs. Eb), time signature, and scale may change from song to song or even during a song. The user may end up having to create a skeleton conductor track.
Re: Pently music player is coming
by on (#162431)
Today I included pently into my main project, and this post is some of my initial thoughts and questions.

First of all I probably could of use any of the other freely usable solutions, but I like the conductor/pattern structure of the music as explained, and I also liked the general style of music so far composed so far.

For the functions that use fixed zero page locations (such as "snddatalo = 0" in pently_start_sound) I often assign them to a relocatable label called temp. Witch would be better to require? A 5 byte variable import or externally reserving specifically zero page 0 through 4?

pently_resume_music and pently_stop_music were not found with the linker.

I know this is not the case with every music engine (except maybe nerdtracker2), but i wonder if it's even possible to design the music data to be relocate without having to recompile the network of address pointers. I also wonder if it's easy to construct and play a pattern from RAM, so that there could be an option for the user to create and save some of her own music.
Re: Pently music player is coming
by on (#162436)
43110 wrote:
For the functions that use fixed zero page locations (such as "snddatalo = 0" in pently_start_sound) I often assign them to a relocatable label called temp. Witch would be better to require? A 5 byte variable import or externally reserving specifically zero page 0 through 4?

I have externally reserved $0000-$000F in all my own projects, starting the ZP segment at $0010. But the next release will allow temporary ZP to be relocated.

Quote:
pently_resume_music and pently_stop_music were not found with the linker.

My bad. This will be corrected in the next release. Until I push it out, go down to line 156 or so and change .proc resume_music and .proc stop_music to have the prefixed names.

Quote:
I know this is not the case with every music engine (except maybe nerdtracker2), but i wonder if it's even possible to design the music data to be relocate without having to recompile the network of address pointers.

In NT2, all offsets are ultimately relative to the start of a song, and songs cannot share instruments or patterns. I don't know how instrument or pattern sharing is possible with that sort of relocation.

Quote:
I also wonder if it's easy to construct and play a pattern from RAM, so that there could be an option for the user to create and save some of her own music.

The Sound Effects Editor included in Double Action 53 uses a subset of Pently 0.04 configured to store sound effects' envelope data in RAM. If you want to make something larger in scope, you could set it up such the tables are at fixed positions in WRAM ($6000-$7FFF).
Re: Pently music player is coming
by on (#162548)
Got a new work in progress version:

0.05wip3 (2016-01)
  • Corrected namespacing of pently_stop_music and pently_resume_music (reported by 43110)
  • Allows relocating temporary zero page space (requested by 43110)
  • pentlyas.py: Refactored without "god object"
  • pentlyas.py: Changed syntax for arpeggio effect; the original was based on a misreading of MCK Beginner's Guide
  • pentlyas.py: Optimizes out data of combined envelopes (instrument attacks and sound effects) that are a subsequence of a longer one. This improves handling of the "latebanjo" and "bf98flute2" instruments in the example songs.
Re: Pently music player is coming
by on (#163465)
In this post, Kasumi wrote:
They might say, "I need you to type up every single note/rest in a file in this format." And then you have to do it if that's how their game works and you want to make music for it. Or write your own program to make that easier for yourself. Or make them write a program to make it easier for you.

Other than the obvious conversion from FamiTracker's text export, what other conversion source formats are expected?

Kasumi wrote:
Different engines/converters might make the same song wildly different filesizes, so there's no answer to how big the song could/should be.

Here's a formula to estimate the ROM size of a Pently project:
  • Engine: about 1.5 KiB
  • Sound effect: 4 bytes plus 2 bytes for each frame in the envelope
  • Drum: 2 bytes each
  • Instrument: 3 bytes plus 2 bytes for each frame in the envelope
  • Song: 4 bytes, plus 2 bytes for each tempo change, plus 4 bytes for each play or stop command
  • Pattern: 3 bytes, plus 1 for each note or rest, plus additional bytes for notes with oddball tied durations, plus 2 for each range shift (if the range is wider than 24 semitones), plus 2 for each legato (HOPO) sequence, plus 2 for each instrument change, plus 2 for each arpeggio change

In other news, qix in #nesdev plans to help me learn how to use Git and has put Pently on GitHub.
Re: Pently music player is coming
by on (#167402)
Is it possible to create a comprehensive guide that tells what can and cannot be when someone is composing music for Pently in Famitracker? (Also, I assume this is based on the current official stable build, though the 0CC fork has effects that equate Pently effects a lot better, like grace notes with Txy which is a delayed "note transposition")
I might be composing a soundtrack for a game using Pently, and as a someone who's been a Famitracker user for 6 years, a plethora of different questions pop up even when trying to come up with ideas for music. Can I do X or Y, or Z? What is the Famitracker equivalent to drums in Pently? Even having read the manual and a number of different posts, it's still a bit of a mess in my head, and at this point it might be worth learning how to use the engine as intended with the text/MML-style sort of thing. From what I can tell it's not too much different from making music with an assembly source by using labels, constants and whatever, but even if I end up going that route I'd say it's worth making a guide for people who want to go strictly with Famitracker because if someone is hired to make music in Famitracker, they need to have the rules explained to them thoroughly.
Re: Pently music player is coming
by on (#167405)
I thought he didn't have famitracker to pently support yet.

Also, I thought he was going to develop a pently specific GUI tracker...which would make famitracker support unnecessary.
Re: Pently music player is coming
by on (#167407)
za909 wrote:
Is it possible to create a comprehensive guide that tells what can and cannot be when someone is composing music for Pently in Famitracker?

Not until I actually make the converter. I haven't had much of a chance to do so for two reasons: my recent illness and my having been hired to work on another NES game. Until then, please follow the guidelines described above at "Here are the compromises that I had planned to make" to see which envelopes and effects are most likely to end up ignored. Vibrato is ignored, and portamento-type effects become legato notes.

I apologize for the inconvenience, but paid projects, housework, my finances, and personal physical fitness take precedence over free projects, and I have not yet been hired to work on Pently. I had planned to incorporate Pently into my previous paid project, but the boss instead ended up going with a different playback engine because the project's composer found the "vibrato is ignored" and "portamento-type effects become legato notes" limits unacceptable.

Quote:
What is the Famitracker equivalent to drums in Pently?

I plan to associate each combination of a noise pitch and noise instrument with a separate drum. If there are more than 25 such combinations, I plan to make conversion fail with an error message whose wording I have not yet made final.
Re: Pently music player is coming
by on (#167411)
Oh I see, well of course I would be the last person trying to wave a flag and bitch about why something is not being developed further instantly, I've got a lot of time to do it as well from what I can tell so I don't depend on anything here, if necessary I'll go with the text version. If needed eventually, I'd be happy to find useful similarities between Pently and Famitracker, but like dougeff said, it might be unnecessary.

For example, demanding the use of certain instrument names in Famitracker, so that upon conversion, certain Famitracker instruments can be interpreted as instruments or attack settings.
Re: Pently music player is coming
by on (#173529)
With the release of NovaSquirrel's ft2pently, I have decided to tag commit 1b5311d as Pently 0.05wip4 alongside it. It contains fixes for defects discovered during the development of ft2pently.

  • Project moved to GitHub
  • pentlyas.py: proper argument parsing
  • pentlyas.py: options to read input from stdin, write output to file
  • pentlyas.py: option to generate period table (requested by dougeff)
  • pentlyas.py: writes data sizes in bytes as comments in output (requested by NovaSquirrel)
  • pentlyas.py: turned some internal exceptions into informative error messages (reported by NovaSquirrel).
  • pentlyas.py: treats r and w the same in drum patterns (requested by NovaSquirrel)
  • pentlyas.py: parentheses for slur for LilyPond parity
  • Legato note overwrites uninjected attack's pitch (reported by NovaSquirrel)

By integrating (optional) period table generation into pentlyas, I have made less work for anyone who wants to compile a py2exe version. Reading input from stdin could allow piping ft2pently's output through pentlyas. The data size diagnostic helps a composer see how close a project's score is to its byte budget without having to parse hex numbers out of an ld65 map file.

The legato problem made grace notes more difficult to use with instruments that have longer attack phases, which are more likely to occur in automated conversions. Early versions of Pently (through 0.03) did not support FamiTracker-style envelopes. Instead, notes either sustained at their starting volume or decayed linearly from their starting volume, just like instruments in NerdTracker II. Pently 0.04 added an attack envelope to all pitched instruments as well as a fifth track that inserted attacks into another channel. (The attack track concept was inspired by "Super Mario Land NES-Mix" by Phlumb-Dumb.)

Versions of Pently with attack envelopes also have an arpeggio effect, as well as a legato effect that changes the note on a channel to a different pitch without restarting its envelope. (Legato on a woodwind instrument corresponds to notes that are not tongued, and on a guitar, it represents hammer-ons and pull-offs. In NT2, a note is played legato by not giving it an instrument number. In FT, it's done with the most rapid portamento-to-note, like 3FF.) In previous versions of Pently supporting attack phase (0.04 through 0.05wip3), a note played legato would change the pitch only of the sustain phase. This didn't cause problems with the idiomatic Pently instrument type that has a relatively short attack and an NT2-style decay on the sustain. But because a converted FT instrument's sustain phase (the last step of its volume envelope) cannot decay the way an NT2 instrument can, the attack phase (all steps but the last) has to be made much longer. I originally had legato not overwrite the attack's pitch so as not to interfere with an attack injected by the attack track. But I found a way to distinguish attacks on the channel's own track from injected attacks and modify only the former's pitch, by taking advantage of a different hack I added to pause a channel's arpeggio while an injected attack is playing and restart it once the attack ends.

[This post put me over 2^14.]
Re: Pently music player is coming
by on (#173778)
Code:
vibratoPattern:
  .byte 2, 3, 3, 3, 2, 0, -2, -3, -3, -3, -2, 0


Today I figured out how to make a musically consistent yet computationally efficient vibrato control.

Vibrato adds a sinusoid to the note period. FamiTracker's vibrato is typical of tracker vibrato, which makes the depth constant in period units. This means that for higher pitches, which have lower periods, a given amount of vibrato depth will sound stronger than it does for lower pitches, which have higher periods. But if the change in period for a given vibrato depth setting is proportional to the note's own period, it'll sound the same for low and high pitches.

I've also found that looping the vibrato once every 12 frames (roughly equivalent to FamiTracker effect 45y for depth y) is within normal limits of vibrato on a string or wind instrument.

This, however, leaves portamento as an excuse.
Re: Pently music player is coming
by on (#173784)
When I made a spreadsheet to double-check the pitch table from the wiki (it has a few rounding errors) I think I had some kind of column with how many bits a sweep needed to be, but I forget what condition I put on it.

I came to the obvious-in-retrospect observation that you get one extra bit of period (be it in its simple play-this-note or the amount you need to sweep to get to the next note in N steps) each octave.
Re: Pently music player is coming
by on (#174236)
More progress.

0.05wip5 (2016-06)

  • Vibrato effect
  • Simplified zeroing of channel state during song start
  • Pattern effects use RTS dispatch
  • Corrected namespacing of some APIs
  • Standardized names of feature defines (PENTLY_USE_*) and moved them to pentlyconfig.inc
  • Feature defines to disable vibrato and arpeggio effects, counting rows per beat, attack track, and the attack envelope entirely
  • Split manual into separate documents for concept overview and bytecode description because with pentlyas and ft2pently, few need to deal directly with bytecode
  • Applied MIT License (Expat variant) throughout
Re: Pently music player is coming
by on (#174239)
Quote:
Pattern effects use RTS dispatch


Please expound this statement.
Re: Pently music player is coming
by on (#174242)
A song consists of a set of patterns and a conductor track, which tells which patterns to play when. In pattern bytecode, codes $00 through $D7 produce notes and rests. Codes $D8 through $DE enable or disable effects, and $FF terminates a pattern. The changelog entry states that effect codes, which had previously been processed using a compare/branch tree, are now processed with a jump table that uses the RTS Trick. This makes the code more maintainable, especially as I add effects (like vibrato) or remove them (the .if commands to leave out code related to vibrato or arpeggio).
Re: Pently music player is coming
by on (#174243)
Ok, that clears it up, thanks.
Re: Pently music player is coming
by on (#174349)
tepples wrote:
Applied MIT License (Expat variant) throughout


This just killed support for romhacks, But whatever, Not my problem.

Though it makes things harder for anyone using this for anything but homebrew!
Re: Pently music player is coming
by on (#174350)
Hamtaro126 wrote:
tepples wrote:
Applied MIT License (Expat variant) throughout


This just killed support for romhacks

How so? MIT is not a copyleft. Though Nintendo is known to be anti-copyleft, I seem to remember that some of the Wii system software has notices for BSD and MIT licenses. If you want, I can go try to dig it up for you.
Re: Pently music player is coming
by on (#174371)
tepples wrote:
Hamtaro126 wrote:
tepples wrote:
Applied MIT License (Expat variant) throughout


This just killed support for romhacks

How so? MIT is not a copyleft. Though Nintendo is known to be anti-copyleft, I seem to remember that some of the Wii system software has notices for BSD and MIT licenses. If you want, I can go try to dig it up for you.


Licenses like that only allow you to go so far before you get sued,

I was planning to try to use in a SMB2 hack to enhance music, but since the MIT licence says this:

Code:
The MIT License (MIT)
Copyright (c) <year> <copyright holders>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions


And after that, the problem area is:

Code:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.


Meaning all uses of the music code (at least legally) MUST NOT be included with copyrighted code originally made by Nintendo.

Also, Fair use don't apply here.
Re: Pently music player is coming
by on (#174381)
All it really means, with respect to my copyrights, is that your hack must give me credit where copyright notices usually appear. In this notice, "the Software" refers to Pently, not any other larger work that includes it. For example, if you are using Pently as a plug-in to replace a game's music engine, see answers to "Can I use MIT licence plugins in my commercial web site?".

If you're referring to the practical problem of including the license text in a sub-megabyte executable, I'll have to think about a good way to clarify that including the notice in the manual is acceptable.
Re: Pently music player is coming
by on (#174488)
Oh, That is fine then...
Re: Pently music player is coming
by on (#174568)
Effects I can add next include
  • Portamento to note
  • Detune channel
  • Channel volume (reuse one instrument for forte and piano sections)
  • Master volume (fade out)
  • Envelope looping instead of sustain phase

Which of these would be most valuable to composers?

The problem with just adding them all is RAM use. On average, each effect takes 2 bytes for each channel that it affects: one for the parameter and one for the current state. So that's 8 bytes if an effect affects only actual channels or 10 bytes if it affects a track (including the attack track). If I added all the effects, RAM use would climb back into the range of heavyweight engines even for soundtracks that aren't using a particular effect. I can't just use .res controlled by .ifdef because I'm storing the channels' state somewhat interleaved: four bytes for pulse 1, then four for pulse 2, etc. for correlation with the offsets in APU MMIO space ($4000-$400F).

So I might have to think of a more clever way to pack state variables needed by those features that are enabled, using ca65 macros if I can or Python if I can't.
Re: Pently music player is coming
by on (#174581)
I find volume control to be one of the most important effects. Every channel, preferred.

Also, down the road, ot would be nice if we had a library of instruments, so every musician doesn't have to reinvent the wheel (or piano-ish volume envelope, for example).
Re: Pently music player is coming
by on (#174593)
dougeff wrote:
I find volume control to be one of the most important effects. Every channel, preferred.

Would four levels (1/4, 1/2, 3/4, full) be enough for this? Or is there a musical use case for more?

Quote:
Also, down the road, ot would be nice if we had a library of instruments, so every musician doesn't have to reinvent the wheel (or piano-ish volume envelope, for example).

I agree. Compose with pentlyas and let's build one.
Re: Pently music player is coming
by on (#174597)
How would that correspond to Famitracker's volume column? Something like...

D-F = 100%
9-c = 75%
5-8 = 50%
1-4 = 25%
0 = off

??
Re: Pently music player is coming
by on (#174602)
That'd be about right: 4, 8, B, F.

The thing motivating the limit of 4 levels is that the NES CPU is slow at multiplying, and I don't want to introduce a bunch of 256-entry lookup tables to make it fast. So I plan to make an engineering tradeoff among control, ROM space, and CPU time.
Re: Pently music player is coming
by on (#174603)
Oh good. I feel good about the new, improved Pently. It seems to be filling in the short-comings of other music drivers. I may try to use it in the future, for game development.

I'm not sure how sound effects will work with it, but I really haven't tried yet. It sounds like you've gotten it to work with your own games, so I guess I'll probably figure that out too, when I get to that point.

Edit...

Quote:
NES CPU is slow at multiplying....compromise


Agreed.
Re: Pently music player is coming
by on (#174606)
Sound effects work in almost exactly the same way as the drum track. Each drum is made of one or two sound effects. Or did you mean you haven't had a chance to understand how drums work either?
Re: Pently music player is coming
by on (#174608)
Sorry, I mean game-generated sound events. Collect a coin = ding.
Re: Pently music player is coming
by on (#174612)
In musicseq.pently, make sfx ding on pulse. Then do this from the game code:
Code:
  lda #PE_ding
  jsr pently_start_sound

(The "PE_" part stands for "Pently effect".)

Thread safety caution: Some people like to run the music engine in the NMI handler to avoid audible consequence of slowdown. If you call pently_update_sound in the NMI handler, don't also call Pently API functions in the main thread; that'll cause undefined behavior if it interrupts itself. Instead, add commands to a list in RAM that the NMI handler processes.
Re: Pently music player is coming
by on (#174644)
Is there a any possibility of ''Go to Track #n'' and ''Go to Previously Buffered Track'' effects for pently?

Makes things easier for full-on jingle effects, such as the ''Time Running Out'' jingle in mario games!
Re: Pently music player is coming
by on (#174647)
From the manual's description of pentlyconfig.inc:
If PENTLY_USE_ROW_CALLBACK is enabled, the main program must .export two callback functions: pently_row_callback and pently_dalsegno_callback. These are called before each row is processed and when a dalSegno or fine command is processed, respectively. They can be useful for synchronizing animations to music. For pently_dalsegno_callback, carry is clear at the end of a track or set if looping.

So turn it on and use pently_dalsegno_callback to know when to restart the music.

Do you want more details?
Re: Pently music player is coming
by on (#174650)
tepples wrote:
Do you want more details?


Yes... That would help a lot if more details are added
Re: Pently music player is coming
by on (#174651)
  1. When you start the song for a level, save the song number of the song for the level in a variable.
  2. When you play a temporary song that ends, such as a fanfare that time is about to expire, do not save its song number.
  3. In pentlyconfig.inc, change PENTLY_USE_ROW_CALLBACK = 0 to PENTLY_USE_ROW_CALLBACK = 1.
  4. Create a subroutine in your main program called pently_row_callback that does nothing (that is, immediately executes the rts instruction). This is required because the same configuration option enables both pently_dalsegno_callback and pently_row_callback
  5. Create a subroutine in your main program called pently_dalsegno_callback, and .export this subroutine. If called while carry is clear, this means that the temporary song that ends, such as a fanfare that time is about to expire, has ended. In this case, it should load the song number from variable in step 1, and if it's a valid song number, call pently_play_music.

If this is not enough, then as I wrote in this post:
Please give us more details on your requests for "more details". What parts of the post did you understand, and what parts of the post did you not understand? If you are unable to express what parts of the posts you did and did not understand, I will have to break up the explanation into smaller posts, as if this were a chat room instead of a forum, and ask you whether you understood each part.


Or did you want me to actually write the code for you?
Re: Pently music player is coming
by on (#174680)
So from what i gathered... Follow how the NES Mario engines originally does things:

-Make and use a subroutine for Main to handle the two music buffers, One for main songs, and one for event (effect) songs
-Then store the songs in one of two buffers, Restore back to the main song when the event (effect) song finishes

I think it is good enough from here if so...
Re: Pently music player is coming
by on (#183203)
Many free software licenses require the license to be reproduced in full in all copies, such as the MIT License (Expat variant) currently used for Pently. This is why the NES Classic Edition's front end includes several pages of "Legal Notices". But then it can afford to do so because it has half a gigabyte of NAND flash for the Linux kernel, emulator, and game ROMs. NES games distributed on Game Paks, on the other hand, are in the tens to hundreds of kilobytes and may not have enough space to store a viewer for the entire software license in the binary. So the MIT License (Expat variant) alone might not be the best choice, as it requires the notice to be reproduced in all copies. This has already caused problems for use of Pently in ROM hacks.

There are a few other non-copyleft licenses. Before Pently moved to Git, I had been using a variant of the GNU All-Permissive License changed to limit the credit requirement to source code:

Quote:
Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved in all source code copies. This file is offered as-is, without any warranty.


My project templates and the game RHDE: Furniture Fight still use this license.

If we find it useful to go with a better-known license, I was considering switching to the license of zlib, which similarly requires the full notice only in source code and encourages but does not require credit in object code. This license is also used by the Allegro 5 library, and it carries forth the spirit of the "giftware" license used by Allegro 4.

As the only contributor so far, I have the right to make this license change unilaterally, but I'm opening this to others' input because I'm nice. So comment here or in bug 10.
Re: Pently music player is coming
by on (#186424)
Channel volume control is checked into GitHub.
Re: Pently music player is coming
by on (#197102)
I've proposed five enhancements to how arpeggios can be entered into a score.


Thoughts?
Re: Pently: a flexible, space-efficient NES music player
by on (#197249)
Before working on the arpeggio enhancements, I wanted to get some changes out into a tagged release for those who don't follow me on GitHub.

0.05wip6 (2017-06)

  • Patterns can change channel volume in 25% steps
  • Rest in attack track no longer corrupts pulse 1 arpeggio
  • pentlyconfig.inc: Change engine's code and data segment; disable pulse channel effect pooling and volume comparison; change initial $4011 value
  • Optionally enable sound effects in NSF
  • pentlyas.py: Improved diagnostics emitted by play command. Shows song name; emits one for playing pattern too low.
  • pentlyas.py: Command line option to change output segment
  • pentlyas.py: Clamp vibrato depth to in-range values
  • pentlyas.py: Ignore loops in volume envelopes, presumably pasted from FamiTracker
  • NSF header gets load address from linker configuration
  • Document use of equal temperament
  • Add "Sticks" sample song
Re: Pently: a flexible, space-efficient NES music player
by on (#204828)
Pently 0.05wip7 has three key improvements: portamento, slow arpeggio, and richer ways to express arpeggio.

  • Change to zlib license, which preserves the spirit of the original license but is recognizable by GitHub
  • Add portamento, the single most requested feature
  • paldetect: Interleave with vwait so as not to depend on NMI handler
  • pentlyas.py: Add 8 predefined chord names (M, maj7, dom7, aug, m, m7, dim, dim7)
  • pentlyas.py: Score can define new chord names
  • pentlyas.py: Add single-note arpeggio syntax similar to LilyPond chord mode (thanks to retrodpc for testing)
  • pentlyas.py: Option to name chord by its top note instead of bottom
  • pentlyas.py: First and second inversions of chords
  • Arpeggio can be set to slow or fast (requested by w7n)
  • Add "Arpeggio Waltz" song demonstrating new features
  • Document that object names follow identifier rules
  • makefile: Launch Python tools with py.exe on Windows
Re: Pently: a flexible, space-efficient NES music player
by on (#210888)
Pently 0.05wip8 is expected to be the final release of this calendar year.

  • Reduce BSS (main RAM) footprint when several effects are off
  • Reduce ZP footprint when attack phase is off
  • Compress 0-pitch frames of instrument envelopes
  • pentlyas.py: correctly parse drum names starting with "l"
  • pentlyas.py: option to change overall tuning up or down from A440
  • pentlyas.py: special filename - means standard output
  • pentlyas.py: output lists each song's total size in comments
  • Add "Isometry" song demonstrating attack track more thoroughly
  • makefile: change score filename
  • NES shell: move copyright notice to status bar
  • NES shell: status shows ROM size and current and peak CPU usage
  • NES/NSF executables no longer in Git; will be in releases instead

Is anyone actually using this?
Re: Pently: a flexible, space-efficient NES music player
by on (#210902)
Personally, i mean to get into pently and try it out once i have one or two balls less to juggle, because it looks very promising. Separate attack portions make a lot of sense. Were you planning on a dedicated tracker?
Re: Pently: a flexible, space-efficient NES music player
by on (#210908)
I even prototyped effect symbols for a new tracker, but I too have many balls to juggle.
Re: Pently: a flexible, space-efficient NES music player
by on (#211754)
Based on discussion about conveniences for MML composers a few days ago, I've been adding enhancements to playback in Pently's NES shell (see bug 27).

  • Visualizer: See what notes are playing on the main pitched tracks and what pitch and volume are output on each channel
  • Rehearsal marks: Navigate to sections of a song
  • Track muting: Disable or enable note-ons on a track. This works on tracks, not channels, letting you (for instance) hear a channel's own track separately from drum and attack track overlays that play over it. I've even added the same double-click behavior as FamiTracker: solo if any other channel is unmuted; otherwise unmute all.
  • Resume point: When the ROM starts, jump to a specific row of a song with specific channels muted.

So here's an interim player release built from the head of my tree. Try it and see if my navigation, visualizer, and track muting are in any way helpful. Press A or B to switch between the song list and the visualizer. On the visualizer, use up and down to jump to a section or left and right to move to the mute controls.
Re: Pently: a flexible, space-efficient NES music player
by on (#214039)
Pently 0.05wip9 is out

This release adds several features useful for iterating on part of a piece, such as a visualizer, channel muting, seeking to rehearsal marks, and slow motion playback. It also adds an editor to create sound effects right on your console.

Engine changes

  • PENTLY_USE options to disable music engine entirely, disable 303 portamento, and enable triangle channel duty fix
  • Regression fix: Cancel injection when attack ends (had been broken since slow arps)
  • Cancel grace note when pattern begins
  • Add rehearsal transport control to skip to a row or slow down or pause playback
  • Add variable mix to mute tracks
  • Store current pitch and volume for use by visualizer

pentlyas.py changes

  • Add warning infrastructure
  • v1 through v4 as synonyms for pp through ff
  • p (pause) is synonym for r (rest)
  • q repeats last chord, as in LilyPond
  • Bar check in pattern to warn if not on a measure boundary
  • pickup works in patterns as well
  • Unreachable A in tunings below A=437 is nonfatal
  • mmloctaves off, which future chord syntax will require
  • Set rehearsal marks for navigation in score
  • Set initial playback position and track muting

NES shell changes

  • Add per-song screen with visualizer, rehearsal mark navigation, track muting, tempo, and pause-and-step
  • Import Sound Effects Editor as of 2014-09-10

Manual and other changes

  • Script to estimate pitch of 93-step noise
  • docs: Recalculate PENTLY_USE savings
Re: Pently: a flexible, space-efficient NES music player
by on (#214183)
One suggestion of thing to add could be the octave mode that < and > makes the octave permanent while ' and , makes the octave temporary (a few MML compilers support this).

Also, I do not see any description of the mmloctaves command in the documentation.
Re: Pently: a flexible, space-efficient NES music player
by on (#214221)
zzo38 wrote:
One suggestion of thing to add could be the octave mode that < and > makes the octave permanent while ' and , makes the octave temporary (a few MML compilers support this).

Which compilers, so I can plunder their manuals the way I did the ppMCK guide? Do they allow one of < or > and one of , or ' on the same note?

zzo38 wrote:
Also, I do not see any description of the mmloctaves command in the documentation.
[/quote]
That's because the feature controlled by mmloctaves is not yet implemented. I reserved that keyword a release in advance, intending to use it for LilyPond-style chorded notation for arpeggios, where <a c e>4 means the same as the chordmode-inspired a4:37.
Re: Pently: a flexible, space-efficient NES music player
by on (#214238)
tepples wrote:
zzo38 wrote:
One suggestion of thing to add could be the octave mode that < and > makes the octave permanent while ' and , makes the octave temporary (a few MML compilers support this).

Which compilers, so I can plunder their manuals the way I did the ppMCK guide? Do they allow one of < or > and one of , or ' on the same note?
The only ones I know are AmigaMML and my own improved version of ppMCK (there may be others, but I do not know of any), and yes they do allow both on the same note. (Actually, it doesn't use , for this purpose, but if implementing it in Pently, , is already used to specify octave so it might as well to still do.)

Here is a copy of the relevant parts of the AmigaMML documentation that have to do with octaves (so that you need not download it if you do not want to):
Quote:
c d e f g a b = Play notes by letters. You can include + (sharp) - (flat) ' (high octave) _ (low octave) after each note, to change them by one or twelve semitones each; using multiple symbols (even multiple same ones, such as double-sharp) is possible. After that, you can include a number to override the note length, and then you can include dots to increase the note length.

o = Set octave. For Amiga mode, range is 0 to 4 (default is 2), although the actual Amiga limit is octave 1 to 3 and some programs might not work with numbers outside of such limit. For Extended mode, the range is 0 to 7 (default is 4).

< > = Make low octave/high octave.
(The o command here is one that all MML compilers I have seen implement (although the description above is for Amiga; the range may differ for NES/Famicom). Pently does not seem to have this, but it probably should be added, which then sets what is considered as "previous note" without actually adding a note. AmigaMML uses _ as the low octave suffix, but Pently uses , instead, which should still be OK; Pently is already difference from MML anyways, so it need not be the same way exactly. Also, maybe this documentation is unclear, but I wrote AmigaMML, so I know that <> is permanent while ' is temporary.)

Quote:
zzo38 wrote:
Also, I do not see any description of the mmloctaves command in the documentation.

That's because the feature controlled by mmloctaves is not yet implemented. I reserved that keyword a release in advance, intending to use it for LilyPond-style chorded notation for arpeggios, where <a c e>4 means the same as the chordmode-inspired a4:37.
Ah, OK.
Re: Pently: a flexible, space-efficient NES music player
by on (#214254)
zzo38 wrote:
The only ones I know are AmigaMML and my own improved version of ppMCK (there may be others, but I do not know of any), and yes they do allow both on the same note. (Actually, it doesn't use , for this purpose, but if implementing it in Pently, , is already used to specify octave so it might as well to still do.)

Yeah, I was just curious if anyone else would use that feature of combining sticky and non-sticky octave changes. Thanks for quoting the manual. I may include it in a new "semirelative" mode.

zzo38 wrote:
o = Set octave. For Amiga mode, range is 0 to 4 (default is 2), although the actual Amiga limit is octave 1 to 3 and some programs might not work with numbers outside of such limit. For Extended mode, the range is 0 to 7 (default is 4).

I am accepting this feature request, with octave numbers interpreted the same way as in NerdTracker II and FamiTracker: o1 means C-1 through B-1, o2 means C-2 through B-2, etc., where NT2 and FT consider middle C to be C-3. Thus o1 would reset the pitch context as if the previous note were F-1, o2 as F-2, o3 as F-3, etc.

EDIT: Added in commit e9d89e0.

zzo38 wrote:
tepples wrote:
I reserved that keyword [mmloctaves] a release in advance, intending to use it for LilyPond-style chorded notation for arpeggios, where <a c e>4 means the same as the chordmode-inspired a4:37.
Ah, OK.

If you're curious, the relevant issue is Create arpeggios from chorded notes (#11).
Re: Pently: a flexible, space-efficient NES music player
by on (#219364)
There is a bug affecting triangle instruments and sound effects with non-final zero values. The fix requires adding 4 bytes of branch over the check for period high mismatch on non-pulse. It has been committed to the repository on MS GitHub and will be included in the next release.
Re: Pently: a flexible, space-efficient NES music player
by on (#224083)
Pently originally grew by adding features slowly over time. And some of them weren't necessarily added in straight-through order, resulting in a few parts whose control flow is a bit spaghetti. I recently completed a code review to produce English pseudocode, which led to a reorganization of parts of the instrument code. In particular, the processing for the sustain phase was moved above the pitch effects arpeggio, vibrato, and portamento, reducing the spaghetti factor and allowing more of what I call "inline tail calls" (a euphemism for fall-throughs). I plan a final release of Pently 5 by the end of this month.

But now I feel like I can no longer seem to keep up with demand for features.

  1. One prospective user decides against it because there's no easy to understand authoring solution that a team of randomly hired chiptune composers can use to collaborate without what amounts to learning a programming language. So I made an MML-inspired score format and have my cousin make a converter from FamiTracker text export. There are things FamiTracker can do that Pently cannot and vice versa.
  2. But that's still not good enough, as another prospective user wants vibrato, volume column, and portamento. So I added those.
  3. But that's still not enough, as now the prospective user wants DPCM so bad he dropped Pently without even telling me.

Let's say I do add DPCM. Will that be enough? Or will developers soon demand support for Famicom expansion audio because they plan to bundle a jumper board for the NES-001 bottom expansion port with every copy of the game?

In order to design a representation of DPCM in Pently that is both space-efficient and musically practical, I have a few questions of people developing NES games that use DPCM in the music:
How many samples are in the soundtrack of your game? More than 25? More than 63? More than 127? And how much space do they total? More than 8K? How many of them are played at different frequencies, vs. played at only one frequency?
Re: Pently: a flexible, space-efficient NES music player
by on (#224085)
I think DPCM would be enough to make people use it. Yes.
Re: Pently: a flexible, space-efficient NES music player
by on (#224087)
DPCM support alone is not enough if the DPCM support does not meet the needs of prospective users. Pently supported pulse 1, pulse 2, triangle, and noise since the first version, but people didn't want to use it because its support for pulse 1, pulse 2, triangle, and noise did not meet needs. This is why I ask what people want in the data model for DPCM, as a byte-for-byte replica of FamiTracker's DPCM instrument model would be space inefficient for a game, but something too limited would be seen as insufficient.
Re: Pently: a flexible, space-efficient NES music player
by on (#224089)
It's tough. With Musetracker playback engine I kind of wanted to throw everything and the kitchen sink in, which resulted in a reasonably performant but not-so-space-efficient engine (and only a few productions ever used it, although I think this was more because people were more used to the FamiTracker UI). In a perfect world the engine would support "everything", but the user would only pay for the features they actually use. But then it becomes quite difficult to design the engine, you'd need some conditional compilation at the very least.

And all this in order to get some users for your library, while getting not much more than a pat on the back in return. It really is a thankless job.
Re: Pently: a flexible, space-efficient NES music player
by on (#224091)
You mean like the PENTLY_USE_* flags I have? But seriously, I have no idea about what people want in DPCM in music in games because I don't myself use DPCM in music in games. I guess not everybody looks up to Tim Follin the way I do.
Re: Pently: a flexible, space-efficient NES music player
by on (#224401)
The top four reasons not to use Pently, even at the expense of having an overall shorter soundtrack for a given ROM size:

  1. DPCM
  2. Preferring to compose with linear pitch turned off, and wanting vibrato rate/depth and portamento rate to match FamiTracker exactly
  3. Becoming frustrated with playback differences and not knowing how to ask for help
  4. (Added 08-28) Using a third-party game engine with built-in FamiTone2/4 or GGSound integration but no Pently integration yet

In theory, a converter could compensate for #2 by using smaller vibrato depths and portamento rates for pitches below A-2 and larger ones for pitches above A-2, converting them from units of reciprocal frequency to log frequency. But in practice, it'd have to be a command line option, as 0CC-FamiTracker's text export does not include whether linear pitch was used. I reported this eight months ago.

This still leaves design of DPCM instrument data structures and composer support. Does anybody have test case FTMs/0CCs showing "typical" use of DPCM in a game soundtrack, as opposed to the data-heavy "Sunsoft bass" tracks I commonly see in FamiTracker Discord where people think nothing of using 64K for a 1-song NSF? And how could I encourage composers to keep me in the loop about problems they encounter?


EDIT (Tue 08-28): Add third-party game engine as the fourth reason
Re: Pently: a flexible, space-efficient NES music player
by on (#224403)
Quote:
How many samples are in the soundtrack of your game? More than 25? More than 63? More than 127? And how much space do they total? More than 8K? How many of them are played at different frequencies, vs. played at only one frequency?


Counterquestion: Does the definition of soundtrack include samples that are used mainly/only for sfx here?

Personally i feel more than 8k is greedy. Since you need your samples visible at all times while they're used, i'd try to aim for max 1k or maybe max 2k if it is something special. I'm not every composer though.

Playing at different frequencies is important if you want to conserve space. I feel it is important.
Even drums benefit from being played at different frequencies.

One limitation that both FamiTone and GGsound puts on DPCM is.. well it's two different takes.
GGsound - only one instrument can be a dpcm instrument in addition to its non-dpcm duty (iirc)
FamiTone2 - only instrument 00 can be a dpcm instrument in addition to its non-dpcm duty.
Re: Pently: a flexible, space-efficient NES music player
by on (#224404)
FrankenGraphics wrote:
Counterquestion: Does the definition of soundtrack include samples that are used mainly/only for sfx here?

Yes. Pently in fact builds its current triangle+noise drums on top of sound effects. I'll also need to come up with a policy for what interrupts what, and it appears a bit more complex than the "whatever's louder" policy that other channels use.

FrankenGraphics wrote:
Playing at different frequencies is important if you want to conserve space. I feel it is important.
Even drums benefit from being played at different frequencies.

Part of it is planning an efficient representation in sequence data, particularly whether I need to plan for every sample being played at every pitch.
Re: Pently: a flexible, space-efficient NES music player
by on (#224405)
One thing i've wanted to try at some point but don't think i've seen (maybe because FT supports a whopping 256k of sample data, so few might've thought about it) is to use dpcm samples just for quick attack portions in tandem with a square or triangle that takes up the flag of the note where the attack portion ends. The attack portion either needs to go from its complex timbre to a tri/square one, or fade out while the tri/square fades in. Either way it could fit a limited size driver. Sometimes limitations may inspire new(?) styles.

Quote:
Yes.
Then definitely at least "more than 25", i think. 63 sounds like a nice max but again, i wouldn't know the needs of other composers.

Quote:
I'll also need to come up with a policy for what interrupts what
Maybe the sorting order of the samples could be enough to decide priority? It's not perfect but allows for some user agency at build time.


Quote:
Part of it is planning an efficient representation in sequence data, particularly whether I need to plan for every sample being played at every pitch.

My experience is a bit too limited to be making a reliable verdict, but i've found the brightest few frequency settings to be the least useful overall so far.
For nonlooping one-shots, you typically get very short sounds for your sample length, and for "faux waveforms", you get very bright/out of tune sounds.
Re: Pently: a flexible, space-efficient NES music player
by on (#227732)
I have tried to keep Pently's data formats the same from version to version. The only breaking change I can remember is from Pently 3 (Thwaite; Zap Ruder; Double Action Blaster Guys; Sliding Blaster) to Pently 4 (RHDE: Furniture Fight), where I enlarged each instrument from 4 bytes to 5 in order to accommodate attack envelopes. So if you're converting a soundtrack from Pently 3 or earlier, keep this in mind.
Re: Pently: a flexible, space-efficient NES music player
by on (#227850)
I think you could sacrifice some songs to make possible to add more sound effects. I can't imagine any game using 128 songs while I can imagine a game using more than 64 sound effects.
Re: Pently: a flexible, space-efficient NES music player
by on (#227853)
I could expand sound effects and instruments to 255, but that'd require a breaking change to their data format, namely converting them to striped tables. I'd prefer to get anything that doesn't require a breaking change done first so I can finish the Pently 5 series before branching off 6.

Issue #33 filed
Re: Pently: a flexible, space-efficient NES music player
by on (#227872)
I see. Well, I hope it can be done eventually. As of instrument limit, it's pretty tight too. Can anything be done about it?
Re: Pently: a flexible, space-efficient NES music player
by on (#228164)
0.05wip10 (2018-10-28)

Driver
  • Grace note durations no longer reduced by 1 frame
  • Always write period high byte for triangle, fixing problem with zero volume in instruments (#32, reported by NovaSquirrel)
  • Suppress linker warnings for export/import address size mismatch
  • Overhaul names and scope of internal subroutines
  • Rearrange conductor processing based on bytecode order
  • Move sustain phase processing above pitch effects
  • Remove redundant checks for attack injection in pitch effects
  • Fix misbehavior when music and a slowed-down sound effect are played at once
  • C bindings for commonly used functions (requested by adrian09_01)
  • pentlyseq.inc: don't truncate patdef at 7 bits (reported and fixed by NovaSquirrel)
  • mkrammap.py: rename to pentlybss.py to encourage remembering to include it when vendoring Pently

pentlyas.py
  • A score can include other files, such as an instrument set (#29)
  • o0 through o7 to set reference pitch (requested by zzo38)
  • Allow grace notes in drum patterns
  • Playing a pattern with only rests or waits is nonfatal
  • Fix warnings for missing "fine" or "dal segno"
  • Order of objects in the output is explicit, the same order in which they appear in the score (requested by NovaSquirrel)
  • Error if no songs are defined (reported by NovaSquirrel)
  • -A means --period-tuning; --output means -o

Packaging and demo
  • Profiler: don't overreport CPU use if the shell has a lag frame
  • Document how to skip the makefile's default autoplay (#30)
  • makefile: Allow building from an arbitrarily named score by giving the name of the corresponding .nes or .nsf
  • Add pseudocode to aid in porting to non-6502 platforms
  • Add Travis CI build script
  • Sample songs: Include the soundtrack of all games by Damian Yerrick that have appeared in Action 53. These are Concentration Room, Thwaite, Zap Ruder, and RHDE: Furniture Fight.

The "Isometry" track from the demo hits peak CPU usage of over 3800 cycles on a frame with a dal segno and play or stop commands on all five tracks. This may dissuade some users. Is there a need for evening out the CPU usage? And if so, is there a good way to go about this? Because if I can't think of something, I'll end up releasing what I have as the final version of Pently 5.
Re: Pently: a flexible, space-efficient NES music player
by on (#235739)
NSFe support has begun. Proper support for some chunks (auth, tlbl, taut, psfx, time, fade) will require changes to pentlyas that will benefit the ROM version as well.

Related issues:
Re: Pently: a flexible, space-efficient NES music player
by on (#235984)
I'm not going to cover this up. I fixed a 3-year-old bug that jroatch reported before his username here was jroatch. This and other recent fixes look like enough stuff to push out another tagged release this week.

Now I'd like to know what's most important to users:

A. More than 51 instruments and 64 sound effects (with drum components included in sound effects)
B. More than 25 drums
C. ASM6 compatibility
Re: Pently: a flexible, space-efficient NES music player
by on (#235985)
tepples wrote:
C. ASM6 compatibility


As I compile it with asm6?
Re: Pently: a flexible, space-efficient NES music player
by on (#236046)
0.05wip11 fixes a few of the most long-standing issues and adds NSFe metadata support.

Driver
  • Attack track allows grace notes (#35, reported by retrodpc)
  • Channel volume in attack track is ignored rather than clobbering another variable (#35, reported by retrodpc)
  • Option to round row grid to nearest tick on loop, pattern start, or beat (#37)
  • Remove use of other .proc's labels in preparation for ASM6 port

pentlyas.py
  • Fix bugs in fallthrough command and document it (#1, reported by jroatch)
  • Specify tempo based on a musical duration other than a beat (#34)
  • Calculate duration of each song and sound effect (#40)

Packaging and demo
  • NES shell: Take track titles from score (#38)
  • NSF shell: Take NSF title, author, and copyright from score (#38)
  • NSF shell: Write NSFe and NSF2 formats (#39, #41)
  • sfxed: Fix display of rate in slow (rate 10+) effects
  • Move .pently files to audio folder
  • Document workarounds for lack of reentrancy (#2)
  • makefile: Add a recipe to convert a FamiTracker module with ft2pently (#36)

Download: ROM and source zip (below) or GitHub release
Re: Pently: a flexible, space-efficient NES music player
by on (#236888)
Over the course of the last dozen or so commits, I've been tackling what is currently the oldest remaining issue: its being exclusive to ca65 (#9). In the process, I wrote a Python script that translates from ca65 to ASM6. I had to deal with not only macro system limits but also what appear to be outright bugs in how it handles forward references. Today I reached a milestone of being able to play all ten songs. But I still have a lot to learn about standard practices in the ASM6 community, such as how programmers expect libraries to allocate RAM and whether makefiles or shell scripts/batch files are more common.
Re: Pently: a flexible, space-efficient NES music player
by on (#236897)
You can trust most asm6 users to be more at home in windows (and only have win installed for that matter); especally since NESmaker. So batch files would be the better option.
Re: Pently: a flexible, space-efficient NES music player
by on (#237478)
I've made a lot of progress on ASM6 support. It appears to be working now. Is anyone interested in trying an integration with a game?

In other news, I've added a button to change sensitivity and support for detecting a mouse that doesn't support sensitivity selection to the sound effects editor.
Re: Pently: a flexible, space-efficient NES music player
by on (#239203)
I'm having trouble figuring out whether there's even demand for this. Nobody has made me aware of any game that has used Pently other than my own, NovaSquirrel's, and adrian09_01's port of Mega Mountain. Because I underestimated how important quirk-for-quirk fidelity of in-game playback to FamiTracker's preview playback was to composers, it turned out to be inadequate even for three games produced by others who have commissioned me to be the game's lead programmer. All three of them started on Pently but switched to a FamiTone2 descendant during development.

Despite Joe's enthusiasm, I'm even having trouble pitching it as a replacement for GGSound for uses of NESmaker, as my PC doesn't primarily run Windows, and the official solution to NESmaker's incompatibility with Wine and Mono is still to purchase a VMable Windows license for $119.99. But I'll take this to another topic.
Re: Pently music player is coming
by on (#239206)
Quote:
Quote:
Imagine you are new to nesdev, and you just wrote a game, now how do I add music?

First you have to find someone to compose original music because the royalties for licensing an existing song for use of a cover version in a game would likely exceed what a hobbyist can afford.


Alternatively, one can select music which was published before January 1, 1925, which is what many classic-era video game designers did. J.S. Bach's two-part inventions are a nice easy direct fit for the NES sound hardware, as would be e.g. the C major and C minor preludes from the Well Tempered Clavier. Many other works by baroque and classical composers, and many songs by Stephen Collins Foster, Henry Clay Work, and George M. Cohan, could also be good choices with some simple adaptation.