It is currently Thu Oct 19, 2017 2:16 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 96 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7
Author Message
PostPosted: Tue Oct 03, 2017 11:03 pm 
Offline
User avatar

Joined: Mon Apr 04, 2011 11:49 am
Posts: 1905
Location: WhereverIparkIt, USA
Well it's happened again, get around to writing some code and taking a closer look at the STM8 register settings, and I found a little gem.

TIM2 is the mid grade counter on chip I've dedicated to the PWM DAC. It's only capable of up counting, and thus has no center aligned PWM mode of operation. HOWEVER there is an output mode that toggles the output pin on timer compare match. Taking advantage of this, one can effectively create a center aligned PWM if you're willing to dedicate the CPU resources to update the compare value on each timer overflow. I'm not yet sure I've got the resources to pull this off in my case, we'll see.

To make this work all that needs to be done is invert the DAC value every other output. We can also take advantage of Tepples tip to keep from loosing a bit of resolution, it's best of both worlds with this trick if there's CPU resources to spare.

Here's how I'm thinking this would work:
-Assuming 16Mhz counter clock, 31Khz PWM freq, counter top value of 255 (0xFF), normally give 8bit DAC, but can gain a bit back for 9bits if down doesn't have to equal up count.

Start with PWM output clear. Say the desired output value for this cycle is 100.5

1)First update cycle is "odd" operation and thus going to simulate down counting. By convention let's round down on odd/down cycles, so this half's output is 100. Being an odd cycle we subtract 100 from the top value 255. We place this difference of 155 in the compare register. When reached the output PWM pin toggles high.

2)Next output cycle occurs, this one is "even" normal up counting. Round up this time from 100.5 to 101. The 101 value is simply placed in the compare register. When reached the output PWM pin toggles low.

3) Calculate next DAC output value and go to step 1.

While this idea works, the added interrupt for step 2 will be costly for the STM8. Interrupts cost a whopping 20 cycles (9 pushes, 2 jump isr, 9 pops). This scenario requires two interrupts per 512 clock update cycle. That's 4% CPU resources for the added interrupt entry/exit, prob need another 5-10 cycles to support the added complexity running each isr, so that's another ~4%, for a total CPU resource cost of 8%. Doesn't seem worthwhile at this point anyway when we've got better things to do with that CPU time. So while this whole trick is viable, but I've now sufficiently talked myself out of it...

I sure wish all those excessive register pushes for STM8 ISRs wasn't there. Much more convenient how the 6502 only pushes PC & SR.. Leave it to the ISR to decide what registers are worth preserving! Worst part about it is, the built in pushes aren't any faster than manual pushing; all they're saving is code bytes.

_________________
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers


Top
 Profile  
 
PostPosted: Wed Oct 04, 2017 11:26 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6280
Location: Seattle
One little caveat about the "just use a count-up / count-down PWM and alternate direction every reload" — it effectively halves your sample rate (and adds one to the bit depth), producing modulation noise at IRQ frequency/2.

15.5kHz is still high enough that it's likely not an issue, but it's worth keeping in mind.


Top
 Profile  
 
PostPosted: Wed Oct 04, 2017 11:56 am 
Offline
User avatar

Joined: Mon Apr 04, 2011 11:49 am
Posts: 1905
Location: WhereverIparkIt, USA
lidnariq wrote:
One little caveat about the "just use a count-up / count-down PWM and alternate direction every reload" — it effectively halves your sample rate (and adds one to the bit depth), producing modulation noise at IRQ frequency/2.


Yeah my initial thought was to run the synth engine on each count "direction" to keep from changing the sample rate. But that doubles the synth computation load in order to keep the same PWM frequency. With limited timer clock speed, and limited CPU resources, there's no way to get around some sort of trade off when going from fast/edge to center/phase correct. And with your conclusion of giving up 1 bit of resolution not being worth gaining center aligned, I question if center aligned is ever worthwhile in a system operating near it's constraints.

_________________
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers


Top
 Profile  
 
