10/31/2023: Localization News - Dead of the Brain 1!

No, NOT a trick, a Halloween treat! Presenting the Dead of the Brain 1 English patch by David Shadoff for the DEAD last official PC Engine CD game published by NEC before exiting the console biz in 1999! I helped edit/betatest and it's also a game I actually finished in 2023, yaaay! Shubibiman also did a French localization. github.com/dshadoff/DeadoftheBrain
twitter.com/NightWolve/PCENews
Main Menu

MML: What are people's actual complaints with the damn thing

Started by Arkhan Asylum, 11/21/2016, 04:36 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Gredler


OldMan

QuoteAll channels, or any specific channel and any number of them, can be set to DDA mode. Or do you mean from the BIOS psg player?
Yeah, i went and looked it up. All 6 channels can do DDA. Would probably be easiest to hack in on channels 5-6, since there's already support in the player to switch modes (ie, noise mode)

Quote...To hack in sample support, it seems that simply setting the PSG player tick to 1 and have the hook do the down counting and call the PSG player when that expires, for tempo control.
I can sort of see how that might work.
The psg player doesn't really have a 'tick'; each call, from vsync/timer is used to count down values. That's easier to explain (to musicians used to midi) as 'ticks'. Wouldn't you have to run the timer at a high rate (ie, low count) to do that though?

QuoteI'm not sure how much space the ripped player takes up in squirrel package,
~8k for the player. Some more in the library page for the actual driver call. (ie. mapping things in, etc)
Same as bios. And yes, iirc, building a cd project changes how the psg setup stuff/driver is done; in a non-cd project, that code is in the library pages, while building a cd project substitutes the appropriate bios calls. Unless you removed it, the player code would still be compiled in, just never used. (My bad).

QuoteAre people really ignorant of PCE audio stuffs??? Nobody reads the PCM threads I post either?
Yes.
I read them. Sometimes I even sort of understand them. Once in a while, I even catch a glimpse of how they work. Not all of us are that into the actual audio processing/hardware operations. Or have studied it in that much detail.

QuoteUnless Old Man and team get this figured out in time when you need it, hit me up when you guys want to do sample streaming support.
Go for it. I have enough other things to do. (Like getting the player to work with the new Huc. Including timer irq support)
If you get it working, pick an unused bytecode to indicate sample playback, and I'll see about putting it in the mml compiler.
..........................
I figure if you pump out the sample values on hsync (assuming 262 hsync/frame) you could handle 12KHz at 5-bit resolution. Not exactly cd quality, but probably good enough for recognisable speech/sfx.
Also, when you re-sample for pce, are you scaling down and interpolating over time, or what?
I've read  some about it, but mostly have been using sox to do it...

DildoKKKobold

Quote from: TurboXray on 12/09/2016, 08:20 PMJust thinking out loud...

So I was looking over the TIRQ code for BIOS player. To hack in sample support, it seems that simply setting the PSG player tick to 1 and have the hook do the down counting and call the PSG player when that expires, for tempo control. Otherwise, outside the PSG player call - the main TIRQ hook outputs samples to whatever channel DAC.

 Those are just the small details. I'm not sure how much space the ripped player takes up in squirrel package, but I think it would be a better idea to keep using it instead of the built in one of the sys card (I assume it switches and uses that for CD projects - haven't looked that far ahead). That would easily solve how to introduce sample support into MML.

 The CD psg player (bios rom version) can be hacked for the hook that I described, but I'd need to know a few more details of how to optimally incorporate sample support for sound FX (aka not drum kits). Otherwise the unoptimal way would be to just reserve one channel for all sample playback. It's crude, but it should work.
Honestly, this would be ideal for our project. Right now, cabbage built us some SFX in Squirrel/MML. They sound OK, but just reserving one channel for actual sampled SFX would be great, especially if it could be built into HuC. That said, it sounds like the overhead would be incredibly high, unless it was every vsync, which comes with its own issues, as Bonknuts pointed out.

EDIT: Also, what happens if my code has some library that does "soundplay(1)" and that overlaps "soundplay(2)"? Will the library be able to handle that?
AvatarDildoKKKobold.jpg
For a good time, email: kylethomson@gmail.com
Dildos provided free of charge, no need to bring your own! :lol:
DoxPhile .com / chat
IMG

TurboXray

Quote from: TheOldMan on 12/09/2016, 09:51 PM
QuoteAll channels, or any specific channel and any number of them, can be set to DDA mode. Or do you mean from the BIOS psg player?
Yeah, i went and looked it up. All 6 channels can do DDA. Would probably be easiest to hack in on channels 5-6, since there's already support in the player to switch modes (ie, noise mode)

Quote...To hack in sample support, it seems that simply setting the PSG player tick to 1 and have the hook do the down counting and call the PSG player when that expires, for tempo control.
I can sort of see how that might work.
The psg player doesn't really have a 'tick'; each call, from vsync/timer is used to count down values. That's easier to explain (to musicians used to midi) as 'ticks'. Wouldn't you have to run the timer at a high rate (ie, low count) to do that though?
Yup. At full 7khz rate. By tick, I mean the interval of time between calls of the parsing routine (and control routine; envelopes, etc). Since the PSG resolution of a tick, interval, is however many TIMER values are used in the timer divider (written to TIMER interval port), those steps that make up the internal are exactly 1 point at 7khz (6991hz to be exact). When you use the timer unit in this way,  you're really just letting hardware do the down counter division for you. But if you set the timer to 0, and do the down counter yourself - the step resolution is exactly the same. The step resolution is always 1024 cpu cycles, whether it's a hardware counter or soft counter at max frequency.

So if you wanted 108hz tempo, set the TIMER to 6991 khz, set the software down counter to 108 (instead of writing it to the TIMER counter port), and on each TIRQ call decrement it. When it reaches 00, pass control to the PSG player. Otherwise, on each call you can now write a sample to any channel you like.

 Obvious you don't want the PSG player writing other stuff to it, but if the PSG player is writing frequency control while in DDA mode - it won't affect the output of the sample. If you can get the PSG player to play a "sound effect" on that same channel, and not touch the volume after an initial set (because volume reg is the same used to set DDA mode), then you can basically get the PSG player not to intervene on that channel while the sample is being streamed to it.

 You could probably take this one step further, by spying on the PSG player's pointer to a specific channel. And if it can read the byte code for notes, then it can interpret that note as a simple #. Even pull the volume control code value from it.

 Basically Air Zonk does all of this.   


