Drawing ADSR envelopes to screen.

For anything related to sound (YM2612, PSG, Z80, PCM...)

Moderator: BigEvilCorporation

Post Reply
Count SymphoniC
Very interested
Posts: 149
Joined: Sat Nov 17, 2012 3:58 am

Drawing ADSR envelopes to screen.

Post by Count SymphoniC » Thu Oct 09, 2014 1:46 pm

What the hell! How is this possible? I see this as a great challenge considering the tile based graphics system. Lots of sprites maybe? What would be the most feasible option?

r57shell
Very interested
Posts: 478
Joined: Sun Dec 23, 2012 1:30 pm
Location: Russia
Contact:

Post by r57shell » Thu Oct 09, 2014 2:02 pm

You just need to implement bitmap drawing based on tiles, nothing difficut.
For me, vizualize sensible ADSR envelope itself much harder. I mean, if you can draw curve, which one to draw?
Last edited by r57shell on Thu Oct 09, 2014 2:04 pm, edited 1 time in total.
Image

BigEvilCorporation
Very interested
Posts: 209
Joined: Sat Sep 08, 2012 10:41 am
Contact:

Post by BigEvilCorporation » Thu Oct 09, 2014 2:03 pm

If you can manipulate individual pixels, you can draw anything ;)

A basic line rasteriser shouldn't be too tricky to knock up with some basic maths. You'll need enough spare VDP memory for one tile per cell (for the area you want to draw on).
A blog of my Megadrive programming adventures: http://www.bigevilcorporation.co.uk

Count SymphoniC
Very interested
Posts: 149
Joined: Sat Nov 17, 2012 3:58 am

Post by Count SymphoniC » Thu Oct 09, 2014 2:35 pm

Thanks guys... I was thinking too much of working with the nametables and not the tiles' bytes themselves. r57shell you're probably right about that being the hard part. I guess I'll just have to break down each part of the envelope until each part works right and BigEvilCorp, as usual you're an inspiration. Bresenham's line algorithm looks useful for the logic part.

I can't wait to share my ADSR envelopes when they're done. They're going to be amazing.

BigEvilCorporation
Very interested
Posts: 209
Joined: Sat Sep 08, 2012 10:41 am
Contact:

Post by BigEvilCorporation » Thu Oct 09, 2014 4:25 pm

My next article is on ADSR, it's been in draft form for a long time though due to work commitments :(

Just in case it's of any use to you:



Welcome to the second article in the Megadrive Sound series! I've been hard at work on my PSG sequencer, making a few improvements, adding new features, and messing with different sounds. The first addition is software envelopes, which allow for individual notes to fade in and out over time. The second is white noise, which allows for some basic percussion sounds. As usual, I'll be starting off with a little theory behind the things I've implemented.

ADSR Envelopes

An envelope is a predefined volume curve applied to each note, which can be tweaked to provide softer sounding notes compared to just hammering them on or off at full volume. With a little creativity, they can be adjusted to create different sounding instruments, or can even be used to create very short notes to simulate percussion, especially when applied to white noise rather than a wave. I've been implementing a specific kind of envelope - ADSR. These envelopes comprise four parts - Attack, Decay, Sustain and Release. Attack is a curve from full attenuation up to an initial "on" volume. The volume then dips down a Decay curve, settling on the Sustain volume. When the sustain time has expired, the volume fades down over the Release curve.

Image

If you're not familiar with the concept, it's easier to imagine how a piano note behaves - it begins with the player pressing down on the key which hits the string with the mallet and immediately recoils, creating the attack sound. This very quickly (over a couple of milliseconds) decays down to a softer sustain volume. Once the player lifts their finger off they key, a dampener covers the string to force the sound to die down sharply, which is the release. Technically, there's a lot more to it than that, but this is all we need to know in order to approximate the sound electronically.

Software ADSR on the PSG

Many dedicated audio processors implement ADSR envelopes on the hardware, but the PSG is very simple and does no such thing. We need to manually ramp the volume up and down to approximate the curves. In the image above, I've demonstrated linear changes, but in the real world these would likely be curves. The PSG's attenuation values from 0xF to 0x0 step up the volume exponentially, so by incrementing the attenuation register linearly we get a curve for free. Unfortunately, with only 16 possible values, the difference between the top few values are quite steep, which can result in some undesired artefacts. It seems the PSG applies all register changes immediately, rather than waiting for the next square wave polarity flip, which means we can potentially alter the attenuation in the middle of a zero crossover point causing pops and clicks. There's no real solution to this, and after some discussions with a few wiser brains on the SpritesMind forum, it seems the best thing to do is avoid these top attenuation values completely. I've also been told the PSG's volume is far louder than the FM chip, so losing the ability to play the PSG at full blast is no real loss. With this in mind, I've chosen a minimum attenuation value of 0x5 to avoid these large, quick jumps in volume. So, how do we define the envelope? We need the following information: attack time, attack height, decay time, sustain height, and release time. We already have the sustain time, that's defined in the data for each note.
A blog of my Megadrive programming adventures: http://www.bigevilcorporation.co.uk

Count SymphoniC
Very interested
Posts: 149
Joined: Sat Nov 17, 2012 3:58 am

Post by Count SymphoniC » Thu Oct 09, 2014 4:56 pm

Yes I'm sure some of that information will be useful. I'm pretty familiar with ADSR envelopes and how they affect the volume of an instrument just not the programming side of it yet, but the issue with artifacts in the PSG is something interesting. Maybe that's why Deflemask doesn't support PSG envelopes... last I checked anyways.

Hey, whenever you get started on the YM2612 let me know. I can pass along the YMDJ .asm source file for all the register defines (there are many of them and typing them all out is a bit more involved than the other chips, enough for me to justify defining the YM2612 globals in a separate file) I try to be organized anyways.

db-electronics
Very interested
Posts: 89
Joined: Mon Feb 24, 2014 6:04 pm
Location: Kapuskasing, Ontario, Canada
Contact:

Post by db-electronics » Tue Jan 27, 2015 2:32 pm

Image

With respect to the specifics of creating a line equation from register values; does anyone have specific information concerning the linearity of values?

For instance, in the sound manual it states that each increment in TL results in roughly a 0.75dB increase in perceived volume.

As an example, Attack Rate is stored as a 5bit number (0 to 31), does this map linearly from 0° to 90°?
What does db stand for? Well that's an excellent question...
http://www.db-electronics.ca

TmEE co.(TM)
Very interested
Posts: 2440
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Post by TmEE co.(TM) » Tue Jan 27, 2015 2:59 pm

Attack is exponential, rest are linear.

Attack : EnvOut += (NOT(EnvOut) * AttInc) SHR 4
Others : EnvOut += AttInc

AttInc value is 0,1,2,4 or 8, depending on some input parameters. I should turn them to shift values instead and lose the multiplication from my emulation core.
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

Post Reply