Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - Miscellany...

Reply to topic
Author Message
vecna
  • Guest
Reply with quote
Miscellany...
Post Posted: Tue Apr 11, 2000 3:59 am
Well, I was *hoping* to make a sort of limited alpha release of CHASMS tonight, but, (cough) few things are more irritating than when something crashes in Release mode, but when you attempt to track it down in Debug mode, the bug doesn't crash. So, I'm gonna be chasing down loose ends for a bit longer, but hopefully I'll be able to make an initial alpha release Real Soon Now.

However, I've been thinking. I've recently gotten the sound (non-FM, non-speech) emulation sounding 99.5% like the real thing (at least on the games I own and can judge from), and the talk about SMS music has made me ponder the idea of a 'SMS Music Tracker'. The project itself wouldn't really be too hard... I'm not sure if I'll have time to do it or not, but it wouldn't be too bad. But, while I was thinking about this, I figured, it'd have two main purposes: it could load and play back music logs or something, since there was talk of a SMS music format a while ago.. but a really cool use would be to track SMS music that could actually be inserted into homebrew ROMs. To that end, we'd have to have a music player. There are a few SMS homebrew ROMs with sound (although I've not looked at their playback loop), I assume commercial SMS ROMs do their music playback inside interrupts? Basically, I'm wondering what the best 'format' to dump PSG data to a file would be such that it could be read in and used by a homebrew SMS ROM music playback code. The most obvious is to just sort of have a byte for every 60hz tick, and an optional 'empty' tick, but that's rather memory hoggy. I could just allow the user to specify the hz resolution, but that doesn't really account for 2-byte command words. What sort of format do real musicplayers use, does anyone know?

I guess, I'm just trying to get a vague idea of what it would be like. *If* I decide to try to do this, I probably wouldn't get around to it until at least the 2nd release of CHASMS such that it could be decently polished.

Oh, and just as a P.S., I'm currently using a logarithmic volume scale for my SMS sound conversions, and it sounds pretty good. Does anyone know if the SMS actually uses a logarithmic vs. linear volume scale or not? I guess human ears probably aren't too adept at telling subtle volume differences, and it probably doesn't really matter one way or another. (shrug)

- vecna
 
  • Site Admin
  • Joined: 25 Oct 1999
  • Posts: 2029
  • Location: Monterey, California
Reply with quote
Post Posted: Tue Apr 11, 2000 6:18 am
Quote
> Well, I was *hoping* to make a sort of limited alpha release of CHASMS tonight, but, (cough) few things are more irritating than when something crashes in Release mode, but when you attempt to track it down in Debug mode, the bug doesn't crash. So, I'm gonna be chasing down loose ends for a bit longer, but hopefully I'll be able to make an initial alpha release Real Soon Now.

What's been keeping me from releasing any version of sms tetris since the first one a few weeks ago, is that every time I have a stable version, I have to add JUST ONE MORE THING to it before I put out the next release, and in doing so I introduce some new bug that eludes me for hours at a time.
And after I finally track it down and get it working like I want it to, I just want to add ONE MORE THING before I release it...

Quote
> However, I've been thinking. I've recently gotten the sound (non-FM, non-speech) emulation sounding 99.5% like the real thing (at least on the games I own and can judge from), and the talk about SMS music has made me ponder the idea of a 'SMS Music Tracker'. The project itself wouldn't really be too hard... I'm not sure if I'll have time to do it or not, but it wouldn't be too bad. But, while I was thinking about this, I figured, it'd have two main purposes: it could load and play back music logs or something, since there was talk of a SMS music format a while ago.. but a really cool use would be to track SMS music that could actually be inserted into homebrew ROMs. To that end, we'd have to have a music player. There are a few SMS homebrew ROMs with sound (although I've not looked at their playback loop), I assume commercial SMS ROMs do their music playback inside interrupts? Basically, I'm wondering what the best 'format' to dump PSG data to a file would be such that it could be read in and used by a homebrew SMS ROM music playback code. The most obvious is to just sort of have a byte for every 60hz tick, and an optional 'empty' tick, but that's rather memory hoggy. I could just allow the user to specify the hz resolution, but that doesn't really account for 2-byte command words. What sort of format do real musicplayers use, does anyone know?

A simple, reasonably efficient and versitile format would be something like this (I'm making this up as I go along, btw):

Each sound channel has it's stream of music data. Hereforth we will look at one stream at a time:
(Assume we've set (StreamPtr) to beginning of the stream data for this channel, and set (Delay) to zero. Set FreqSetCode to (%10000000 | (ChannelNumber<<5). Set VolumeSetCode to FreqSetCode | %10000).
At each cycle (60 cycles per second, 50 PAL):
If (Delay) is non-zero, decrease (Delay) by one, and end iteration (RETurn)
Else, Read the next byte off the stream into (Data) (get value at (StreamPtr), increase (StreamPtr))
If top two bits (bit 6 & 7) of (Data) are clear:
...Output (Data) to port $7f
...Read next byte of stream into (Data) (Read value at (StreamPtr), increment (StreamPtr))
...Save of copy of (Data) (on stack, perhaps)
...Clear top four bits of (Data) (AND with $f)
...Merge bits of (Data) with (FreqSetCode) (OR them together)
...Output (Data) to port $7f
...Restore the copy of (Data) we saved (from stack, probably)
...Move top four bits of (Data) to bottom four, replace top bits with zero (shift logical right four times)
...Merge bits of (Data) with (VolumeSetCode) (OR them together)
...Output (Data) to port $7f
...End iteration (RETurn)
Else..
If Top bit of (Data) is clear, but the second is Set.. ( (Data) & ($c0 == $40)
...Clear top 4 bits of (Data) (AND with $f)
...Merge (Data) with VolumeSetCode (AND them together)
...Output (Data) to port $7f
...End iteration (RETurn)

If Top Bit of (Data) is set, Second to Top is clear.. ( (Data) & $c0 == $80)
...Clear top bit of (Data) (AND with $3f, or RES 7, or hatever)
...Store (Data) in (Delay)
...End iteration (RETurn)
Else.. (Top bits must both be set at this point)
If low six bits of (Data) are clear.. ((Data) == $c0))
...End of Stream has been reached, terminate stream --and end iteration of course.
Else..
Load (Data) into High byte of (OffsetValue)
Get next byte off stream, put into low byte of of (OffsetValue) (Increment the (StreamPtr) while we're at it)
Add (OffsetValue) to (StreamPtr) [(OffsetValue) is a negative value, so we'd be bbacktracking into the stream]
Go back to beginning of the stream handler (since we've moved back, we'll still want to play the next sound or start the next delay in this cycle)

end pseudocode
Um, I'm swooning with fatigue right now, if you don't mind I'll post this now and proofread and correct tomorrow morning.

The short version:
For each channel, it's own stream.

At each cycle...
If the delay timer isn't zero, reduce it by one, and return.
Otherwise, read a byte off the stream
If bits 6 and 7 are clear, then this and the next byte are the frequency and volume packed into 16-bits. Output them and return.
If bit 7 is clear but bit 6 is set, the change in volume is in the lower four bits. Output and return.
If the bit 7 set, but bit 6 clear, then the lower six bits are the number of cycles to delay until reading the next byte off the stream. Store this value in (Delay), and return.
If the byte is $c0, end the stream (or end the music, I'm not sure which).
Otherwise, this byte (high byte) and the next byte (low byte) are the signed 16-bit offset from the current location of the Stream pointer. (this is used for looping music, especially those that don't loop back to the very beginning). Adjust pointer and go back to the beginning of the stream handler.

Are there any logical anomalies? This seems to be reasonably memory efficient, allowing for delays with no change which don't use more than one byte for evert 63 pause cycles. (I guess you can also pause for 256 cycles too. hmm. not sure if I should close that loophole), condensing volume and frequency changes into a single 2-byte code, allowing for looping and ending, and using a single byte for volume changes, which are much more common. Not terribly inefficient, it doesn't waste bytes on control codes, nor is it too difficult to implement, but it's hard to write music that way. I'd recommend writing a program to convert it from an easier to write text format into raw data.
I also like that it doesn't depend on music using a certain number of channels. It can also be used for single (or multichannel) sound effects just as effectively.

It's -not- as efficient, however, if you're going to be doing things with glissando, vibrato, and other pitch-change intensive things (or volume change intensive also).If (worst case scenerio) all three tone channels are changing their frequencies one per cycle, it would cost 360 bytes per second. That could add up.
I have a much more complicated method in mind, but it wouldn't work well as a portable solution.



Quote
> I guess, I'm just trying to get a vague idea of what it would be like. *If* I decide to try to do this, I probably wouldn't get around to it until at least the 2nd release of CHASMS such that it could be decently polished.

> Oh, and just as a P.S., I'm currently using a logarithmic volume scale for my SMS sound conversions, and it sounds pretty good. Does anyone know if the SMS actually uses a logarithmic vs. linear volume scale or not? I guess human ears probably aren't too adept at telling subtle volume differences, and it probably doesn't really matter one way or another. (shrug)

I am 98% sure it's linear. For what it's worth coming from me.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 1999
  • Posts: 1732
  • Location: Paris, France
Reply with quote
Suggestion
Post Posted: Tue Apr 11, 2000 7:48 am
Quote
> Well, I was *hoping* to make a sort of limited alpha release of CHASMS tonight, but, (cough) few things are more irritating than when something crashes in Release mode, but when you attempt to track it down in Debug mode, the bug doesn't crash. So, I'm gonna be chasing down loose ends for a bit longer,

I suggest putting "inline" everywhere. It might correct the bugs with you too ^_^

[SMS Sound Format]
see Heliophobe's post.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 1999
  • Posts: 1732
  • Location: Paris, France
Reply with quote
Post Posted: Tue Apr 11, 2000 7:54 am
It seems very good to me, except for the delay things. With a maximum of 63 cycles, even 256 cycles, the player will spend its time decreasing the delay counter.
Remember sound is updated 25/30 or 50/60 times per second. More than 60 seconds means the same as playing a voice, catch most of the CPU time.
When a game like Space Harrier play voice, I believe the sound code is the main process and moving the character is done inside of the interrupt.
Still, I don't think there is a way to make a generic replayer handling cycle delays and that run in the background (inside of INTs).
So I suggest simply changing that delay unit from a cycle to a 1/60 frame unit.
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 25 Oct 1999
  • Posts: 2029
  • Location: Monterey, California
Reply with quote
Post Posted: Tue Apr 11, 2000 8:20 am
Quote
> It seems very good to me, except for the delay things. With a maximum of 63 cycles, even 256 cycles, the player will spend its time decreasing the delay counter.
> Remember sound is updated 25/30 or 50/60 times per second. More than 60 seconds means the same as playing a voice, catch most of the CPU time.
> When a game like Space Harrier play voice, I believe the sound code is the main process and moving the character is done inside of the interrupt.
> Still, I don't think there is a way to make a generic replayer handling cycle delays and that run in the background (inside of INTs).
> So I suggest simply changing that delay unit from a cycle to a 1/60 frame unit.

Errrmph.
I don't know which one of us is confusing the other.
When I say 'cycle', I mean iteration of the sound handler, not machine cycles.
I think I mentioned somewhere in that each cycle (err, iteration... err, delay unit) was meant to be 1/60th of a second, 1/50 of a sec in PAL.
Should be more careful with those interchangable terms.hmm.
And, when you say "1/60 frame unit" you mean, 1/60th of a second, not 1/60th of a frame (1/3600 of a second), right?
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 1999
  • Posts: 1732
  • Location: Paris, France
Reply with quote
Post Posted: Tue Apr 11, 2000 9:10 am
Quote
> Errrmph.
> I don't know which one of us is confusing the other.
> When I say 'cycle', I mean iteration of the sound handler, not machine cycles.
> I think I mentioned somewhere in that each cycle (err, iteration... err, delay unit) was meant to be 1/60th of a second, 1/50 of a sec in PAL.
> Should be more careful with those interchangable terms.hmm.
> And, when you say "1/60 frame unit" you mean, 1/60th of a second, not 1/60th of a frame (1/3600 of a second), right?

Right.
Forget what I said, I probably didn't read your post carefully enough.
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 25 Oct 1999
  • Posts: 2029
  • Location: Monterey, California
Reply with quote
Post Posted: Tue Apr 11, 2000 5:08 pm

Quote
> Right.
> Forget what I said, I probably didn't read your post carefully enough.

I certainly didn't write it carefully enough.

Hmm. I'm starting to wonder if it might be better to interleave the streams instead of using three seperate stream pointers. Maybe I'll work on that whne I'm ready to add sound to my game.

And start working on a new game, maybe. Bleah, I don't even like tetris.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 1999
  • Posts: 1732
  • Location: Paris, France
Reply with quote
Post Posted: Tue Apr 11, 2000 5:54 pm
Quote
> And start working on a new game, maybe. Bleah, I don't even like tetris.

A racing one should be cool and very faisable.
  View user's profile Send private message Visit poster's website
Chris
  • Guest
Reply with quote
Cool, that makes sense
Post Posted: Wed Apr 12, 2000 12:28 am
Quote
> Remember sound is updated 25/30 or 50/60 times per second. More than 60 seconds means the same as playing a voice, catch most of the CPU time.
> When a game like Space Harrier play voice, I believe the sound code is the main process and moving the character is done inside of the interrupt.

This part. This makes sense. Except for in games likes Alex Kidd: Lost Stars and Afterburner, they completely freeze the entire game just to play a sample. Sega had a good idea when they did that with Space Harrier. It would suck if you heard, "Guuaaaahh!" and then the animation happened. I'm also glad they took out that "You're doing great!" and "Keep it up, you're almost there!" voice that you heard everytime you beat a level in the Arcade version. That would madly lag up the gameplay.

Quote
> Still, I don't think there is a way to make a generic replayer handling cycle delays and that run in the background (inside of INTs).
 
Reply to topic



Back to the top of this page

Back to SMS Power!