QuoteGo for it. I have enough other things to do. (Like getting the player to work with the new Huc. Including timer irq support)
If you get it working, pick an unused bytecode to indicate sample playback, and I'll see about putting it in the mml compiler.
..........................
I figure if you pump out the sample values on hsync (assuming 262 hsync/frame) you could handle 12KHz at 5-bit resolution. Not exactly cd quality, but probably good enough for recognisable speech/sfx.
Also, when you re-sample for pce, are you scaling down and interpolating over time, or what?
I've read  some about it, but mostly have been using sox to do it...
Some PCM demos I posted do this. It's higher than 12khz though. If you output a sample on every scanline per frame (H-int can be called on every scanline), that's 262 samples per frame or 15.73khz. I kept mine at 15.3khz output because 256 samples per frame allowed for alignment optimization (saved cycles in handling/check bank boundary crossings; it doesn't have to be done per instance of the sample fetch, but rather once per frame). I did 262 interrupts, but skipped playing a sample every so many lines (used a down counter).

 The downside to this method, is that there's a good amount of overhead just to do 262 h-int calls - nothing else. It's ~20% cpu resource just for the setup of the next line. Not bad if you already need to do a scanline interrupt every active display scanline for sinewave or similar effects, but not so great if you don't.

 Here's an example of 7khz vs 14khz: http://www.pcedev.net@ftp.pcedev.net/HuPCMDriver/7khz_vs_14khz.zip
 The 14khz is just the sample code being called twice inside the TIMER routine. Simple to do, but wasteful. I just wanted to see what the different in frequency would sound like. Apparently at this rare level though, bit depth matters more than sample rate.

TurboXray

Quote from: DildoKKKobold on 12/09/2016, 10:15 PMHonestly, this would be ideal for our project. Right now, cabbage built us some SFX in Squirrel/MML. They sound OK, but just reserving one channel for actual sampled SFX would be great, especially if it could be built into HuC. That said, it sounds like the overhead would be incredibly high, unless it was every vsync, which comes with its own issues, as Bonknuts pointed out.
The overhead isn't that high, it's just amount of work to set this up for someone. It would be something custom for you, if you needed it. As far as cpu overhead, you're looking at like something like 6% cpu resource for a single channel stream. That's not too high.

Arkhan Asylum

Quote from: TurboXray on 12/09/2016, 07:21 PMYes. All channels. Are people really ignorant of PCE audio stuffs??? Nobody reads the PCM threads I post either? I thought DDA mode was pretty common knowledge.

 PSG.txt from Magickit docs (I think it's in HuC PCEAS section too). Everything should be correct in that doc, except the LFO scaling part.
Yes, a lot of people are ignorant to a lot of PCE stuff.  We aren't exactly a crowded development community.   There's also always something to be learned.

Also, not a lot of people read documentation all the way through.  Some people read, and then forget due to not practicing what they read, and some of the PCE stuff is just sprawled about in weird places.


I knew all 6 channels could be switched to sample mode, and I'm sure OldMan did at one point, but mostly just mixed it up with the LFO or noise mode, since neither of us have looked at that particular stuff in awhile.   It's two modes we don't really use/talk about, mixed up.  No biggy. 

I don't think either of us has really done anything sound-centric in awhile.   I've been busy making games (Atlantean and Inferno), and he's been inhaling plastic fumes, and playing with the CD card stuff.



Also, I don't know about anyone else, but I tend to find your posts hard to read.  You don't seem to proofread what you post, and it's often formatted in a way that isn't very conducive to easy-reading.

So, we end up with a wall of text that has broken sentences via fragmentation, tense change, idea change, or straight up grammatical errors.   It's kind of effort-y to sit and read sometimes.

I know I've told you this in the past.   

If you're trying to document or explain something, proofreading for accuracy and readability is pretty important.   Formatting is a skill in and of itself.




Now, to some of the stuff going on in the thread: As OldMan said, you can take a sample, convert it to 5 bit values, and break it into 32 byte chunks, and store these as custom waveforms.  I swear I've explained it on here before, and it might be in the manual for Squirrel.  I forget, because I've not looked at in a long time.

Then, you can play a note, change the  wave, keep playing the note, and basically string the sample back together.

You won't get the same quality as DDA mode, but it's doable.  I've played around with it before.

You just make sure to use the same note that you sampled in at.

I am not sure if I still have an example of it.  I was doing it for kick drums and ended up liking the completely PSG based kick drum I made more, so I stopped caring for the time being.

What "hack" from OldMan are you talking about that will produce a hum? 

I've thought about it a few times about how to make the samples an easy-to-add-to-MML piece. 

Notation wise, it should be pretty straight forward, and we'd probably end up writing a converter to produce the text-data that you'd paste into the file for a given sample. 

I have to see what symbols are unused in MML, because we'd be basically extending MML and making it a little less standard possibly.

Maybe have samples as %# to indicate which sample data to use, instead of the @# that is in use for waves.

I'll dig around MSXLand and see what they're used to.  They often don't bother with samples though, since you can do plenty without.   

They've got 3 PSG channels, 9 FM channels, and 5 SCC channels to work with, lol.

Funny thing about MSX is that the SCC is real similar to the PCE, except it uses 8 bit values instead of 5, but doesn't support stereo panning.

I prefer the stereo panning
This "max-level forum psycho" (:lol:) destroyed TWO PC Engine groups in rage: one by Aaron Lambert on Facebook "Because Chris 'Shadowland' Runyon!," then the other by Aaron Nanto "Because Le NightWolve!" Him and PCE Aarons don't have a good track record together... Both times he blamed the Aarons in a "Look-what-you-made-us-do?!" manner, never himself nor his deranged, destructive, toxic turbo troll gang!

TurboXray

Quote from: Psycho Arkhan on 12/09/2016, 11:14 PMYes, a lot of people are ignorant to a lot of PCE stuff.  We aren't exactly a crowded development community.   There's also always something to be learned.

Also, not a lot of people read documentation all the way through.  Some people read, and then forget due to not practicing what they read, and some of the PCE stuff is just sprawled about in weird places.


I knew all 6 channels could be switched to sample mode, and I'm sure OldMan did at one point, but mostly just mixed it up with the LFO or noise mode, since neither of us have looked at that particular stuff in awhile.   It's two modes we don't really use/talk about, mixed up.  No biggy. 

I don't think either of us has really done anything sound-centric in awhile.   I've been busy making games (Atlantean and Inferno), and he's been inhaling plastic fumes, and playing with the CD card stuff.
Well, this kinda of stuff gets talked about on other game forums (not centric to PCE). PCE is kinda known for decent samples, sort of how Genesis is known for crappy samples. It was also on wiki, which people love to take as gospel. It's been part of a lot of sound discussions over the years too (all outside this forum). Did I mention it's on wiki? My point being. With all the "experts" out there that don't even write code for these platforms, I would have figured the homebrew community would at least know the basic; samples are easy to do on PCE; can do it on any channel or all channels. Maybe not the exact details, but at least that much.

I'm not knocking anyone. I'm just surprised.

QuoteAlso, I don't know about anyone else, but I tend to find your posts hard to read.  You don't seem to proofread what you post, and it's often formatted in a way that isn't very conducive to easy-reading.

So, we end up with a wall of text that has broken sentences via fragmentation, tense change, idea change, or straight up grammatical errors.   It's kind of effort-y to sit and read sometimes.
Other than some grammatical errors (I don't proof read and I type it out fairly quick - as I'm thinking through it). I don't have time to put things into an easy to read essay format. Ideas and information tends to get packed into paragraphs. It also requires some level knowledge to make the connections I'm presenting (again, I don't have time to explain redundant information).


QuoteNow, to some of the stuff going on in the thread: As OldMan said, you can take a sample, convert it to 5 bit values, and break it into 32 byte chunks, and store these as custom waveforms.  I swear I've explained it on here before, and it might be in the manual for Squirrel.  I forget, because I've not looked at in a long time.

Then, you can play a note, change the  wave, keep playing the note, and basically string the sample back together.

You won't get the same quality as DDA mode, but it's doable.  I've played around with it before.

You just make sure to use the same note that you sampled in at.

I am not sure if I still have an example of it.  I was doing it for kick drums and ended up liking the completely PSG based kick drum I made more, so I stopped caring for the time being.

What "hack" from OldMan are you talking about that will produce a hum? 
I'm pretty sure I've mentioned this like 5 times already ;_;

You can't fill the 32byte buffer unless you turn the channel "off". Turning the channel off, also has the same effect as setting the volume to zero. When you re-enable the channel, it's the same as setting the volume to max (or whatever volume setting you used before). On all PCEs with the original 6280 (the non A revision), large changes in the volume causes an audible 'pop' on the DAC. There's one for turning off the channel, and one for turning on the channel. The direction of the pop, relative to zero line, is directly related to the change in volume (from no volume to max volume creates a positive side "pop" and max to none creates a negative side "pop"). It's not a small "pop" or click; it's pretty loud in relation to the audio. So if you update the waveform buffer 60times a second, you'll get a 60hz hum. The hum asides, 60x32 = 1.9khz. That's pretty crappy of a playback rate to begin with, but the clicks/pops are the worse part. Bump it up to 120hz with every update, then 3.84khz - still crappy and you up the range of the clicks into a higher the buzz frequency.

 Drumkit type samples are super forgiving of a lot of things, including bit depth, extreme jitter, and other artifacts. In Genesis games, where the jitter is soo bad that the voices have the distinct "genesis" throaty sound to them - the drumkit samples on the same PCM driver don't exhibit these audible artifacts. So maybe that's why you didn't hear it.

 Does that make sense? I used to have pics showing what this looks like (recordings). On any system with an updated 6280A revision cpu, these pops from the volume change are barely there. Only the SuperGrafx, and some models of CoreGrafx I, have this updated revision (later models went back to the original cpu model).

 I mean, If you're just updating the waveform to add "timbre" like effects, at lower than 30hz, that's not sample playback - that's something else. I'm not sure if you're confusing the two. And it'll be more "clickity" than a hum or buzz, simply because the rate is slower.


QuoteI've thought about it a few times about how to make the samples an easy-to-add-to-MML piece. 

Notation wise, it should be pretty straight forward, and we'd probably end up writing a converter to produce the text-data that you'd paste into the file for a given sample. 

I have to see what symbols are unused in MML, because we'd be basically extending MML and making it a little less standard possibly.
Aren't PCE waveforms already none standard for MML? I mean, setting a waveform to a channel? Why not have some sort of "null" type of sample, where all notes for the waveform are interpreted as different samples.

ccovell

To add to this discussion:

If you're working on a project and need a channel free for sampled sound effects, and your target is (Super) CD, use the ADPCM hardware.  It's there, free, high-enough-quality, and costs you no CPU time or CD program RAM space.

I guess some people don't want to read, so try watching the few PCE dev tutorials I have recently put on YouTube, where I cover in breezily low detail the capabilities of the PC-Engine & its sound hardware.  (ie: the things reminded above)   https://www.youtube.com/user/wwwchrismcovellcom/videos

You can play around with waveforms and test the audible "popping" using my PCMgine waveform tool, as there is a function that swaps samples around at a fixed rate to channel 0.  Link: https://www.chrismcovell.com/creations.html


TurboXray

Chris, you should do section on the Pro Wrestling games (three on the PCE) that do waveform corruption. If a channel is playing, and write to the DDA port, the sample will overwrite that playback position in the waveform buffer. These games do this to get a single channel metallic timbre change effect. I always thought it was interesting and underutilized.

 About the whole waveform updating thing, 32byte, while the channel is playing - it does make for some interesting sound FX:

/audio/bloodywolf/BW_test1.mp3
/audio/bloodywolf/BW_test2.mp3
/audio/bloodywolf/BW_test3.mp3

(the low frequency playback of the channel masks the popping).

OldMan

QuoteSo if you wanted 108hz tempo, set the TIMER to 6991 khz, set the software down counter to 108 (instead of writing it to the TIMER counter port), and on each TIRQ call decrement it. When it reaches 00, pass control to the PSG player. Otherwise, on each call you can now write a sample to any channel you like.
I understand the theory (sort of). Here's the problem I have....

I assume setting the TIMER to 6991Khz is meant to lock in a particular clock for the timer.
If I set the down counter to 120 (for 120 beats per minute), I will get timer irqs at the 'clock' frequency. If I decrement the down count, and call the psg driver when the counter hits 0, how do I do 32'nd notes? There are 32 of those per beat, and I only get 1 call.

Now, assume it works (and I think it can, by appropriate choices for the parameters). How do I speed it up? Change the value for the down counter? So i would need a table for the different  tempo/downcounts? Okay, and doable. So it should work.

But now I'm effectively duplicating what the hardware does in software.
And I would still have to send out a sample, regardless of whether the psg driver runs or not, wouldn't I? Otherwise, I'd end up missing samples.

I can see that it should work, but it's not obvious (to me, anyway) how it would be implemented.

Arkhan Asylum

Quote from: TurboXray on 12/10/2016, 12:38 AMWell, this kinda of stuff gets talked about on other game forums (not centric to PCE). PCE is kinda known for decent samples, sort of how Genesis is known for crappy samples. It was also on wiki, which people love to take as gospel. It's been part of a lot of sound discussions over the years too (all outside this forum). Did I mention it's on wiki? My point being. With all the "experts" out there that don't even write code for these platforms, I would have figured the homebrew community would at least know the basic; samples are easy to do on PCE; can do it on any channel or all channels. Maybe not the exact details, but at least that much.

I'm not knocking anyone. I'm just surprised.
Yeah, I don't go to other forums because I don't really need that many technobabble places to go to and watch people ramble alot, lol.   I got enough of that watching C64 people argue about the dumbest shit for hours on end.

The homebrew community doesn't have to be expected to know how to do samples.  Besides, on paper it's always easy.  In practice, it may not always be, as other problems (especially with our toolsets) can arise and create issues when trying to do this with a game.

Because it's all hobbyism, and a game platform, the main focus seems to be on the game part.  Not the audio engineering.


QuoteOther than some grammatical errors (I don't proof read and I type it out fairly quick - as I'm thinking through it). I don't have time to put things into an easy to read essay format. Ideas and information tends to get packed into paragraphs. It also requires some level knowledge to make the connections I'm presenting (again, I don't have time to explain redundant information).
Yeah, I'm just saying, if you proofread and form better paragraphs/phrasing, you might find that your own points you are trying to make will get across better.   I've lost count of how many times I re-read things you've posted and basically have to try and auto-correct it into a sensible sentence.   Sometimes I just scroll on by and give up.

QuoteI'm pretty sure I've mentioned this like 5 times already ;_;
If you did, I missed it because ^^^^^^^^^^^



QuoteYou can't fill the 32byte buffer unless you turn the channel "off". Turning the channel off, also has the same effect as setting the volume to zero. When you re-enable the channel, it's the same as setting the volume to max (or whatever volume setting you used before). On all PCEs with the original 6280 (the non A revision), large changes in the volume causes an audible 'pop' on the DAC. There's one for turning off the channel, and one for turning on the channel. The direction of the pop, relative to zero line, is directly related to the change in volume (from no volume to max volume creates a positive side "pop" and max to none creates a negative side "pop"). It's not a small "pop" or click; it's pretty loud in relation to the audio. So if you update the waveform buffer 60times a second, you'll get a 60hz hum. The hum asides, 60x32 = 1.9khz. That's pretty crappy of a playback rate to begin with, but the clicks/pops are the worse part. Bump it up to 120hz with every update, then 3.84khz - still crappy and you up the range of the clicks into a higher the buzz frequency.

 Drumkit type samples are super forgiving of a lot of things, including bit depth, extreme jitter, and other artifacts. In Genesis games, where the jitter is soo bad that the voices have the distinct "genesis" throaty sound to them - the drumkit samples on the same PCM driver don't exhibit these audible artifacts. So maybe that's why you didn't hear it.

 Does that make sense? I used to have pics showing what this looks like (recordings). On any system with an updated 6280A revision cpu, these pops from the volume change are barely there. Only the SuperGrafx, and some models of CoreGrafx I, have this updated revision (later models went back to the original cpu model).

 I mean, If you're just updating the waveform to add "timbre" like effects, at lower than 30hz, that's not sample playback - that's something else. I'm not sure if you're confusing the two. And it'll be more "clickity" than a hum or buzz, simply because the rate is slower.
I gave a shit exclusively about drums, so this would likely be why I didn't hear anything.   And, as I said, you can achieve a more than great kickdrum without samples, so I stopped screwing around with it for the time being.
 

QuoteAren't PCE waveforms already none standard for MML? I mean, setting a waveform to a channel? Why not have some sort of "null" type of sample, where all notes for the waveform are interpreted as different samples.
the waveforms operate as the instrument being used.  This is completely normal. This is straight out of PC98/MSX MML usage.  You use @# to specify what voice to use for playback. 

What your describing is how you might define some sort of sampling drumkit, and I've already considered that, as it would lend itself well to how percussion is already handled with Squirrel.
This "max-level forum psycho" (:lol:) destroyed TWO PC Engine groups in rage: one by Aaron Lambert on Facebook "Because Chris 'Shadowland' Runyon!," then the other by Aaron Nanto "Because Le NightWolve!" Him and PCE Aarons don't have a good track record together... Both times he blamed the Aarons in a "Look-what-you-made-us-do?!" manner, never himself nor his deranged, destructive, toxic turbo troll gang!

DildoKKKobold

Quote from: Psycho Arkhan on 12/10/2016, 05:19 AMThe homebrew community doesn't have to be expected to know how to do samples.  Besides, on paper it's always easy.  In practice, it may not always be, as other problems (especially with our toolsets) can arise and create issues when trying to do this with a game.

Because it's all hobbyism, and a game platform, the main focus seems to be on the game part.  Not the audio engineering.
I have to agree with Arkhan. My goal in creating a homebrew wasn't to learn the deeper details of the PC Engine hardware. Catastrophy isn't going to be stretching the system to its limits. Hopefully, if and when its released, people will think it is a fun, high quality game for a system the love.

I feel like it gets forgotten that I'm not capable of coding in ASM. Sure, there is plenty of info on the psg... that is totally useless from a HuC perspective. Squirrel makes it stupid-easy to integrate music and SFX into a HuC program. Its just damn hard to make decent sounding SFX in squirrel.

 It depends on what your goal is, is it to encourage more 'less capable' homebrewers to make games? If you don't keep it simple, its not going to get used by people like me.
AvatarDildoKKKobold.jpg
For a good time, email: kylethomson@gmail.com
Dildos provided free of charge, no need to bring your own! :lol:
DoxPhile .com / chat
IMG

TurboXray

Here's an extreme example of using the 32byte waveform ram as a "buffer" on the SGX:5bit audio. The playback is something like 56khz! It uses a 1747hz step TIMER setup, and fills the channel using 32 samples. The cpu resource to drive that is super low. The same file, which I can't find at the moment, on PCE sounds horrible (because of the poping on the DAC - it's a loud constant screech). The above wave was recorded from my SGX.

 Such a rate seems unrealistically high. Overkill. But, at such a high rate you could interleave every other sample from a different stream. Now you have two channels of 5bit, playing at 28khz. This is actually how the Genesis mixes channels - instead of mixing them in the digital domain, it just interleaves them at a right fast rate. And because the FM chip in the Genesis is a single 9bit DAC, the accumulation allows higher than 9bit resolution in the analog domain (9bit+9bit = 10bit, etc). So the same on PCE, two channels at 28khz or PMW of two samples for a single channel of 6bit depth at 28khz (driven at 56khz). Given the SGX's filter range, you could probably extend that to four 5bit channels at 14khz, or two 6bit channels at 14khz.

 Why am I mentioning this? Who cares about the SGX except SGX devs? Because there is a solution on the PCE. Remember how I said the pop on the DAC is in relation to the direction of the volume change? What if you reserved two channels. When you turn off one channel, you turn on another (at the same volume). The two different directional pops will cancel themselves out (simple rule: amplitudes add together). But there is a slight delay, in nano seconds IIRC, as to when channel volumes are processed. So it's possible there would be a super slight-tiny hum (because the spikes on perfectly overlap in the time domain; but the analog filtering on the PCE should lessen this even further). I tested out the cancellation on a real PCE, but I haven't tested it with streaming on the PCE itself. And at a rate of 56khz, two hardware channels can get back two or more channels with interleaving the streaming data.

 This sounds easy, but timing has to be precise. If run off the TIRQ instead of the H-int routine, it's mean super tight code for H-int as not to delay TIRQ by too much. Thankfully, with one channel being off (available for 32byte data update), it's only the turning on of one and off of the other, that actually matters in the time domain. I'd probably even buffer in two extra samples (bytes) - so assume 30 bytes/samples per update (bringing it down to 52khz for the base frequency), and allowing any delay time to be covered by the last two samples (last two of 32).

 Does that make sense? tl;dr - wall of text: you should in theory be able to use 32byte buffer method to play high rate samples on the original PCE without pops on the DAC, and have hardware mix multiple sample streams via high rate interleaving, but it requires using two hardware channels. Btw - some Amiga games/demo do this; the faster models can output up to 56khz, so they interleave sample data to extend the 4 channels into 8 channels.

elmer

Quote from: Gredler on 12/09/2016, 06:52 PMI'll take your question if we can settle for low quality as a compliment, because if you've seen my abilities so far to make this game I think it'd be a given that we have to settle with low quality ;)
On the contrary, I'm really impressed with what you guys have done.  :D

You game has a real charm to it that a lot of professional games don't.  =D>


Quote from: DildoKKKobold on 12/09/2016, 05:50 PMDon't they use the same chip? I'm not sure how the sound chip works, but a sample would have to disrupt the music to play.
Yes, samples use the same PSG chip as the music on the basic PCE.

So you have to drop out music channels (temporarily) in order to play a sample instead.

It's no different to how sound-effects also use the same PSG chip, and how sound-effects cause music channels to drop out (temporarily).

It's all up to the sound driver (aka music driver/System Card Player/Squirrel Player) to deal with the technical details, and for the musician that creates the tunes, and usually the sound effects too, to keep in mind when they're assigning which hardware voices play which parts of a tune or a sound effect.

The problem with the System Card Player (and therefore Squirrel) is that it doesn't support sample playback, and that it would be an ugly hack to try to get it to do so.


Quote from: DildoKKKobold on 12/09/2016, 05:50 PMAlso, I'm not sure how I understand how you'd ever play a sample, since you'd have to recreate it with the various waveforms available on the PC Engine.
Nope, the PSG already supports sample playback ... but it's entirely CPU-driven, and it costs a noticable amount of CPU time.


Quote from: TurboXray on 12/10/2016, 12:38 AMMy point being. With all the "experts" out there that don't even write code for these platforms, I would have figured the homebrew community would at least know the basic; samples are easy to do on PCE; can do it on any channel or all channels. Maybe not the exact details, but at least that much.
From what I can see, it's just not relevent to most homebrew developers here, both because the toolchain and sample code don't exist, and becaue it's just not been *needed* in the few homebrew games that have been developed.


Quote from: ccovell on 12/10/2016, 01:15 AMIf you're working on a project and need a channel free for sampled sound effects, and your target is (Super) CD, use the ADPCM hardware.  It's there, free, high-enough-quality, and costs you no CPU time or CD program RAM space.
Absolutely! The capability just needs to be integrating into the toolchain and sound driver.


Quote from: ccovell on 12/10/2016, 01:15 AMI guess some people don't want to read, so try watching the few PCE dev tutorials I have recently put on YouTube, where I cover in breezily low detail the capabilities of the PC-Engine & its sound hardware.  (ie: the things reminded above)   https://www.youtube.com/user/wwwchrismcovellcom/videos
I absolutely love your disection of different game's usage of the PSG.


Quote from: TheOldMan on 12/10/2016, 03:38 AMI assume setting the TIMER to 6991Khz is meant to lock in a particular clock for the timer.
Yes, the problem that is being discussed is (AFAIK) how to play samples and music at the same time, and how to be able to define certain "instruments" and "effects" as one that play a 6991Hz sample instead of using the PSG's 32-byte waveform.

So the timer would be locked at 6991Hz (it's maximum rate).


Quote from: TheOldMan on 12/10/2016, 03:38 AMIf I set the down counter to 120 (for 120 beats per minute), I will get timer irqs at the 'clock' frequency. If I decrement the down count, and call the psg driver when the counter hits 0, how do I do 32'nd notes? There are 32 of those per beat, and I only get 1 call.
If someone were to implement that kind of scheme, then you'd get as many calls as you like ... it's just a case of defining your tempo as something that's an integer multiple of 1/6991 seconds.

But while you can say that you *need* fine tempo adjustment for some reason ... most of the old games were done without it.

And ... what's the fuss with 1/32 notes (a demi-semi-quaver)?

Doesn't the System Card Player already limit you to 1/16 notes (a semi-quaver)?

From what I can see, it defines time as a multiplier of 60Hz ticks per 1/16 note.

That matches up with the calculations that I did a long time ago ...

BPM in terms of 1/4 note lengths.

TEMPO1          EQU     5                       ;clk note TEMPO CONTROL (180 bpm)
DSQ1            EQU     TEMPO1/2                ;    1/32 DEMI-SEMI-QUAVER
SQ1             EQU     TEMPO1                  ;  5 1/16 SEMI-QUAVER
QV1             EQU     SQ1*2                   ; 10 1/8  QUAVER
DQV1            EQU     QV1+SQ4                 ; 15 3/16 DOTTED QUAVER
CR1             EQU     QV1*2                   ; 20 1/4  CROTCHET
DCR1            EQU     CR1+QV4                 ; 30 3/8  DOTTED CROTCHET
MN1             EQU     CR1*2                   ; 40 1/2  MINIM
DMN1            EQU     MN1+CR4                 ; 60 3/4  DOTTED MINIM
SB1             EQU     MN1*2                   ; 80 1    SEMI-BREVE
DSB1            EQU     SB1+MN4                 ;120 3/2  DOTTED SEMI-BREVE

TEMPO2          EQU     6                       ;clk note TEMPO CONTROL (150 bpm)
DSQ2            EQU     TEMPO2/2                ;  3 1/32 DEMI-SEMI-QUAVER
SQ2             EQU     TEMPO2                  ;  6 1/16 SEMI-QUAVER
QV2             EQU     SQ2*2                   ; 12 1/8  QUAVER
DQV2            EQU     QV2+SQ2                 ; 18 3/16 DOTTED QUAVER
CR2             EQU     QV2*2                   ; 24 1/4  CROTCHET
DCR2            EQU     CR2+QV2                 ; 36 3/8  DOTTED CROTCHET
MN2             EQU     CR2*2                   ; 48 1/2  MINIM
DMN2            EQU     MN2+CR2                 ; 72 3/4  DOTTED MINIM
SB2             EQU     MN2*2                   ; 96 1    SEMI-BREVE
DSB2            EQU     SB2+MN2                 ;144 3/2  DOTTED SEMI-BREVE

TEMPO3          EQU     7                       ;clk note TEMPO CONTROL (128 bpm)
DSQ3            EQU     TEMPO3/2                ;    1/32 DEMI-SEMI-QUAVER
SQ3             EQU     TEMPO3                  ;  7 1/16 SEMI-QUAVER
QV3             EQU     SQ3*2                   ; 14 1/8  QUAVER
DQV3            EQU     QV3+SQ3                 ; 21 3/16 DOTTED QUAVER
CR3             EQU     QV3*2                   ; 28 1/4  CROTCHET
DCR3            EQU     CR3+QV3                 ; 42 3/8  DOTTED CROTCHET
MN3             EQU     CR3*2                   ; 56 1/2  MINIM
DMN3            EQU     MN3+CR3                 ; 84 3/4  DOTTED MINIM
SB3             EQU     MN3*2                   ;112 1    SEMI-BREVE
DSB3            EQU     SB3+MN3                 ;168 3/2  DOTTED SEMI-BREVE

TEMPO4          EQU     8                       ;clk note TEMPO CONTROL (112 bpm)
DSQ4            EQU     TEMPO4/2                ;  4 1/32 DEMI-SEMI-QUAVER
SQ4             EQU     TEMPO4                  ;  8 1/16 SEMI-QUAVER
QV4             EQU     SQ4*2                   ; 16 1/8  QUAVER
DQV4            EQU     QV4+SQ3                 ; 24 3/16 DOTTED QUAVER
CR4             EQU     QV4*2                   ; 32 1/4  CROTCHET
DCR4            EQU     CR4+QV3                 ; 48 3/8  DOTTED CROTCHET
MN4             EQU     CR4*2                   ; 64 1/2  MINIM
DMN4            EQU     MN4+CR3                 ; 96 3/4  DOTTED MINIM
SB4             EQU     MN4*2                   ;128 1    SEMI-BREVE
DSB4            EQU     SB4+MN3                 ;192 3/2  DOTTED SEMI-BREVE


Quote from: TheOldMan on 12/10/2016, 03:38 AMI can see that it should work, but it's not obvious (to me, anyway) how it would be implemented.
??? It's easy-enough with counters and branches ... but it slows down every single timer interrupt by 8 cycles for a decrement-zero-page, branch-if-zero.

That's 928 cycles per frame, 2+ scanlines, just to have a finely-adjustable tempo that is rarely (if ever) needed.

It's certainly possible, but it seems like a very high cost to allow both samples and a finely-adjustable tempo, and I really don't see the point.


Quote from: Psycho Arkhan on 12/10/2016, 05:19 AMthe waveforms operate as the instrument being used.  This is completely normal. This is straight out of PC98/MSX MML usage.  You use @# to specify what voice to use for playback. 

What your describing is how you might define some sort of sampling drumkit, and I've already considered that, as it would lend itself well to how percussion is already handled with Squirrel.
Sure, aren't instruments normally defined as both a waveform and an associated volume envelope?

Defining 7KHz samples as just an extension to the drum kit makes a lot of sense from a "music production" standpoint.


Quote from: TurboXray on 12/10/2016, 03:36 PMThis sounds easy, but timing has to be precise. If run off the TIRQ instead of the H-int routine, it's mean super tight code for H-int as not to delay TIRQ by too much. Thankfully, with one channel being off (available for 32byte data update), it's only the turning on of one and off of the other, that actually matters in the time domain. I'd probably even buffer in two extra samples (bytes) - so assume 30 bytes/samples per update (bringing it down to 52khz for the base frequency), and allowing any delay time to be covered by the last two samples (last two of 32).

 Does that make sense? tl;dr - wall of text: you should in theory be able to use 32byte buffer method to play high rate samples on the original PCE without pops on the DAC, and have hardware mix multiple sample streams via high rate interleaving, but it requires using two hardware channels. Btw - some Amiga games/demo do this; the faster models can output up to 56khz, so they interleave sample data to extend the 4 channels into 8 channels.
It's very clever and nice that that can be done!  =D>

But, practically, I sure wouldn't want to interleave 2 samples together in realtime on the PCE while I'm trying to run a game, and also lose both the individual panning and volume envelopes on each sample.

And "yes" ... I know that you can get the volume envelope capability back with another multiply ... but doing so slows things down again.

Using the technique for a single-channel sample might make some sense, although I'm not sure that a lot of musicians would be happy to lose 2 channels (temporarily) in order to gain the single sample channel.  :-k

TurboXray

Quote from: elmer on 12/10/2016, 07:32 PMBut, practically, I sure wouldn't want to interleave 2 samples together in realtime on the PCE while I'm trying to run a game, and also lose both the individual panning and volume envelopes on each sample.

And "yes" ... I know that you can get the volume envelope capability back with another multiply ... but doing so slows things down again.

Using the technique for a single-channel sample might make some sense, although I'm not sure that a lot of musicians would be happy to lose 2 channels (temporarily) in order to gain the single sample channel.  :-k
Volume can be implemented via a look up table. I would never use multiplication in real time for soft(ware) volume.  I mean it's as simple as ldx $0000 and lda vol_table,x. An extra 5 cycles per sample to handle volume over not using it. I usually implement this as self modifying code, and just adjust the table position in the array on a fame basis because it doesn't need to be done on a per sample basis (volume envelope changes happen on a low frequency basis.. like 60hz or lower). If you mixed 4channels at 5bit depth for 14khz output, that's 1% cpu resource per channel to do software volume on. Yeah, nothing's free - but that's pretty good.

Interleaving two or more streams really isn't any harder than handling a stream independently. It's actually really nice because it means no adding of any samples, and no translation tables to convert it into 10bit output for paired channel playback. I think that's pretty good.

 From what I've seen of PCE games that do use samples, a good 90% don't even use hardware volume control for DDA playback - they leave it fixed (no envelopes). Things like drumkit samples are usually a fixed volume state, as well as sound FX samples. Some Genesis games mix up to four samples for the DAC, and never use any volume control on the individual streams.

 Maybe there's some confusion here in how one would use samples. If you're using it as a musical instrument, with loop points, then I can see the need for volume envelopes. But most of the time, samples are just drumkits, one off sounds such as orchestra hits, and sound FX. Volume rarely plays a role in those types of samples. I mean, it can but it's not needed and isn't a big deal if absent. Yeah, panning goes out the window.. but look at what you gain. You have panning on the rest of the channels anyway, so it's not like you completely lost panning FX. And if you really need volume, eat the 1% overhead per stream. Heh - you'd probably gawk at my 4 channel@8bit 15khz player resource requirement. Everything has trade offs. Just like Arkhan wanting Timer resolution tempo control. If you're willing to accept the performance requirement, then you gain whatever additional ability.

 I guess I should of mentioned that my post with the 32byte buffer thing, wasn't meant as something to add to MML or whatever. It's just a technique. And as Arkhan was exploring with it, it can be used to do some things on the PCE that's above and beyond what any devs were doing back in the day. I was just presenting how the concept could work and a relative example of it working. That is, if taken outside of the PSG bios player.

esteban

Quote from: TurboXray on 12/10/2016, 03:36 PMHere's an extreme example of using the 32byte waveform ram as a "buffer" on the SGX:
Damn. That sounds great.
IMGIMG IMG  |  IMG  |  IMG IMG

OldMan

*** WARNING: Wall of text below. If you're not interested in technical arguements, or have not been avidly following ths thread, you may ignore this post ***

Quote
QuoteQuote from: TheOldMan on Today at 12:38:03 AM

    If I set the down counter to 120 (for 120 beats per minute), I will get timer irqs at the 'clock' frequency. If I decrement the down count, and call the psg driver when the counter hits 0, how do I do 32'nd notes? There are 32 of those per beat, and I only get 1 call.
If someone were to implement that kind of scheme, then you'd get as many calls as you like ... it's just a case of defining your tempo as something that's an integer multiple of 1/6991 seconds.
I can't define the tempo. Tempo is how fast the song plays (not how fast the irq tick is). If a song is at 120 BPM ( a popular tempo),
that means it plays 120 whole notes in 1 minute. Or 20 in 1 second.

I -can- define how  many down counts are used before the psg player is called. So yes, in 1 second I can get as many calls as
needed. But I still only get 1 call per group of counts.
In order to change the *tempo*, I have to change the counter limit, which the psg player does, by changing the timer interval. I understand
it *can* be done, but it's a bit more complicated than just "do this".
How would you deal with interrupts in such a situation? (Remember we are getting 6991 of them every second) There's no guarantee that
an irq won't occur while the player is updating. Do those interrupts count towards the next psg call?
And at 6991 timer irqs / sec, do we even have enough time to handle this? And run a game? At 60 fps?

Those are the things I don't understand about how this would work. (And keep in mind, irq problems are a real thing, as rovers problem shows)

QuoteBut while you can say that you *need* fine tempo adjustment for some reason ... most of the old games were done without it.
You never played a game where the boss attacked faster as you did damage?
Listen closely; the music usually speeds up, too.

QuoteAnd ... what's the fuss with 1/32 notes (a demi-semi-quaver)?
Doesn't the System Card Player already limit you to 1/16 notes (a semi-quaver)?
I'm not sure if the system card limits you or not, but that wasn't the point of the 1/32 note question.
*IF* you are limited to -only- vsync, 1/32nd notes are impossible. They require a fraction of a frame.
But, if you use the timer irq, you can update at  less than 1 frame. That was the point.
So the timer -is- needed. And without using the timer, There's no way to get 1/32 notes.

(And. as an aside, 1/32 notes are possible to play in the player. They just take 1 tick, instead of the 1.5 they should be,
causing them to de-sync. Which is probably why they aren't supported. And how we found the trick below, thanks to
a bug in squirrel during development.)

However, with the timer, we can use the following trick: Write the 32nd notes as 16th notes. Double all the other
note times. And run the song at double the tempo. Sounds exactly the same.
And you can do 64th notes by doubling again. Makes for some smoother arepeggios, and doesn't do too bad
as a slide. (something the psg player is lacking in)

And before anyone asks, you can change the tempo before a measure, double the note length for just that measure,
and then re-set the tempo. Provided you have a fixed tempo (ie, you don't call the psg setTempo() function to speed
the whole song up)

QuoteIt's certainly possible, but it seems like a very high cost to allow both samples and a finely-adjustable tempo, and I really don't see the point....
QuoteThis sounds easy, but timing has to be precise. If run off the TIRQ instead of the H-int routine, it's mean super tight code for H-int as not to delay TIRQ by too much
Which is part of the reason I was asking about running it from HSync.
*IF* it can run off of hsync...
1) you could do a quick sample update  (lda  [samples],x / sta )
2) it would be at a decent rate (15 Khz, right?)
3) It could be hooked in via the user hsync hook.

I'm not at all sure it would work, and would require a channle just for samples. But it's interesting to think about....
I'll give you one more thing to think about, too. The psg player keeps a bit-mapped byte to indicate which channels are in use.
It should be possible (though not necessarily quick) to check the byte and find an available channel :)

QuoteThe question is ... is the System Card Player, and the IRQ handling in both the System Card and HuC smart enough to handle not only timer-followed-by-vblank, but also vblank-follow-by-timer???
For the player, it is. Once the player starts processing, it locks itself out from further calls until it is done.

elmer

Folks, can we all get on the same page with music-theory?  :-k

Tempo is the basic timing for a tune, it says how often a "beat" happens per second.

A "note length" is just a way of specifying relative (and not absolute) timings for events, so a note, a 1/2 note, a 1/4 note, or the wonderful British names, a semibreve, a minim and a crotchet.

These are further modified by having "dotted" notes that adds another fraction of the note to the lengths.

See https://en.wikipedia.org/wiki/Note_value
See https://en.wikipedia.org/wiki/Tempo

The point is ... the note lengths specify time relative to other note lengths, and NOT in terms of absolute fractions of a second.

It is the time-signature and tempo that define the link between the note length and absolute time in beats-per-minute (BPM).

A "beat" is commonly defined as 1/4 note (especially in videogames), but that isn't an absolute rule.

But I'll use that 1/4 note = 1 beat convention for the rest of this.

Once you realize that note length are just a notation for relative time, you can see that changing the tempo (BPM) is just another way of saying that you're changing how long a 1/4 note is.

Here are the common "conventional" timings for running a music-driver on a console/old-computer ...

NTSC

Base Tempo = 5/60s per 1/16th  = 20/60s per 1/4 note  = 180.0 bpm  (60 * 60/20)
Base Tempo = 6/60s per 1/16th  = 24/60s per 1/4 note  = 150.0 bpm  (60 * 60/24)
Base Tempo = 7/60s per 1/16th  = 28/60s per 1/4 note  = 128.6 bpm  (60 * 60/28)
Base Tempo = 8/60s per 1/16th  = 32/60s per 1/4 note  = 112.5 bpm  (60 * 60/32)
Base Tempo = 9/60s per 1/16th  = 36/60s per 1/4 note  = 100.0 bpm  (60 * 60/36)

PAL50

Base Tempo = 4/50s per 1/16th  = 16/50s per 1/4 note  = 187.5 bpm  (60 * 50/16)
Base Tempo = 5/50s per 1/16th  = 20/50s per 1/4 note  = 150.0 bpm  (60 * 50/20)
Base Tempo = 6/50s per 1/16th  = 24/50s per 1/4 note  = 125.0 bpm  (60 * 50/24)
Base Tempo = 7/50s per 1/16th  = 28/50s per 1/4 note  = 107.1 bpm  (60 * 50/28)
Base Tempo = 8/50s per 1/16th  = 32/50s per 1/4 note  =  93.8 bpm  (60 * 50/32)



The table above shows that you can achieve a number of different "tempo" settings and still run your music driver in the vsync interrupt.

It also shows that speeding-up a tune (i.e. in a boss-attack) just involves changing the delay-per-quarter-note.

That's how games used to do it ... not by changing the number of times-per-second that the music driver was called!!!  :roll:

***************************

Now, practically, in videogame music-drivers, the programmer has to make a decision about how to encode the note-lengths.


The simplest choice is just to use the tune's BPM to calculate the length of a note (in terms of 1/60s aka the number of "calls" to the music-driver) when you build the game.

For example, on an NTSC console (i.e. America/Japan and the PC Engine), if your tune is playing back at 128 BPM (which is your closest approximation for 120 BPM), then you'd store the length of a quarter-note as "28", meaning that you call the music-driver 28 times before the next note (see the table above).

That's the fastest-to-process when playing back the music, but it means that you can't easily change the tempo during playback.

Once the timing is baked into the tune data like that, the only way to change the tempo is to change how often the music-driver itself is called per second.

Now, most games do NOT change the tempo during playback, and so that's a common way to store the note-lengths.

The System Card Player can store tune data in this way, and it calls it the "Direct" length mode.

This appears to be the method that Arkhan and TheOldMan have chosen to use for Squirrel, and it's why they can't change the tempo of a song without changing how often the Squirrel Player is called per second.

It is not the only way to encode tune data, and it is not even the only way that the System Card Player supports.


Another way to store the length of a note is to store it in the original terms, for-example the length as a number 1..16 in terms of 1/16th notes, or the number 1..32 in terms of 1/32nd notes.

If you do things this way, then you can trivially change the tempo during playback by changing the length of 1/16th note from being 7/60s (a delay of 7 calls to the music-driver), to 5/60s or 8/60s.

The System Card Player can also store tune data in this way, and it calls it the "Time Base" length mode.

This is how most games work that change the tempo during playback.

This is also effectively how most trackers work, if they allow the musician to set the delay-time for each row/line in the pattern.

If you consider each row/line as the time of 1/32nd note, then you can get all of those 4, 5, 6, 7, etc 1/60s timings just by changing the delay times of even and odd rows/lines.

Deflemask does this, for example, when you to set the "Speed" to 4 & 3 ticks for the even/odd rows, resulting in 4+3=7 1/60s ticks per 1/16th note ... for 112.5 BPM (close-enough to a nominal 120 BPM).

One issue with using the System Card Player in this way is that it only stores notes in multiples of 1/16th note, which means that it cannot play 1/32nd notes without resorting to doubling the tempo and calling the driver twice-as-often (i.e. 120 times-per-second).

That's a limitation of the System Card Player's encoding of the tune data ... trackers don't have the same issue.


The System Card Player supports one one final way of storing the tune data, and that is to store the note length in terms of multiples of 1/64th of a note, then multiplied by 3. It calls this the "Tempo Method" length data. For this to work, the System Card Player *must* be called from a timer interrupt where the driver changes the length of the timer depending upon what BPM tempo you want to play back the music at.

The downside of this is that the more times you call the music-driver per second, the more CPU-time you're throwing away.


Hopefully that's all reasonably clear.  [-o<

elmer

Quote from: TurboXray on 12/11/2016, 02:51 AMSo if the BPM is based on down count of 3 (1/60 ticks), when that expires refill the downcount to 3-1, then on expire back to 3 - and repeat. You'd think this would get you 'warbly' sounds, but it doesn't. It gets you a BPM that's in between a 3 tick and a 2 tick. In MOD or XM files, you can set the tick on every pattern line, and a pattern line is read once the tick down count reaches 0. So it's not uncommon to see something like tick defines as 3,2,3,2,3,2,3,2 going all the way down the pattern - etc. Of course, you could do this on the player side too.
OK, that makes sense, for a while I thought that you were talking about changing the timing every "frame" (i.e. 1/60s or 1/30s)!

Changing it on pattern rows/lines make sense.

As I showed above, that 3 & 2 alternation is there to give 5/60s per 1/16th note -> 180.0 BPM.


Quote from: Psycho Arkhan on 12/11/2016, 03:30 AMAlso, I recall now (and OldMan reminded me), that Squirrel with vsync doesn't support tempo changing because it was a PITA, and the timer mode was not. 

vsync has a fixed tempo, so you must set note durations accordingly.   It kind of sucks, and I forgot about it until all of this came up.
Nope, with the System Card Player, vsync does support changing the tempo. You've just got to encode the note length data in the "Time Base" length mode.

Doing so comes with the limitation that you can't specify 1/32nd notes, but that wasn't seen as a show-stopper problem by the programmer that wrote the driver, or by Hudson apparently.

Now, if your Squirrel compiler doesn't support that mode, then that's your choice.


Quote from: Sunray on 12/11/2016, 05:25 AM60 Hz is always going to be 125 BPM in a tracker, so I would avoid creating modules in other tempos.
As bonknuts said, and my calculations above show ... at 60Hz, it's 128.6 or 112.5 BPM, and not 125.

It's only a fixed tempo if your tracker doesn't let you change the timing for the rows/lines.

If that's the case, then I can only suggest that you use a better tracker.

TurboXray

Quote from: TheOldMan on 12/11/2016, 12:33 AMAnd at 6991 timer irqs / sec, do we even have enough time to handle this? And run a game? At 60 fps?
To play a sample via writing to a single DDA channel, at 6991 calls per second, takes 11% cpu resource. It's 5% if no sample is playing (just down counting).

11% is not a lot when it comes to assembly. It's not exactly free, but unless you're really close to the edge in HuC, it shouldn't break the bank. So 5% no sample playing, 11% while sample playing.


Here's what the code could look like:



TIMER
      stz $1403                           ;5
      BBS0 <in_progres, TIMER_BUSY        ;6
      inc <in_progress                    ;6
      cli
      pha                                 ;3
      BBR0 <DDA_state, TIMER_RETURN       ;8                   
      jmp PlaySample                      ; -2, +4
                                          ;30cycles
TIMER_RETURN

      dec <counter                        ;6
      beq TIMER_RTN                       ;4
                                          ;10cycles     
     
      lda counter_refill                  ; -2,+5
      sta <counter                        ;4

        ;PHP                                ;3
        ;lda PSG_PLAYER                     ;5
        ;pha                                ;3
        ;lda PSG_PLAYER+1                   ;5
        ;pha                                ;3
         
      jsr PSG_PLAYER                      ;7         


TIMER_RTN
      pla                                 ;4
     
TIMER_BUSY
      stz <in_progress                    ;4
  rti                                     ;7
                                          ;14cycles                                         

PlaySample
      tma #$04                            ;4
      pha                                 ;3
      lda <sample_bank                    ;4
      tam #$04                            ;5
      stz $800                            ;5
      lda [sample]                        ;7
      bmi .EOF                            ;2
      sta $806                            ;5
      inc <sample                         ;6
      bcs .msb                            ;2
.out
      pla                                 ;4
      tam #$04                            ;5
      jmp TIMER_RETURN                    ;4
 
                                          ;56 cycles
     
.EOF
      stz <DDA_state
      bra .out

.msb
      lda <sample+1
      inc a
      and #$1f
      ora #$80
      sta <sample+1
      bcc .out
      inc <sample_bank
      bra .out   



QuoteThose are the things I don't understand about how this would work. (And keep in mind, irq problems are a real thing, as rovers problem shows)
His issue sounds like an edge case scenario. That he needs to move his scroll() handling routines sooner up the chain so handle such delays. If you know what scanline number scroll() routine sorts the data and builds the RCR calls, you can work around this. If it's not doing it on the first active scanline, or a few scanlines right before first displayable line, I would change it so that scroll sort routine does this at this point in time.

That's why I said anchor the TIMER unit with a resync on V-int, and use the timer intervals to make something fixed like 120hz or 240hz system. When you can predict where code is going to happen every time, it's easier to deal with. But would require making some serious modification to the PSG player code or make a new engine. But meh - enough with the broken record of the opposition :P


QuoteHowever, with the timer, we can use the following trick: Write the 32nd notes as 16th notes. Double all the other
note times. And run the song at double the tempo. Sounds exactly the same.
That's an old MOD/tracker trick!

PS: I like the wall of text :D


 EDIT: Forgot the CLI in the code ;>_>

TurboXray

Quote from: elmer on 12/11/2016, 12:47 PMFolks, can we all get on the same page with music-theory?  :-k

Tempo is the basic timing for a tune, it says how often a "beat" happens per second.

A "note length" is just a way of specifying relative (and not absolute) timings for events, so a note, a 1/2 note, a 1/4 note, or the wonderful British names, a semibreve, a minim and a crotchet.

These are further modified by having "dotted" notes that adds another fraction of the note to the lengths.

See https://en.wikipedia.org/wiki/Note_value
See https://en.wikipedia.org/wiki/Tempo

The point is ... the note lengths specify time relative to other note lengths, and NOT in terms of absolute fractions of a second.

It is the time-signature and tempo that define the link between the note length and absolute time in beats-per-minute (BPM).

A "beat" is commonly defined as 1/4 note (especially in videogames), but that isn't an absolute rule.

But I'll use that 1/4 note = 1 beat convention for the rest of this.

Once you realize that note length are just a notation for relative time, you can see that changing the tempo (BPM) is just another way of saying that you're changing how long a 1/4 note is.

Here are the common "conventional" timings for running a music-driver on a console/old-computer ...

NTSC

Base Tempo = 5/60s per 1/16th  = 20/60s per 1/4 note  = 180.0 bpm  (60 * 60/20)
Base Tempo = 6/60s per 1/16th  = 24/60s per 1/4 note  = 150.0 bpm  (60 * 60/24)
Base Tempo = 7/60s per 1/16th  = 28/60s per 1/4 note  = 128.6 bpm  (60 * 60/28)
Base Tempo = 8/60s per 1/16th  = 32/60s per 1/4 note  = 112.5 bpm  (60 * 60/32)
Base Tempo = 9/60s per 1/16th  = 36/60s per 1/4 note  = 100.0 bpm  (60 * 60/36)

PAL50

Base Tempo = 4/50s per 1/16th  = 16/50s per 1/4 note  = 187.5 bpm  (60 * 50/16)
Base Tempo = 5/50s per 1/16th  = 20/50s per 1/4 note  = 150.0 bpm  (60 * 50/20)
Base Tempo = 6/50s per 1/16th  = 24/50s per 1/4 note  = 125.0 bpm  (60 * 50/24)
Base Tempo = 7/50s per 1/16th  = 28/50s per 1/4 note  = 107.1 bpm  (60 * 50/28)
Base Tempo = 8/50s per 1/16th  = 32/50s per 1/4 note  =  93.8 bpm  (60 * 50/32)



The table above shows that you can achieve a number of different "tempo" settings and still run your music driver in the vsync interrupt.

It also shows that speeding-up a tune (i.e. in a boss-attack) just involves changing the delay-per-quarter-note.

That's how games used to do it ... not by changing the number of times-per-second that the music driver was called!!!  :roll:

***************************

Now, practically, in videogame music-drivers, the programmer has to make a decision about how to encode the note-lengths.


The simplest choice is just to use the tune's BPM to calculate the length of a note (in terms of 1/60s aka the number of "calls" to the music-driver) when you build the game.

For example, on an NTSC console (i.e. America/Japan and the PC Engine), if your tune is playing back at 128 BPM (which is your closest approximation for 120 BPM), then you'd store the length of a quarter-note as "28", meaning that you call the music-driver 28 times before the next note (see the table above).

That's the fastest-to-process when playing back the music, but it means that you can't easily change the tempo during playback.

Once the timing is baked into the tune data like that, the only way to change the tempo is to change how often the music-driver itself is called per second.

Now, most games do NOT change the tempo during playback, and so that's a common way to store the note-lengths.

The System Card Player can store tune data in this way, and it calls it the "Direct" length mode.

This appears to be the method that Arkhan and TheOldMan have chosen to use for Squirrel, and it's why they can't change the tempo of a song without changing how often the Squirrel Player is called per second.

It is not the only way to encode tune data, and it is not even the only way that the System Card Player supports.


Another way to store the length of a note is to store it in the original terms, for-example the length as a number 1..16 in terms of 1/16th notes, or the number 1..32 in terms of 1/32nd notes.

If you do things this way, then you can trivially change the tempo during playback by changing the length of 1/16th note from being 7/60s (a delay of 7 calls to the music-driver), to 5/60s or 8/60s.

The System Card Player can also store tune data in this way, and it calls it the "Time Base" length mode.

This is how most games work that change the tempo during playback.

This is also effectively how most trackers work, if they allow the musician to set the delay-time for each row/line in the pattern.

If you consider each row/line as the time of 1/32nd note, then you can get all of those 4, 5, 6, 7, etc 1/60s timings just by changing the delay times of even and odd rows/lines.

Deflemask does this, for example, when you to set the "Speed" to 4 & 3 ticks for the even/odd rows, resulting in 4+3=7 1/60s ticks per 1/16th note ... for 112.5 BPM (close-enough to a nominal 120 BPM).

One issue with using the System Card Player in this way is that it only stores notes in multiples of 1/16th note, which means that it cannot play 1/32nd notes without resorting to doubling the tempo and calling the driver twice-as-often (i.e. 120 times-per-second).

That's a limitation of the System Card Player's encoding of the tune data ... trackers don't have the same issue.


The System Card Player supports one one final way of storing the tune data, and that is to store the note length in terms of multiples of 1/64th of a note, then multiplied by 3. It calls this the "Tempo Method" length data. For this to work, the System Card Player *must* be called from a timer interrupt where the driver changes the length of the timer depending upon what BPM tempo you want to play back the music at.

The downside of this is that the more times you call the music-driver per second, the more CPU-time you're throwing away.


Hopefully that's all reasonably clear.  [-o&lt;
Ok. We're on the same page. This is exactly how I know music engines on 60hz to work.

elmer

Quote from: TurboXray on 12/11/2016, 01:19 PMPS: I like the wall of text :D
Me, too ... I certainly write enough of them!  :wink:


Quote from: TheOldMan on 12/11/2016, 12:33 AMI can't define the tempo. Tempo is how fast the song plays (not how fast the irq tick is). If a song is at 120 BPM ( a popular tempo), that means it plays 120 whole notes in 1 minute. Or 20 in 1 second.
See my message above on the basic theory.


Quote from: TheOldMan on 12/11/2016, 12:33 AMI -can- define how  many down counts are used before the psg player is called. So yes, in 1 second I can get as many calls as
needed. But I still only get 1 call per group of counts.
In order to change the *tempo*, I have to change the counter limit, which the psg player does, by changing the timer interval.
See my message above on the basic theory.

Your "problem" as-such is that you're hard-coding the note-length in Squirrel, either as "Direct" mode or as "Tempo" mode (which are basically, from a programming POV, the same thing).

By doing that, then "yes" you need to change the timer interval in order to change the tempo.

That's a design-choice that you guys made with Squirrel ... it's not a limitation of the System Card Player, or a basic limitation of other music-drivers.

So, in "practical" terms, I do see where you're coming from.


Quote from: TheOldMan on 12/11/2016, 12:33 AMHow would you deal with interrupts in such a situation? (Remember we are getting 6991 of them every second) There's no guarantee that
an irq won't occur while the player is updating. Do those interrupts count towards the next psg call?
And at 6991 timer irqs / sec, do we even have enough time to handle this? And run a game? At 60 fps?

Those are the things I don't understand about how this would work. (And keep in mind, irq problems are a real thing, as rovers problem shows)
The whole point of any well-designed interrupt scheme is to keep the interrupt handling predicatable and usually short and fast.

Handling interrupts from within other interrupts just requires a careful design.

Bonknuts gave the basic code for a timer interrupt for handling the 6991Hz sample playback and music-driver calling.

Yes, interrupts need to be counted if you were to run a sound driver from a timer IRQ at the same time as you were outputting samples with the same IRQ.

For example ... take your 120 BPM.

120 BPM, with a beat being 1/4 note, and using the PSG Player's convention of 48 calls per 1/4 note, means that you'd want to call it 96 times per second.

With a 6991Hz timer interrupt, that means that you'd call the PSG Player once every 6991/96 = 73 timer interrupts ... which would give you an actual rate of 119.7 BPM.


Quote from: TheOldMan on 12/11/2016, 12:33 AM*IF* you are limited to -only- vsync, 1/32nd notes are impossible. They require a fraction of a frame. But, if you use the timer irq, you can update at  less than 1 frame. That was the point.
So the timer -is- needed. And without using the timer, There's no way to get 1/32 notes.
You can do then in the System Card Player by using the Direct length mode of encoding the data stream, and setting the time to 3 or 4 ticks at 1/60th and 128 BPM.

But then you lose the ability to change the Tempo, and you'd have to worry keeping track of the overall time.

That's a limitation of the operation of the System Card Player, deflemask is quite happy to do them, taking either 3 or 4 ticks at 128 BPM using a 60Hz update.


Quote from: TheOldMan on 12/11/2016, 12:33 AM(And. as an aside, 1/32 notes are possible to play in the player. They just take 1 tick, instead of the 1.5 they should be,
causing them to de-sync. Which is probably why they aren't supported. And how we found the trick below, thanks to a bug in squirrel during development.)
Sure, call the System Card Player at 120Hz, and suddenly you have a 7/120ths instead of 3.5/60ths.

Computers like integers!


Quote from: TheOldMan on 12/11/2016, 12:33 AMHow would you deal with interrupts in such a situation? (Remember we are getting 6991 of them every second) There's no guarantee that an irq won't occur while the player is updating. Do those interrupts count towards the next psg call?
And at 6991 timer irqs / sec, do we even have enough time to handle this? And run a game? At 60 fps?
Of course another interrupt would occur while the sound driver was doing it's slow processing.

That's fairly easy to handle, and "yes", of course you have to keep counting the timer interrupts while the sound driver is processing.

As for whether there would be enough time, Bonknuts has already said that single-channel 7KHz sample playback takes approx 11% of the CPU cycles.

So there's time ... it's just that even trying to do a countdown like that wastes 928 cycles per frame for the dec-zero-page+branch instructions.


Quote from: TheOldMan on 12/11/2016, 12:33 AMWhich is part of the reason I was asking about running it from HSync.
*IF* it can run off of hsync...
1) you could do a quick sample update  (lda  [samples],x / sta )
2) it would be at a decent rate (15 Khz, right?)
3) It could be hooked in via the user hsync hook.
You could do that, but you've just doubled the CPU cost for those samples, and the hsync processing is slower anyway, which costs even more cycles.