PostPosted: Mon Oct 09, 2017 9:47 pm 
Offline
User avatar

Joined: Mon Apr 04, 2011 11:49 am
Posts: 1905
Location: WhereverIparkIt, USA
Quick little update, testing out the PWM DAC with a simple middle C square wave. Current PWM DAC is the standard 3.9k 4.7nF (8.7Khz cutoff) low pass filter fed directly to EXP6. Then fed through the 'standard' 47k EXP audio resistor I was able to achieve a volume comparable to one of the 2a03's squares at full volume. Things went according to my plan here with a DAC setting of ~12% the CICOp square was audibly similar to the 2a03 square in volume and timbre. I haven't came up with a means to objectively compare the two, but using my ears alone the CICOp may have sounded a little "warmer" but honestly I could be mistaking that based on slight difference in volume. In any event I'm happy with the preliminary performance of this simple setup!

I took a handful of different scope measurements, still blows me away that the PWM DAC sounds as good as it does despite how it looks! [EDIT: all measurements taken with 10x probe]

Realizing a limitation of running at PWM frequency of 31Khz is the min period resolution of 32usec which I assume will prove troublesome for keeping higher pitched notes in tune.. I may be able to pull off 62Khz, but I'm wondering if this could be made up for by counting fractional steps and then rounding each period. Where the the average of something like 4 cycles would be in tune effectively providing 8usec period resolution. Have a feeling a hack like that has some (audible) drawback but I don't really know..


Attachments:
File comment: 31Khz PWM noise alive and well at output level ~3.1vdc
image.jpg
image.jpg [ 1.42 MiB | Viewed 133 times ]
File comment: Middle C, measured on main board 20k mixing resistor (between 47k exp resistor)
image.jpg
image.jpg [ 1.44 MiB | Viewed 133 times ]
File comment: Middle C, output of PWM DAC
image.jpg
image.jpg [ 1.39 MiB | Viewed 133 times ]
File comment: Step response from 5v->0v, then ramp to 5v in one step increments.
image.jpg
image.jpg [ 1.39 MiB | Viewed 133 times ]

_________________
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers


Last edited by infiniteneslives on Tue Oct 10, 2017 9:14 am, edited 1 time in total.
Top
 Profile  
 
PostPosted: Mon Oct 09, 2017 9:58 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6280
Location: Seattle
infiniteneslives wrote:
Realizing a limitation of running at PWM frequency of 31Khz is the min period resolution of 32usec which I assume will prove troublesome for keeping higher pitched notes in tune.
It isn't necessary to have pitches be integer divisors of your sample rate.

It's true that square waves (or anything else with more higher frequency content) will start having audible aliasing artifacts if you just use nearest-neighbor=sample-and-hold resampling, but that can be fixed or worked around in a variety of ways.

Quote:
I'm wondering if this could be made up for by counting fractional steps and then rounding each period. Where the the average of something like 4 cycles would be in tune effectively providing 8usec period resolution. Have a feeling a hack like that has some (audible) drawback but I don't really know.
That's actually literally how the Namco 163 works. The waveform position there is 8.16 fixed point (and the pitch is 2.16 fixed point). The SNES does something similar (pitch is 2.12 fixed point), but it adds an interpolator ("Gaussian") to reduce aliasing noise (and everything else high frequency, oops)


Top
 Profile  
 
PostPosted: Thu Oct 12, 2017 1:18 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5718
Location: Canada
Yeah, with accumulator based tones (e.g. N163, FDS, SID) it's not a divider of the clock frequency, and your low pitch precision ends up at low frequencies instead of high.

It's the inverse of the clock divider approach (e.g. 2A03, VRC6, AY).

I think the main difference is that the divider gets a lot more range with less bits in the register, and only has to increment instead of doing a full add. (Also at 31 kHz you'll have audible aliasing, but probably acceptable. No worse than N163 in 4 channel mode.)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 96 posts ]  Go to page Previous  1 ... 3, 4, 5, 6, 7

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group