Request for opinions on sound library functionality
Request for opinions on sound library functionality
This is why it's good to ask for feedback.
I really hadn't given any thought to making routines in zsound.lib for manipulating ZSM data (ZSM = zerosound streaming music) on the X16 itself, not as a player but just to work with the data.
For instance, creating a ZSM file on the X16 itself. There is a little bit of complexity involved in the encoding side, so it does make sense that if anyone wanted to generate a ZSM stream from whatever routines they use to generate sound, that it would be nice to have encoder routines available to record that as ZSM. For instance, if someone were to make an on-system tracker, and would like it to be able to export a ZSM of the results, it would be useful to have routines to facilitate that so you don't have to write your own encoder.
- kliepatsch
- Posts: 247
- Joined: Thu Oct 08, 2020 9:54 pm
Request for opinions on sound library functionality
What will be the timing unit of the format? Will it be vsync, or will more precise timing be supported?
Request for opinions on sound library functionality
On 11/19/2021 at 4:28 PM, kliepatsch said:
What will be the timing unit of the format? Will it be vsync, or will more precise timing be supported?
I'm going with "ticks" as the timing format. The file has a 2-byte field in the header for "playback rate" (Hz), which defines how long a "tick" is. Right now, the playmusic: routine in my library is speed agnostic. It would be more aptly named "step_music." It only advances one tick per call, so it can be called at whatever rate and that's what playback speed it produces. I plan to make a new routine and call it playmusic instead. This one will be designed to be called at 60Hz intervals. It will work out how many times to call step_music on this frame, keeping a fixed-point ticks-per-frame tally. If you want to make an arbitrary resolution time source using the VIA or whatever, then that can work - just call step_music directly. There's really not a lot of benefit to making a ZSM of anything higher resolution in the time domain as I see it, but I felt that this would be something useful to have in the spec.
In fact, it was just the other night I was starting to figure out how I'm going to do divide-by-60 in assembly, specifically to make this new routine. I'm thinking I could do it by doing >> 6 and then taking the answer >> 4 and adding that to the value, doing another >> 4 and add, and a final >> 2 with the final >> being a ROR (to load the carry flag) then adding zero to the decimal and integer values to carry in the one.
Basically /60 is / 4 / 15. 15's close to 16, so just divide by 16 and add back 1/15th of the result... which is what the repeated >> 4 does - keep propagating the error down off the least significant bit, and if carry is set, round up.
Request for opinions on sound library functionality
On 11/19/2021 at 4:28 PM, kliepatsch said:
What will be the timing unit of the format? Will it be vsync, or will more precise timing be supported?
I've now implemented the time resolution support in both the library's player and the ZSM generation script. As a test, I generated Sonic The Hedgehog, Green Hill Zone at the VGM-native 44100 just to see how much more CPU-expensive that is. It's pretty steep, roughly 20% of the visible raster time.
My simple player produces a "raster bar" at the top-right corner of the screen.
This is how much raster time is taken up as a minimum when it calls step_music 735 times per frame:
For comparison, when the same tune is re-sampled to 60Hz and only called once per frame, the minimum is actually zero pixels of the raster bar shown... typically one or two raster lines are used except when YM voices re-patch for instrument changes.
Obviously, this "step it 735 times" per frame method is still not as accurate (or CPU-intensive) as it would be to generate IRQs at 44.1KHz, but it demonstrates that the format handles it well.
Also, now that the playback rate support is there, the player can now speed up or slow down the playback in real time.
- kliepatsch
- Posts: 247
- Joined: Thu Oct 08, 2020 9:54 pm
Request for opinions on sound library functionality
That's an interesting result! How did you set up the timing of 44100 Hz? And how is the CPU time being measured?
Request for opinions on sound library functionality
On 11/23/2021 at 5:28 AM, kliepatsch said:
That's an interesting result! How did you set up the timing of 44100 Hz? And how is the CPU time being measured?
SIMPLEPLAYER.PRG draws the CPU bar using a "deluxe" method of the old school C64 trick where you INC $D020 and then DEC $D020 when the routine is finished, creating a "raster color bar" on the border. The player makes this bar by setting L0 to use L1's screen memory area (i.e. switching the display to use L0 instead of L1), creating a second screen memory area at $4000 and clearing it, then drawing the bar at the right edge of the screen from top to bottom. Then L0 is activated and L1 is disabled so nothing looks different on screen.
Then whenever it calls the player, it first unhides L1 and then when the player finishes, it re-hides L1. In order to put the bar at the top of the screen, I used a LINE IRQ on line 0 to trigger the music instead of just using VSYNC, as that would result in most of the activity happening during VBLANK - thus not visible on screen.
As for the timing - zsound's zsmplayer has 4 main routines for playing music: startmusic, playmusic, stopmusic, and stepmusic.
startmusic: Sets up all the pointers and counters and such from the selected tune. (pass it a pointer to where you loaded the ZSM into HIRAM). Among other things, it calculates the ticks/frame value from the tune's playback HZ in the header. In this case, the ZSM header says 44100 Hz. startmusic calculates this as 735 ticks/frame.
stepmusic: processes exactly 1 tick of the music. You can call this directly if you want to accurately play back a tune at some rate other than 60Hz. If that kind of accuracy isn't required, you can just use playmusic.
playmusic: will play back any tune by calling it once per frame. It just uses the ticks/frame value to know how many times to call stepmusic. It keeps residual fractional ticks so if it's 3.5 ticks per frame, then it would call stepmusic 4 times every other frame.
stopmusic - duh.
-
- Posts: 913
- Joined: Tue Apr 28, 2020 2:45 am
Request for opinions on sound library functionality
This is also how Deflemask works when making NTSC YM2151 tracks, making every delay multiples of 735. My VGM conversion code just divides all delay values by 735 to make them 60Hz ticks. If a source VGM was for PAL, it would have delays with multiples of 882, but Deflemask defaults for NTSC as it is intended to create tracks for Sega arcade boards.
Request for opinions on sound library functionality
My VGM-to-ZSM conversion script does this as well. VGMs are natively 44100hz sample rate. Until yesterday, it always just resampled time to 60hz. Since I wanted to make the format support higher resolutions in case it's needed for some reason, I needed to make the reference implementations also support the feature, right? ?
Now my encoder just does 60hz by default, but supports a command line flag -t so you could use -t240 to get 4 ticks per frame in time resolution. It's a shame the emulators don't support VIA 6522 timer IRQs because I'd like to try some of the tunes from City Connection at 44100 "in the lab" because I suspect that the PSG will be more audible.
- kliepatsch
- Posts: 247
- Joined: Thu Oct 08, 2020 9:54 pm
Request for opinions on sound library functionality
Thanks for the clarification. I missed that part
On 11/22/2021 at 11:34 PM, ZeroByte said:
Obviously, this "step it 735 times" per frame method is still not as accurate (or CPU-intensive) as it would be to generate IRQs at 44.1KHz
So you're doing 60 Hz playback with two different methods, one with and one without prior conversion of the music data to 60 Hz. Gotcha ?
Request for opinions on sound library functionality
On 11/23/2021 at 9:08 AM, kliepatsch said:
Thanks for the clarification. I missed that part
So you're doing 60 Hz playback with two different methods, one with and one without prior conversion of the music data to 60 Hz. Gotcha ?
Yep - the main difference is that the "without prior conversion" method allows the on-system player to play the ticks at a smooth rate or just clump them together as required by the application. ?