Quote from: TheOldMan on 12/11/2016, 12:33 AM
QuoteThe question is ... is the System Card Player, and the IRQ handling in both the System Card and HuC smart enough to handle not only timer-followed-by-vblank, but also vblank-follow-by-timer???
For the player, it is. Once the player starts processing, it locks itself out from further calls until it is done.
Yes, but that's not the problem that I'm worried about. The problem is "what happens if the vsync interrupt triggers, and then the timer interrupt triggers one scanline later on".

Is the entire vblank interrupt processed with interrupts disabled?

If so, then you're delaying interrupts for a long time, and introducing a delay/error in the sample playback.

If not, then a timer interrupt can occur with a complete call to the sound driver, which would delay the time-critical processing that's going on in the vblank.

It all depends upon just how much stuff is being processed in the vblank interrupt.

OldMan

Elmer:
 Got it. I'm not sure if the mml compiler supports "Time base" mode or not (that's the packed format, iirc). In any case, you would need as assembler call (and knowledge of where the variable is at) to do tempo changes that way from HuC. Something the psg bios doesn't (natively) have, afaik.

So, here's what I think I'm gonna do:
I already have the patch in to add the underscore to the register name. I haven't exhaustively checked it yet, but I'm fairly confident it works.
I'll 'extend' the MML parser, so that upper-case notes will be direct mode, while lower case notes will be time-base mode (which will have the happy side-effect of allowing for shrinking the output).
I'll probably add a simple psg-bios call to change the time base.
Then we can start discussing in detail how to alter the timer/hsync irq to get things working right for samples.

