kool kitty89 Posted October 26, 2015 Share Posted October 26, 2015 I'm not sure if this technique is ever actually used in existing games or demos, but using 2 POKEY channels and two timers, it should be possible to get 8-bit linear PCM output through POKEY. Set one timer to the desired sample rate and set one 4-bit volume level for the upper 4 bits of a sample while the lower 4 bits go to the other channel. The second channel gets its volume then cut again to 1/16 by using the second timer to set the duration of the pulse to 1/16 of a sample period. Yes you'd get noise at low sample rates (more and more audible below 11 kHz) but that's true to some extent for harmonics of low sample rate PCM in general. (and not the same sort of squeal and noise as 1-bit PDM/PWM on a PC speaker or beeper or whatnot) Using cycle timed loops instead of interrupts (or polling) for the timing would also be possible. I also know using 4-bit samples in general is often more practical on the A8 due to memory constraints (and SNR often favoring 4 bit over 8 bit at low bitrates) and that PCM playback is also CPU intensive (from previous talks with malducci, I believe 50 cycles per interrupt for decently tight code) and this method would be more CPU intensive than straight 4-bit playback, but it still seems interesting at least. (8-bit output is better for software mixing too, but that's only good if you have free cycles to dedicate to mixing, and I know multiplexing 4-bit samples on a single channel is also an option there) I may also be misusing the term PDM, pulse-width modulation might be more correct here, but I think PDM applies. (there isn't really modulation involved either, just fixed pulse width of the lower channel ... you COULD modulate a single channel to get those added 16 volume levels, but that still takes 2 timers -or careful coding- and I don't think would sound as good) 16 Quote Link to comment Share on other sites More sharing options...
tebe Posted May 5, 2018 Share Posted May 5, 2018 http://atariage.com/forums/topic/278463-pwm-experiments/ Quote Link to comment Share on other sites More sharing options...
Xuel Posted May 7, 2018 Share Posted May 7, 2018 Amazing idea!I implemented my take on your idea here:github.com/lybrown/hifiExample:aha.car.zipLonger example:thecart.car.zip (21MB, 10 minutes)I implemented 44270Hz but there's headroom to go up to 65520Hz if I take out all of the NOPs.In Altirra you can press Ctrl+Alt+1 to toggle POKEY channel 1 where the lower 4-bits are being played, so you can hear what it sounds like with just the upper 4-bits being played as normal PCM on channel 2. You can also press Ctrl+Alt+2 to toggle channel 2 so you can hear what the lower 4 bits sound like. (Hint: it basically sounds like noise. )I ran the 1/16 signal as fast as it can go so it's running at 111Khz (1.77Mhz / 16). At that frequency you don't really have to synchronize the signal with the PCM signal. You can just apply the 4 lower bits to the 111Khz signal and roughly three pulses will be played at that volume.Curious if anyone with a The!Cart can try this on real hardware. 14 Quote Link to comment Share on other sites More sharing options...
Xuel Posted May 7, 2018 Share Posted May 7, 2018 Correction: The 1/16 signal is running at 55.4KHz. I forgot that you have to divide by 2! All the more amazing to me that this works as well as it does then, since you're only getting about 1.25 pulses per sample. I guess that's enough.Maybe I'll try pegging to as close to 1 pulse per sample as possible and see how that sounds... Note: For best quality in Altirra, I've found it's best to disable non-linear mixing. This could bode poorly for the quality on real hardware. Maybe if we massage the waveform to fit the 256 voltage-levels observed on real hardware we can improve things. Quote Link to comment Share on other sites More sharing options...
NRV Posted May 7, 2018 Share Posted May 7, 2018 Nice! Two questions.. would doing: lda hi,x ldy lo,x sta audc2 sty audc1 instead of: lda hi,x sta audc2 lda lo,x sta audc1 ..improve anything? And do you think it still would sound good at 15.7 KHz? 1 Quote Link to comment Share on other sites More sharing options...
Rybags Posted May 7, 2018 Share Posted May 7, 2018 That sounds pretty good, the notice definitely noticable. Strange request though... even without the low bits it sounds way better than most A8 sampling due to the high rate. How about a test at lower bitrates like 8, 16 KHz? 1 Quote Link to comment Share on other sites More sharing options...
Sheddy Posted May 7, 2018 Share Posted May 7, 2018 Note: For best quality in Altirra, I've found it's best to disable non-linear mixing. This could bode poorly for the quality on real hardware. Maybe if we massage the waveform to fit the 256 voltage-levels observed on real hardware we can improve things. Presumably the real voltage levels are very close together at higher volumes, losing effective bits in the same way as PCM(?) BTW this is all very awesome! Quote Link to comment Share on other sites More sharing options...
R0ger Posted May 7, 2018 Share Posted May 7, 2018 Damn that's smooth. And such a simple idea ! Great job ! Quote Link to comment Share on other sites More sharing options...
R0ger Posted May 7, 2018 Share Posted May 7, 2018 Correction: The 1/16 signal is running at 55.4KHz. I forgot that you have to divide by 2! All the more amazing to me that this works as well as it does then, since you're only getting about 1.25 pulses per sample. I guess that's enough.Maybe I'll try pegging to as close to 1 pulse per sample as possible and see how that sounds... Note: For best quality in Altirra, I've found it's best to disable non-linear mixing. This could bode poorly for the quality on real hardware. Maybe if we massage the waveform to fit the 256 voltage-levels observed on real hardware we can improve things. That's actually great. I mean the fact the 1/16 signal doesn't have to run at sample frequency at all. You can the 8kHz sample rate without the 1/16 signal being audible. Simply run the 1/16 signal as high as real hardware can reliably mix it. 1 Quote Link to comment Share on other sites More sharing options...
xxl Posted May 7, 2018 Share Posted May 7, 2018 another barrier was broken. 1 Quote Link to comment Share on other sites More sharing options...
gorgh Posted May 7, 2018 Share Posted May 7, 2018 amazing quality! Quote Link to comment Share on other sites More sharing options...
mono Posted May 7, 2018 Share Posted May 7, 2018 You are the star! 4.4 samples Quote Link to comment Share on other sites More sharing options...
antrykot Posted May 7, 2018 Share Posted May 7, 2018 (edited) Correction: The 1/16 signal is running at 55.4KHz. I forgot that you have to divide by 2! Its frequency really is 110840 Hz (PAL), there is no divide by two when hi-pass filter is enabled. Edited May 7, 2018 by antrykot 1 Quote Link to comment Share on other sites More sharing options...
+Stephen Posted May 7, 2018 Share Posted May 7, 2018 Wow - sound is just incredible! Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted May 7, 2018 Share Posted May 7, 2018 This is bloody remarkable. Pity there isn't time to issue IDE sector read requests, otherwise we could play huge files direct from FAT partitions on one of the currently available hard disk solutions. Really astounding quality, though. 2 Quote Link to comment Share on other sites More sharing options...
Xuel Posted May 7, 2018 Share Posted May 7, 2018 Its frequency really is 110840 Hz (PAL), there is no divide by two when hi-pass filter is enabled. Oh yeah, because the waveforms are XOR'ed so you get two pulses per period. Awesome! BTW, I tried other periods like 1/13, 1/14, 1/15, 1/17 and some of them sound pretty good. Maybe something to tune for real hardware? Nice! Two questions.. would doing: lda hi,x ldy lo,x sta audc2 sty audc1 instead of: lda hi,x sta audc2 lda lo,x sta audc1 ..improve anything? And do you think it still would sound good at 15.7 KHz? I actually had it that way at first (first version), but I was trying to make the cart code simpler so I tried it the other way and it sounded the same to me. Need to break out the test and measurement equipment for a quantitative answer. That sounds pretty good, the notice definitely noticable. Strange request though... even without the low bits it sounds way better than most A8 sampling due to the high rate. How about a test at lower bitrates like 8, 16 KHz? On my todo list. Presumably the real voltage levels are very close together at higher volumes, losing effective bits in the same way as PCM(?) BTW this is all very awesome! That's what I'm guessing as well. I wonder if there are also non-monotonic transitions in POKEY's DACs like there are in GTIA for example between luminances 7 and 8 in 16-luma mode. Maybe if we had an accurate model of POKEY's DACs we could massage the waveform data to compensate. This is bloody remarkable. Pity there isn't time to issue IDE sector read requests, otherwise we could play huge files direct from FAT partitions on one of the currently available hard disk solutions. Really astounding quality, though. I wouldn't say IDE is out of the question. There's quite a bit of CPU left over. 2 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted May 7, 2018 Share Posted May 7, 2018 I wouldn't say IDE is out of the question. There's quite a bit of CPU left over. I ran the AHA tune in Altirra and it looked like the CPU was flat-out at first, but I can see now the NOP and there's also time to update HPOSP0 every few cycles, so yeah. The trick will be waiting for the IDE sector buffer to become ready after a read request. Ideally you'd continue playing during that phase, but since we'd be feeding directly off the IDE data register, we'd be stuck for a few milliseconds waiting for the data to become ready. Such a player would be pretty convenient, though. 4 Quote Link to comment Share on other sites More sharing options...
ivop Posted May 7, 2018 Share Posted May 7, 2018 Very nice results! Could you manage to put the main play loop in page zero? If so, you can save two cycles (inc play+1 and inc play+2). They might come in handy 4 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted May 7, 2018 Share Posted May 7, 2018 Just thinking: we don't need a pointer at all if reading from the IDE data register: it's just repeated loads from the same location, plus the overhead of reading the next cluster (assuming we issue multi-sector reads to grab whole clusters at a time). 3 Quote Link to comment Share on other sites More sharing options...
twh/f2 Posted May 7, 2018 Share Posted May 7, 2018 Holly shit. Really PCM 8bit @ 44khz ?! This sounds amazing. What a great idea. So can this idea be applied only with Pokey or is that idea convertible to e.g. C64 SID? (I'm asking that I can provocate my C64-fanboy neighbor *gg) Quote Link to comment Share on other sites More sharing options...
twh/f2 Posted May 7, 2018 Share Posted May 7, 2018 I wouldn't say IDE is out of the question. There's quite a bit of CPU left over. At at the end you guys discover that there is still CPU left for some smart MP3-decoding *ggg But honestly, how much of an impact to quality would it be with IDE data feed? Quote Link to comment Share on other sites More sharing options...
Xuel Posted May 7, 2018 Share Posted May 7, 2018 Holly shit. Really PCM 8bit @ 44khz ?! This sounds amazing. What a great idea. So can this idea be applied only with Pokey or is that idea convertible to e.g. C64 SID? (I'm asking that I can provocate my C64-fanboy neighbor *gg) See here. 1 Quote Link to comment Share on other sites More sharing options...
twh/f2 Posted May 7, 2018 Share Posted May 7, 2018 dammit 1 Quote Link to comment Share on other sites More sharing options...
flashjazzcat Posted May 7, 2018 Share Posted May 7, 2018 (edited) But honestly, how much of an impact to quality would it be with IDE data feed? Avery's video player issues multi-sector reads (17 sectors) and expects the data to be ready 4ms after issuing the command, and this equates to 47 scan lines (during which he plays buffered audio). Here, we'd be issuing 8 sector or 16 sector reads (for 4K or 8K clusters), with the sector numbers derived from a pre-computed list built when traversing the FAT chain when the file was first opened. So it seems to me some clever method of keeping the player running during that 4ms wait period is required (it may be less than 4ms, and we can get out early by polling the DRQ bit). Perhaps some clever interleave would allow preparation of a cache large enough to keep things moving during down-time. This is all assuming the current data rate is somehow preserved, ideally resulting in no quality reduction. Edited May 7, 2018 by flashjazzcat 2 Quote Link to comment Share on other sites More sharing options...
emkay Posted May 7, 2018 Share Posted May 7, 2018 dammit Not sure how they managed it on the C64, but it sounds like pressed through a compander. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.