One question for you and tom, though. How much worse will mapping alternate pages make the timer stuff?  IF we add sample support, I believe it's going to need extra space for the samples; some of them are going to be quite long, and the mml player is currently limited to 2 pages. Sort of. (That's a whole different discussion.)

..........................
Tom:
 You're the only leftover hardware guru afaik. Do you know when the hsync irq actually occurs? Is it at the end of the active scan-line display (ie, start of the back porch), in the middle of the hblank area, or at the beginning of active display?
More specifically for what I'm thinking: How long do I have between an hsync irq triggering and the actual start of active display? The entire hb;ank period, or 0 cycles?

...........................
Everyone else:
 Stay tuned. This could get interesting, and we may actually hash out how to add samples to the psg player.....

Arkhan Asylum

I would like to think/assume we're all on the same page with music theory, and are maybe misspeaking/typing due to wall-of-text/excited/not proofreading, lol.

Am I the only one here with a real music background, out of curiosity?  (I minored in music.  I've been doing music theory / lessons / crap since I was a kid).

I'll openly admit I get all jumbled up with regards to implementing these sort of things on goony old machines though, since fractions piss me off.


Quote from: elmer on 12/11/2016, 01:15 PMNope, with the System Card Player, vsync does support changing the tempo. You've just got to encode the note length data in the "Time Base" length mode.

Doing so comes with the limitation that you can't specify 1/32nd notes, but that wasn't seen as a show-stopper problem by the programmer that wrote the driver, or by Hudson apparently.

Now, if your Squirrel compiler doesn't support that mode, then that's your choice.
IIRC, the CD version will work fine with the vsync stuff.  I can't remember though because I haven't touched the CD PSG stuff since Pyramid Plunder.   

It's the HUCARD version that for sure won't.   That's the pain in the ass I spoke of.  We're all aware that the capability does actually exist.  Hell, it's in the documentation in Develo, Hu7, and some notepad file IIRC.

but some of that stuff we did could be wrong.  As stated, we did this stuff by experimenting and looking around.  If we did something wrong, nobody is exactly there to correct it. 

It definitely did what was needed to make music in 4 games, though.  So it can't be too far off if some of the timing and such isn't implemented "how games used to do it *insert eyeroll here*"

also, those britspeak words for musical things are so dumb.  I always hated those in music classes.  We all made fun of them, and put on British accents and acted like assholes.

Can we agree to not use them anymore in these forums?  lolol

I don't know about anyone else but semi quaver cross stitch tea and crumpet demi semi loopdeedoo whatever just sounds like nonsense.

:)

now I just need to convince OldMan to not use case sensitivity in MML.  we need a better way to do that.


at least we've got the sample-ideas stirring again.  the idea came up awhile ago, there was no time to do it, we got sidetracked,  (and it was still barely important), but now would be a good time to worry about it.



EDIT:  Oh btw: Squirrel already has things for modifying the timebase, but they might not be right (that's what the ^D# commands do).

So, instead of adding something, we probably just need to look at what is already there. :)

This "max-level forum psycho" (:lol:) destroyed TWO PC Engine groups in rage: one by Aaron Lambert on Facebook "Because Chris 'Shadowland' Runyon!," then the other by Aaron Nanto "Because Le NightWolve!" Him and PCE Aarons don't have a good track record together... Both times he blamed the Aarons in a "Look-what-you-made-us-do?!" manner, never himself nor his deranged, destructive, toxic turbo troll gang!

Gredler

Hell yeah let's make that cat purr with sampled sfx :P

elmer

Quote from: TheOldMan on 12/11/2016, 05:57 PMI'll probably add a simple psg-bios call to change the time base.
That would be a "questionable" thing to do unless you make a whole bunch of other underlying changes.

The capability that's in the System Card Player is pretty-obviously to allow for tunes themselves to speed up ... i.e. you bake the command to change the Time Base into the tune data, so that the 2nd repetition of the loop is faster than the 1st, and the 3rd faster than the 2nd, and so on.

If you do it externally, you're going to have problems with channels losing sync because you change the Time Base while some channels are still playing notes with durations calculated using the old Time Base.

You'd have to sync any change to the start of a measure (or whatever the musical folks want to call it) when you retrigger every channel on the same frame.

P.S. trackers don't have this problem!


Quote from: TheOldMan on 12/11/2016, 05:57 PMEveryone else:
Stay tuned. This could get interesting, and we may actually hash out how to add samples to the psg player.....
It's a race!  :wink:

My sound driver is now re-written in 6280 assembly language, and the next step is to implement some GameBoy emulation features on the PCE (just so that I actually have tune data to test it with).

BTW ... this is a chance to say just how wonderfully *nice* Hu6280 assembly language can be compared to the Z80-ish that the GameBoy uses.

The GameBoy code is hideous in order to deal with some of the limitations of its not-actually-a-Z80 processor, where the Hu6280 code is simple and readable.

Arkhan Asylum

"simple and readable" to an extent, due to 6502isms.

:)

I don't think OldMan intended to do what you think with regards to changing the time base.   Maybe he does.  I don't know, lol.     As I said, we already support time base commands when setting up channels, but the tempo/vsync stuff may not be there, or right.  I am thinking we might not be as far off as we think, though, in terms of work.


Now, isn't the reason a tracker avoids this issue because of the fact that the tracker style tends to sort of "lock" things together, so everything is running simultaneously?

I'm not sure on the technical way of explaining that.  Things are sort of guaranteed and synced up.

EDIT: Also, should I envy you old goobers and your copious amounts of free time ?   I try to slot out free time so I can get Inferno/etc. done, and still PLAY games.  My backlogs kind of falling out of a cabinet right now.   -_-;

This "max-level forum psycho" (:lol:) destroyed TWO PC Engine groups in rage: one by Aaron Lambert on Facebook "Because Chris 'Shadowland' Runyon!," then the other by Aaron Nanto "Because Le NightWolve!" Him and PCE Aarons don't have a good track record together... Both times he blamed the Aarons in a "Look-what-you-made-us-do?!" manner, never himself nor his deranged, destructive, toxic turbo troll gang!

TurboXray

GBz80..wooh.. no good. I haven't written GBz80 in a long time, and I have recently looked back on it - yeah, no. To a lesser extent, real z80 too. When I code on the z80, and GBz80, I feel restricted by the force use of smaller register-register operations (and 90% of them still have to be done through one reg: "A" reg). I miss the direct memory access of the 65x, and the labels you get to use (keeping everything in regs instead of direct memory with labels, made the code harder to read IMO).

 Old Man: From what I remember my tests showing me, when the VDC transitions from "hsync" (or more accurately; the period/window where the VDC waits for VCE to trigger it to move onto "back porch" area) to the actual blanking line (blanking level), is when the VDC will generate an interrupt for the cpu. You can test this, because while the VDC is setup for a "waiting window" for the VCE to trigger it, the VCE trigger itself ALWAYS moves the VDC back to "front porch" area - no matter where it is in the scanline (the VDC's front porch, which when unaligned is not always the VCE's front porch). This is how you can get the VDC to show two individual lines of graphic data on the same VCE NTSC line. Does this make sense?

Maybe this pic will help:
IMG

 The VDC enters a mode where it waits for the VCE to trigger the start of the next scanline. In the pic, that would be the "sync tip" area. And where you see the line going back up to 0 IRE, that would be the position in VDC "world" where the H-interrupt is generated. That "sync tip" is what the VDC manuals refer to as "horizontal sync pulse width". But since the VDC is in subordinate mode (requiring external interrupts to provide the image frame work), this is just a wait delay. It's set in segments of 8 "VDC" pixels wide, but if the VCE trigger in the middle it, then the VCD immedialely transitions into the next phase. So it's not going to actually be 8 pixels long. You could set it to be 24 pixels long; it won't matter. The VDC also immediately reads the X and Y position buffers and works out the logic for how to process the current line (sprites positions, BG positions, etc). I doubt you'd be able to get a fast enough routine to update these regs in time anyway, so that's why changes to regs happen on the following line. That way, if the H-int routine gets delayed then it should be affected. But that all depends on how close the reg updates happen relative to the start of the H-int routine. 

tl;dr: H-int happens at the very start of the back porch, when sync level goes to 0 IRE (right before the color burst in the pic). And if I remember correctly, the VCE adds a 8 pixel delay from what the VDC is displaying to what you actually see on screen. But that probably shouldn't effect what you're doing unless you're trying to change VCE regs per scanline.

 It's a little bit confusing in understanding the VDC in relation to the VCE. The VDC on the PCE doesn't generate hsync pulse or the color burst area, because it's in subordinate mode, but the regs will always be setup as if you're defining a real line. So I used the term "back porch" to keep things relative in talking about where in the line stuff happens on the VDC.



 So, I didn't really follow along of what you're trying to solve. What timing issue are you trying to work out?

OldMan

QuoteSo, I didn't really follow along of what you're trying to solve.
Not a timing issue, yet. I'm trying to get a feel for how quick and hsync routine would have to be to avoid the active display area.

So, if I'm understanding it correctly, I have about 5us after hsync before color burst and active display....That's gonna be tight.
......................................
Edit:  My bad. I misunderstood. I had to go read it about 3 more times before what was where on the diagram clicked.

Hsync is gonna be triggered after the color burst, and very shortly before active display starts.
That actually explains some of the color tearing i've seen.

Thx.

elmer

Quote from: Psycho Arkhan on 12/11/2016, 11:33 PMNow, isn't the reason a tracker avoids this issue because of the fact that the tracker style tends to sort of "lock" things together, so everything is running simultaneously?

I'm not sure on the technical way of explaining that.  Things are sort of guaranteed and synced up.
The whole "pattern" abstraction with its even and odd 1/32nd-note rows does make it visibly-clear exactly how each of the channels are synced up to each other, and forces the musician into placing notes in such a way that the "patterns" that run on different channels never go out-of-sync (which *can* be a problem with MIDI-to-MML).

But ... IMHO, at the end-of-the-day, it's really just a case of when the "note length" values get converted into ticks (i.e. the number of 1/60s music-driver calls before the next note).

The standard music-driver convention (which I believe that the System Card Player follows), is that you calculate the length of a note as-soon-as you see that note on the stream of data (i.e. what the MML gets converted into so that the System Card Player can understand it).

That means that if you change the Base Time, i.e. the number of music-driver calls per 1/16 note, then the next note that you process on a different channel will see a different multiplier, and calculate a perfectly-correct delay count for it's own channel, but the other channel with the old note will drift out of sync by a few frames.

Repeat that enough times and it's all going to sound like cr*p.

The "tracker" model gets around this by redefining a note length as a certain number of rows/lines.

That way, the number of 1/60th ticks delay that each row/line takes up can change at any time.

From a programming POV, it's using 2 counters per note (1 for Base Time, and 1 for # rows) instead of a single counter in the traditional model.

That has its cost in processing terms ... but it's a tiny cost, and the flexibility that you gain from it is well-worth-it (IMHO).

Of course ... as a programmer, you'll realize that you can do exactly the same thing with MIDI or MML data that's converted into a command-string format and fed into some music driver, just like you do with the System Card Player ... but the actual System Card Player itself doesn't support that particular abstraction.

It's another thing on the (long) list of reasons why the System Card Player (and therefore the Squirrel Player) need to be taken out back behind the wood shed and put out of their misery.

I have no vested-interest in what data-format my music-driver plays (except for absolute-efficency).

Converting Deflemask files is no easier (or more difficult) than converting MIDI or MML files.

A "sane" music-driver uses some form of "processed" version of the tune data that is totally-optimized for it's own capabilities and the target platform.


Quote from: Psycho Arkhan on 12/11/2016, 11:33 PMEDIT: Also, should I envy you old goobers and your copious amounts of free time ?   I try to slot out free time so I can get Inferno/etc. done, and still PLAY games.  My backlogs kind of falling out of a cabinet right now.   -_-;
Being as-old-as-the-hills has to come with some (pitifully-few) advantages!  :wink:


Quote from: TurboXray on 12/12/2016, 12:15 AMI miss the direct memory access of the 65x, and the labels you get to use (keeping everything in regs instead of direct memory with labels, made the code harder to read IMO).
That's the issue, exactly!  :)

It's the difference between sta mz_volume,x, where "X" is the channel number, and the GBZ80 code that's full of ld hl,sp+VOLUME and ld (hli),a instructions, with very, very, very careful ordering of the variables in order to keep on using the (hld) or (hli) addressing modes for speed.

It's practically undecipherable except for the idiot that wrote the mess in the first place!  ](*,)

The Amiga and ST versions are much clearer (with the ST version supporting sample-playback), but I chose to work from the GameBoy version because that was the final version of the code.

Strange to be revisiting such old code and re-targeting it to a new platform!


Quote from: TurboXray on 12/12/2016, 12:15 AMSo, I didn't really follow along of what you're trying to solve. What timing issue are you trying to work out?
Hahaha!  :lol:

That's one brilliantly OCD post full of wonderful information, before finally getting around to the "what was your question, again?"  :wink:

I *think* that the information that TheOldMan is looking for is that the hsync timing doesn't really matter very much.

The VDC chip make copies of the scroll-registers that it will use for the next line of video at the start of an hsync, and doesn't read them again until the start of the next hsync.

So you actually set the hync interrupt to trigger on the line *above* where you want to change the scroll value, and then you have an entire scanline (433 cycles) to set the new scroll values before the VDC reads them again to set them for the next line that it's going to display (and where you want the actual scroll region to change).

The PCE is not like a lot of the old home-computers where you absolutely-must change the scroll-register values *during* the few microseconds of the hblank.

Arkhan Asylum

Some MML playing engines (I think Squirrel might.  if it doesn't, it should.) also support a different tempo for each channel.

I seem to recall messing around with it once.   It's not a common thing to want to do and really is for when you do SFX on a channel, or when you want to do arps or weird effects on a channel.

You can crank the tempo through the tits and get stranger sounds while the rest of the song plays at a tempo that is conducive to coherent music.

I'll have to see if it was Squirrel that was also doing that, or if that was around when I started Inferno and was doing this on MSX.

I think though, that with a little bit of fiddling around, Squirrel will be able to do some new things.

It hasn't exactly been touched or updated since before Atlantean.  The last time it was updated was for Pyramid Plunder. 
This "max-level forum psycho" (:lol:) destroyed TWO PC Engine groups in rage: one by Aaron Lambert on Facebook "Because Chris 'Shadowland' Runyon!," then the other by Aaron Nanto "Because Le NightWolve!" Him and PCE Aarons don't have a good track record together... Both times he blamed the Aarons in a "Look-what-you-made-us-do?!" manner, never himself nor his deranged, destructive, toxic turbo troll gang!

TurboXray

Quote from: elmer on 12/12/2016, 01:24 AMHahaha!  :lol:

That's one brilliantly OCD post full of wonderful information, before finally getting around to the "what was your question, again?"  :wink:
In my defense, I had a 14 page ethnographic paper I was trying to get done in order to turn it in by mid-night on Sunday. So I had a number of glasses of alcohol to get things.. flowing.  :-"

elmer

Quote from: TurboXray on 12/11/2016, 01:19 PMTo play a sample via writing to a single DDA channel, at 6991 calls per second, takes 11% cpu resource. It's 5% if no sample is playing (just down counting).
I take it that you have a timing setup in place.

Are you able to run a simple 6991Hz timer IRQ and tell us what the CPU cost (in cycles-per-frame) of the basic IRQ overhead?

That's on a HuCard, with a direct hardware vector (at $FFFA) to this IRQ routine ...

tirq_null:      stz     $1403                   ; 5
                rti                             ; 14


Arkhan Asylum

Why do you have ; 14 for the cycle count of RTI? 

I thought it was like 6. 

6502.org says 6.  ArchaicPixels says 7.   

Where did 14 come from?
This "max-level forum psycho" (:lol:) destroyed TWO PC Engine groups in rage: one by Aaron Lambert on Facebook "Because Chris 'Shadowland' Runyon!," then the other by Aaron Nanto "Because Le NightWolve!" Him and PCE Aarons don't have a good track record together... Both times he blamed the Aarons in a "Look-what-you-made-us-do?!" manner, never himself nor his deranged, destructive, toxic turbo troll gang!

elmer

Quote from: Psycho Arkhan on 12/12/2016, 02:41 PMWhere did 14 come from?
It came from the IRQ example code that bonknuts posted ... I was too lazy to look it up.

Yep, it's listed as 7 cycles in my docs.

Perhaps the other 7 cycles are the cost for the IRQ itself? If so, that would be the information that I'm looking for!

Arkhan Asylum

This "max-level forum psycho" (:lol:) destroyed TWO PC Engine groups in rage: one by Aaron Lambert on Facebook "Because Chris 'Shadowland' Runyon!," then the other by Aaron Nanto "Because Le NightWolve!" Him and PCE Aarons don't have a good track record together... Both times he blamed the Aarons in a "Look-what-you-made-us-do?!" manner, never himself nor his deranged, destructive, toxic turbo troll gang!

elmer

Quote from: Psycho Arkhan on 12/12/2016, 03:20 PMIs it slower on 6280 vs. 6502?  6502.org lists it as 6.
Lots of stuff is a cycle slower on the 6280 ... but lots of stuff is the same.

I have no idea why there's an extra cycle on an RTI, but it's documented.

The timings in the cribsheets that can be downloaded from bonknut's blog are accurate.

TurboXray

14 was the return total (pla, tam, and rti)
The int call is 8 cycles, the RTI is 7 cycles. That's the minimum you can possibly have on the PCE.

 Anyway, look over this:
/HuPCMDriver/TIRQ_playnice.png

I changed a few things around. "in_progress" can be used as both temporary bypass (sample currently being fetch/played), or to complete stop sample playback (because it can't undo itself if the condition is set outside the IRQ routine).
 
 I also decided to wrap the timer decrement inside a protect area (interrupts disabled). Just in case some wild edge case scenario showed its ugly head. You don't want a second call (overlapping TIRQ) to decement the counter while the previous call was in the middle of updating (resetting it back). The question is, would that be a bad thing if it did happen?

 So for stalling H-int, the longest is 44 cycles, mid is 30 cycles, and minimum is 22 cycles. The code is a little difficult to follow at first, because I'm trying to optimize for few case cycles per delay. You might notice that if a sample is going to be played, interrupts are enabled during that process, but disabled for the counter. If a sample isn't played, the branch that skips it - leaves interrupts disabled until the counter decrement can finish its process.

 Actually, worse case scenario of H-int delay would be 45 cycles; no sample to play, decrement counter but no psg player call, exit routine.


 So, you want overhead? Just the overhead of the decrement counter and no sample playing or player call? 45 cycles per call (a call being TIMER set to max speed). If you re-sync TIMER on internal vsync interrupt, you get a nice integer of 116 calls per frame (and no drift of the psg player relative to the frame - async.. eww). 116*45 = 5220 cycles or 4.38% cpu resource overhead.

Note: I think you stated something like 433 cpu cycles per scanline. I'm not sure if you were talking absolute or relative to overhead: VDC scanline is 455 cpu cycles long (the frame rate of 262 mode is something like ~60.1hz).



QuoteIs it slower on 6280 vs. 6502?  6502.org lists it as 6.
Some things are +1 cycle longer on the PCE (but unlike the 65x, there are no page boundary penalties.)
IMG

EDIT
Opps. I forgot to update ".EOF". It should read like this:
pla
tam #$04
jmp .TIMER_sampledisable

 Where .TIMER_sampledisable is a label point right after stz <in_progress.

ccovell

Slightly apropos of this topic, MML, case-sensitivity, and Z80 stuff, etc., did you hear about the MML driver that's in Alpha's Neo-Geo games?  I did a dissection, explanation, videos, etc. here: https://www.chrismcovell.com/ADKMML.html

Who knows, maybe the overloaded MML syntax might give some ideas for customization for the PCE hardware.

elmer

Quote from: TurboXray on 12/12/2016, 04:01 PMThe int call is 8 cycles, the RTI is 7 cycles. That's the minimum you can possibly have on the PCE.
QuoteNote: I think you stated something like 433 cpu cycles per scanline. I'm not sure if you were talking absolute or relative to overhead: VDC scanline is 455 cpu cycles long (the frame rate of 262 mode is something like ~60.1hz).
Thanks, those are both really useful information!  :D

So you're basing your percentages on 119210 cycles-per-frame?


Quote from: TurboXray on 12/12/2016, 04:01 PMAnyway, look over this:
That looks good!  :)

I'd be tempted to do things a *little* differently if I were going to try to implement the permanent-timer and music-driver-running-from-the-timer, especially in the case of HuC.

From what I've seen, HuC maps the main library bank to both MPR6 and MPR7, probably in order to maintain a consistent memory layout between HuCard and CD-ROM, and have the the library code at $C000.

In that case (and in whatever case if I were writing purely in assembly), I'd probably prefer to map RAM into MPR7 so that I could change the interrupt vectors at runtime.

If you do that, then your timer routine depends upon how many channels you want to play, and your idle-case for the driver gets a lot faster, something like this ...

tirq_none:      ;;;                             ; 8 (cycles for the INT)
                stz     $1403                   ; 5 Acknowledge TIMER IRQ.
                dec     <driver_cnt             ; 6
                beq     .driver_s               ; 2
                rti                             ; 7


That's just 28 cycles-per-irq, and 3248 cycles-per-frame, for just a 2.7% CPU overhead.

There is one thing ... I don't think that your sample-playback code is safe from something in a vsync or hsync handler changing the value of sample_bank or sample_ptr.

If you run the music-driver from the timer interrupt, then you'll probably get away with that, but you're may start getting problems if the music-driver runs in the vsync.

Of course ... the big thing here is that we're both still messing-around and trying to come up with solutions that work when the music-driver is called more-often that 60Hz.

I'd really rather not do that.  :-k

TurboXray

Quote from: elmer on 12/12/2016, 09:32 PMThat's just 28 cycles-per-irq, and 3248 cycles-per-frame, for just a 2.7% CPU overhead.
It's just a template to work with. Nice optimization though ;) If you're going to be playing samples for music, and SFX, personally I'd rather optimize for worse case scenario. If the max is 11% cpu resource, that's what I'm going to figure in when I'm allocating cpu resource per frame. Anything that fluctuates below that, such as idle cost, isn't going to help me. You have something else in mind?

QuoteThere is one thing ... I don't think that your sample-playback code is safe from something in a vsync or hsync handler changing the value of sample_bank or sample_ptr.

If you run the music-driver from the timer interrupt, then you'll probably get away with that, but you're may start getting problems if the music-driver runs in the vsync.
You're totally on your game :D I didn't put it in the code because we hadn't talked that far yet: There are some questions that need to be answered first: is the PSG player going to issue/handle SFX? I.e. SFX is handled through the PSG player or outside of it. I'd assume sampled instruments would be handled inside of it.

 I ran into this exact problem with my 4 channel PCM driver and how to change samples without overriding something that's in the middle of the TIRQ routine. I came up with a processing system. You send requests for driver updates (sample stuff), and the TIMER routine itself called this little "processing routine" to safely update sample regs - every 116 down count (another reason to re-sync TIMER immediately in vsync int).

 But yeah, there needs to be window provided to safely update sample reg stuff of the TIMER routine. If it's done through the PSG player (or whatever music "engine" is called in its place), then that would solve a lot of problems. And likewise, SFX should probably go through it. But you can do a buffer/processor system with a hook in vsync to safely update it too (as long as TIMER isn't async).

 I attached the "processor update" code to the TIMER itself with a downcount of 116, only because my 4 channel PCM driver is software frequency scaling each channel in realtime (and can stream samples to all 6 channels: 4 with frequency scaling, two fixed frequency for SFX). So it came dangerously close to not finishing in time for worse case scenario on vsync interrupt. Being this is just a simple sample stream routine, you could easily and safely put the "processor update" code in the vsync int routine. As in - directly inside the vsync handler, not a manual call in HuC itself after a vsync().

TurboXray

Also, I vote we call this "sample player" addition code as... "Muthafucking Juan Carlos". Because this shit's gonna rule!

elmer

Quote from: TurboXray on 12/11/2016, 01:19 PMTo play a sample via writing to a single DDA channel, at 6991 calls per second, takes 11% cpu resource. It's 5% if no sample is playing (just down counting).
Here are the versions that I've come up with for running the music-driver in the vblank interrupt, and then allowing for either a one-channel-only, or a two-channel-capable timer IRQ handler.

The timings are ...

|---------------------------------------------------------------------------------|
|  handler \ playing  |    0-channels    |     1-channel     |     2-channel      |
|---------------------------------------------------------------------------------|
|  one-channel-only   |  6380cyc, 5.35%  |  10582cyc, 8.85%  |                    |
|  two-channel-able   |  7308cyc, 6.13%  |  11484cyc, 9.63%  |  15712cyc, 13.18%  |
|---------------------------------------------------------------------------------|


But sensibly, if you were updating the music-driver in the vsync, and weren't actually playing any samples, then you'd just disable the timer interrupt completely and have a 0-cycyle, 0% cost.

It's such a minimal extra-cost to go for the two-channel-capable driver that it seems like it would be well worth-it.

13.18% worst-case cost for two channels of samples isn't stunningly great, but it doesn't seem too bad, either.  :-k


Here's the code, and please let me know if anyone sees any problems/mistakes ...

;****************************************************************************
;
; One Channel Sample Playback
;
; Time (normal 0 channel):  55 * 116 calls =  6380 cycles (5.35%)
; Time (normal 1 channel):  91 * 116 calls = 10556 cycles (8.85%)
; Time (worst  1 channel):  91 * 115 calls +
;                          117 *   1 calls = 10582 cycles (8.88%)

tirq_ch4:       ;;;                             ; 8 (cycles for the INT)
                stz     $1403                   ; 5 Acknowledge TIMER IRQ.
                cli                             ; 2 Allow HSYNC to interrupt.
                pha                             ; 3
                tma3                            ; 4
                pha                             ; 3
                sei                             ; 2 Disable interrupts.

.channel4:      bbr4    <sample_flag,.done      ; 6
                lda     <sample4_bnk            ; 4
                tam3                            ; 5
                lda     #4                      ; 2
                sta     PSG_R0                  ; 5
                lda     [sample4_ptr]           ; 7
                bmi     .eof4                   ; 2
                sta     PSG_R6                  ; 5
                inc     <sample4_ptr            ; 6
                beq     .msb4                   ; 2

.done:          pla                             ; 4
                tam3                            ; 5
                pla                             ; 4
                rti                             ; 7

.msb4:          inc     <sample4_ptr+1          ; 6
                bpl     .done                   ; 2
                inc     <sample4_bnk            ; 6
                lda     #$60                    ; 2
                sta     <sample4_ptr+1          ; 4
                bra     .done                   ; 4

.eof4:          stz     PSG_R4                  ; 5
                rmb4    <sample_flag            ; 7
                bra     .done                   ; 4


;****************************************************************************
;
; Two Channel Sample Playback
;
; Time (normal 0 channel):  63 * 116 calls =  7308 cycles (6.13%)
; Time (normal 1 channel):  99 * 116 calls = 11484 cycles (9.63%)
; Time (normal 2 channel): 135 * 116 calls = 15660 cycles (13.14%)
; Time (worst  2 channel): 135 * 115 calls +
;                          187 *   1 calls = 15712 cycles (13.18%)

tirq_ch34:      ;;;                             ; 8 (cycles for the INT)
                stz     $1403                   ; 5 Acknowledge TIMER IRQ.
                cli                             ; 2 Allow HSYNC to interrupt.
                pha                             ; 3
                tma3                            ; 4
                pha                             ; 3
                sei                             ; 2 Disable interrupts.

.channel3:      bbr3    <sample_flag,.channel4  ; 6
                lda     <sample3_bnk            ; 4
                tam3                            ; 5
                lda     #3                      ; 2
                sta     PSG_R0                  ; 5
                lda     [sample3_ptr]           ; 7
                bmi     .eof3                   ; 2
                sta     PSG_R6                  ; 5
                inc     <sample3_ptr            ; 6
                beq     .msb3                   ; 2

.channel4:      bbr4    <sample_flag,.done      ; 6
                lda     <sample4_bnk            ; 4
                tam3                            ; 5
                lda     #4                      ; 2
                sta     PSG_R0                  ; 5
                lda     [sample4_ptr]           ; 7
                bmi     .eof4                   ; 2
                sta     PSG_R6                  ; 5
                inc     <sample4_ptr            ; 6
                beq     .msb4                   ; 2

.done:          pla                             ; 4
                tam3                            ; 5
                pla                             ; 4
                rti                             ; 7

.msb3:          inc     <sample3_ptr+1          ; 6
                bpl     .channel4               ; 2
                inc     <sample3_bnk            ; 6
                lda     #$60                    ; 2
                sta     <sample3_ptr+1          ; 4
                bra     .channel4               ; 4

.msb4:          inc     <sample4_ptr+1          ; 6
                bpl     .done                   ; 2
                inc     <sample4_bnk            ; 6
                lda     #$60                    ; 2
                sta     <sample4_ptr+1          ; 4
                bra     .done                   ; 4

.eof3:          stz     PSG_R4                  ; 5
                rmb3    <sample_flag            ; 7
                bra     .channel4               ; 4

.eof4:          stz     PSG_R4                  ; 5
                rmb4    <sample_flag            ; 7
                bra     .done                   ; 4

TurboXray

Quote from: elmer on 12/12/2016, 10:51 PM13.18% worst-case cost for two channels of samples isn't stunningly great, but it doesn't seem too bad, either.  :-k
Well, compare that to Air Zonk. Air Zonk is almost 30% cpu resource max (and it hits that max every time a sample is playing)! Sure, it's decompressing samples - but.. 30%! Pfft. ~13% is fine.

 Yeah, once you have the overhead of everything, adding additional channels for sample streaming doesn't increase it a whole lot.

 Just some thoughts:
On your 2nd channel one. I would add a cli, nop, sei right after .channel4. Your worst case scenario for each channel is 68 cycle delay for H-int, which would probably be fine, but I wouldn't push it with twice that in a worse case scenario.

 Also, by not having a busy flag system (have interrupts open for the whole thing)- you're setup is going to be little less friendly with code using small Txx in 32byte segments during active display - and worse case scenarios in all settings (H-int and TIRQ). Just something to note. Might want to recommend or write block transfers with 16byte or 8byte segments with Txx.





 These following ideas might not be popular for HuC, but I'll mention them anyway:

 It won't save a whole lot, but if you pad sample with some 0's (assume all samples are made of 116 byte segments). You can run a segment length counter in vsync, and remove the BMI to .EOF check, it only saves 2 cycles per channel though.

Likewise, you can speed up if you're using two or more channels - if you store 116 samples as 128 byte segments (bytes 117 to 127 are null - do nothing). And then align them to 128byte boundary in rom/memory. A little bit a growth (the size of 7.68khz but the playback of 7khz), but now you don't need to check bank boundary crossing in the TIRQ routine itself - AND.. all samples regardless of their memory address can all use one Y index reg value. Incrementing to the next 128 segment would be done during vsync or on the last 116th call. Stick the TIRQ routine inside of ram, and you save some more cycles with self-modifying code. What's the thing take up now? 200 bytes?


 

 Something I'm curious about: Why channel's 3 and 4? Why not channels 0 and 1? Channel 0 saves you 2 cycles. And leaving channels 4 and 5 free allow noise mode for both of those while samples are playing. 7khz is pretty good for almost all drumkit samples, but not so great at short/closed hi-hats. Noise channel is good for those. Just some thoughts.

Arkhan Asylum

Quote from: TurboXray on 12/12/2016, 10:35 PMAlso, I vote we call this "sample player" addition code as... "Muthafucking Juan Carlos". Because this shit's gonna rule!
I vote we move the assembly sample playing bromance all out of the MML thread to somewhere else because it's probably scaring people away from MML and basically has dickall to do with MML, thus clogging the thread up with something else.

I think there's already a PCM thread.

https://www.pcengine-fx.com/forums/index.php?topic=21695.0
This "max-level forum psycho" (:lol:) destroyed TWO PC Engine groups in rage: one by Aaron Lambert on Facebook "Because Chris 'Shadowland' Runyon!," then the other by Aaron Nanto "Because Le NightWolve!" Him and PCE Aarons don't have a good track record together... Both times he blamed the Aarons in a "Look-what-you-made-us-do?!" manner, never himself nor his deranged, destructive, toxic turbo troll gang!

Arkhan Asylum

Quote from: ccovell on 12/12/2016, 07:25 PMSlightly apropos of this topic, MML, case-sensitivity, and Z80 stuff, etc., did you hear about the MML driver that's in Alpha's Neo-Geo games?  I did a dissection, explanation, videos, etc. here: https://www.chrismcovell.com/ADKMML.html

Who knows, maybe the overloaded MML syntax might give some ideas for customization for the PCE hardware.
Lol, that damn Magician Lord sample.  It's so goofy.

I'd be curious what they composed with back then.  I wonder if they just typed the music in after composing it elsewhere, or what


It's good for the most part that they stayed fairly standard, but I do not see why they went with > and < meaning backwards things.

I wonder if it was on accident?

I would personally like to avoid introducing the concept of case sensitivity because that will be a recipe for disaster and annoyance, but we have definitely already added some PCE specific things to Squirrel.


This "max-level forum psycho" (:lol:) destroyed TWO PC Engine groups in rage: one by Aaron Lambert on Facebook "Because Chris 'Shadowland' Runyon!," then the other by Aaron Nanto "Because Le NightWolve!" Him and PCE Aarons don't have a good track record together... Both times he blamed the Aarons in a "Look-what-you-made-us-do?!" manner, never himself nor his deranged, destructive, toxic turbo troll gang!

elmer

Quote from: ccovell on 12/12/2016, 07:25 PMSlightly apropos of this topic, MML, case-sensitivity, and Z80 stuff, etc., did you hear about the MML driver that's in Alpha's Neo-Geo games?  I did a dissection, explanation, videos, etc. here: https://www.chrismcovell.com/ADKMML.html
That's so darned amazingly cool, I wasn't aware of that at all. Thanks for posting that!  :dance:


Quote from: Psycho Arkhan on 12/13/2016, 12:30 AMI vote we move this all out of the MML thread because it's probably scaring people away from MML and basically has dickall to do with MML.
Hahaha ... just don't bring this sample-sh*t into the HuC thread!!!  :wink:


Quote from: TurboXray on 12/12/2016, 10:30 PMThere are some questions that need to be answered first: is the PSG player going to issue/handle SFX? I.e. SFX is handled through the PSG player or outside of it. I'd assume sampled instruments would be handled inside of it.
Any sane music-driver for a console also needs to handle sound-effects.

I have no idea what modifications it would take to hack the System Card Player to play samples as either drums, or as SFX.

Honestly ... I just don't care.

I'd much-rather have an open-source replacement (with a clean copyright status) that could play samples.

From the POV of my driver that I'm converting at the moment ... "yes", both sound effect and sample support are handled.

I do not currently, and probably won't-ever, handle the case of restarting/continuing a music-channel sample that gets cut-off by a sound-effect sample.

Fixed-rate samples in music-channels are normally limited to drums and short things like that where you don't object to dropping-out a single hit/note.

But if someone cares-enough about the capability ... that's why stuff like this should be open-source these days ... so that they can go and add it themselves.


QuoteI ran into this exact problem with my 4 channel PCM driver and how to change samples without overriding something that's in the middle of the TIRQ routine. I came up with a processing system.
...
But yeah, there needs to be window provided to safely update sample reg stuff of the TIMER routine.
I think/hope that you'll see that the code that I posted above is immune to this problem, and needs no special handling. You just disable the sample playback (or interrupts) before changing the pointer to the sample. Trivial.

It should also be completely safe for use around hsync interrupts, and 32-byte Txx transfer instructions.  :)

elmer

Quote from: TurboXray on 12/13/2016, 12:01 AMWell, compare that to Air Zonk. Air Zonk is almost 30% cpu resource max (and it hits that max every time a sample is playing)! Sure, it's decompressing samples - but.. 30%! Pfft. ~13% is fine.
Reply move to the PCM thread to stop thread-bombing Arkhan!  :lol:

TurboXray

Quote from: elmer on 12/13/2016, 01:04 AM
Quote from: TurboXray on 12/13/2016, 12:01 AMWell, compare that to Air Zonk. Air Zonk is almost 30% cpu resource max (and it hits that max every time a sample is playing)! Sure, it's decompressing samples - but.. 30%! Pfft. ~13% is fine.
Reply move to the PCM thread to stop thread-bombing Arkhan!  :lol:
Since you're doing your own engine/driver/whatever.. make a new thread! I got something I wanted to share with you, now that you have a TIRQ routine.

Arkhan Asylum

LOL.

This sandbox MMO called Archeage apparently uses MML, and even has a little tutorial in it.

I loled pretty hard at this discovery .
Metallica, lol, wtf:
This "max-level forum psycho" (:lol:) destroyed TWO PC Engine groups in rage: one by Aaron Lambert on Facebook "Because Chris 'Shadowland' Runyon!," then the other by Aaron Nanto "Because Le NightWolve!" Him and PCE Aarons don't have a good track record together... Both times he blamed the Aarons in a "Look-what-you-made-us-do?!" manner, never himself nor his deranged, destructive, toxic turbo troll gang!