Jump to content

Photo

PCM audio experiment


32 replies to this topic

#1 phaeron OFFLINE  

phaeron

    Stargunner

  • 1,107 posts
  • Location:USA

Posted Sun Oct 16, 2011 5:10 AM

For a while now, I've been thinking about ways to do PCM audio on the 8-bit Atari better than the standard 4-bit PCM through volume-only mode. The way this used to be done with the PC speaker was through one-shot mode, which unfortunately POKEY lacks. I tried doing this with two-tone mode but wasn't able to get more than about 4.5-bit precision due to only being able to use the second half of each period. I realized last night that 16-bit linked timers could be used to create a one-shot timer by using the high timer to hold down the low timer after it has fired. The result is the attached music. I'm interested in knowing if it works for other people on real hardware, since the noise is less than I expected (there is a 15KHz carrier due to the technique used). You probably won't be able to get it running if you have a 65C02 or 65C816 due to a hack I used in the timer IRQ. Some of the 2.0 test builds of Altirra also have a regression in STIMER handling that prevents this from playing properly; 1.9 is OK, and this version has a bug fix:

http://www.virtualdu...2.00-test43.zip
http://www.virtualdu...-test43-src.zip

The output sample precision is about 6.7 bits, but the volume is a bit low because three voices are being mixed.

Attached Files



#2 Rybags OFFLINE  

Rybags

    Quadrunner

  • 12,176 posts
  • Location:Australia

Posted Sun Oct 16, 2011 5:26 AM

Nice. Why are you wanting a 1-shot Timer mode - Do you have variable delay among the samples?

Is this actually PWM ? I've just had a quick look through the code (it's a little hard to work out what's going on).

Also, have you considered doing away with IRQs and just using polling mode? The cycles saved might allow you to bump up the sample rate and/or have a screen active.

#3 MaPa OFFLINE  

MaPa

    Dragonstomper

  • 730 posts
  • Location:Czech Republic

Posted Sun Oct 16, 2011 5:38 AM

Nice.. it works on my real Atari 800 XL.

#4 drac030 OFFLINE  

drac030

    Stargunner

  • 1,306 posts
  • Location:Warszawa, Poland

Posted Sun Oct 16, 2011 6:54 AM

Plays nice on a real 130XE (PAL). The carrier is audible, but it is not so bad as on Altirra 1.9.

#5 Tezz OFFLINE  

Tezz

    River Patroller

  • 2,086 posts
  • Location:Manchester, England

Posted Sun Oct 16, 2011 7:33 AM

Impressive under emu. I'll have to check it out on the real hw tonight.

#6 drac030 OFFLINE  

drac030

    Stargunner

  • 1,306 posts
  • Location:Warszawa, Poland

Posted Sun Oct 16, 2011 9:25 AM

PS. phaeron, the emulator you posted here has broken support for ATRs with 512 bytes per sector: the sector 1 cannot be accessed at full size.

#7 phaeron OFFLINE  

phaeron

    Stargunner

  • Topic Starter
  • 1,107 posts
  • Location:USA

Posted Sun Oct 16, 2011 1:40 PM

Nice. Why are you wanting a 1-shot Timer mode - Do you have variable delay among the samples?
Is this actually PWM ? I've just had a quick look through the code (it's a little hard to work out what's going on).


The one-shot delay is how the sample is actually played. Timers 1+2 are configured in 16-bit mode but only timer 1 is enabled for sound. The IRQ routine hits STIMER to reset the outputs and writes the sample to AUDF1, causing a variable delay until the output toggles back. Because the two timers are in a 16-bit configuration, timer 1 can't fire again until a full 256 cycles and the IRQ routine runs again before this happens. Timer 4 drives the IRQ and runs off the 15KHz clock, which means it ignores the jitter caused by writing STIMER.

It's actually possible to run two voices this way, but you either have to restrict one to half volume (channel 3 only) or give up the IRQ timer (channels 3+4 linked). It's also possible to run an envelope on the voice by modifying AUDC1 but I abandoned that because it made the carrier beat as well.

Also, have you considered doing away with IRQs and just using polling mode? The cycles saved might allow you to bump up the sample rate and/or have a screen active.


I did, but that makes it difficult to run any other code. Currently, the mixer runs off the IRQ in page zero while the mainline plays notes and updates ADSR envelopes every 128 scanlines (I'm too lazy to change the MIDI parser back to VBI timing).

Currently, the IRQ takes about 85% of the CPU according to the profiler. The lowest I've gotten it with three voices is about 63% without the mixing clamp. I thought about polled operation as it would save a bunch of cycles, but that makes it much harder to run anything else in mainline, whereas this way you can run pretty much anything as long as there is enough CPU time. I tried to use the serial port to clock the IRQ to avoid needing to toggle IRQEN, which was 6 cycles faster, but the fastest I could run it was about 12.7KHz which drops the carrier too low in frequency. The main problem is that the 6502 just isn't very fast at updating the oscillators. I wonder how fast the VBXE blitter could do this -- if it could mix enough channels it could be enough to play some SNES music.

#8 Stephen OFFLINE  

Stephen

    River Patroller

  • 4,443 posts
  • A8 Gear Head
  • Location:Akron, Ohio

Posted Sun Oct 16, 2011 1:46 PM

Works fine on my NTSC 130XE.

#9 phaeron OFFLINE  

phaeron

    Stargunner

  • Topic Starter
  • 1,107 posts
  • Location:USA

Posted Mon Oct 17, 2011 12:30 AM

Cool, thanks for testing.

Attached is little experimentation with a straight sound sample (the music clip is from an anime called Carnival Phantasm). This one requires 128K. The audio.obx file uses PWM, whereas audio-vol.obx uses traditional 4-bit volume only mode. The PWM output has less noise but you hear the carrier instead. I tried dropping the sample rate to 10KHz and then doubling it to 20KHz in the IRQ routine, but for some reason the carrier actually got louder. Rats. It works, but it's not something you'd want to listen to for a long time. I guess this technique belongs in the past with the original PC and the PalmPilot. :)

Attached Files



#10 Rybags OFFLINE  

Rybags

    Quadrunner

  • 12,176 posts
  • Location:Australia

Posted Mon Oct 17, 2011 1:00 AM

On my "to-do" list is using VBXE to do the pick + mixing of virtual channels for digital sound.

The idea I have is to use the "ADD" mode to step through the waveforms, which would need to be massively repeated through VRAM. Then add all of the amplitudes together to get an 8-bit value and use a table lookup for AUDC values to store in 4 voices.

Not having 16-bit add of course makes things somewhat harder, but I reckon VBXE should allow many more virtual voices than a CPU only based system.

I wonder - could the carrier wave be attenuated a little by playing the same frequency pure tone on a pair of the opposite channels - or maybe by just playing a forced volume square wave on another channel?

#11 ANTIQ OFFLINE  

ANTIQ

    Chopper Commander

  • 132 posts

Posted Mon Oct 17, 2011 4:30 AM

Is it possible to improve PWM / PDM with the high-pass filter?

#12 Rybags OFFLINE  

Rybags

    Quadrunner

  • 12,176 posts
  • Location:Australia

Posted Mon Oct 17, 2011 4:35 AM

No. High-pass Filter is kind of the wrong name for it anyway, it's more of a frequency dependant AND gate.

#13 Stephen OFFLINE  

Stephen

    River Patroller

  • 4,443 posts
  • A8 Gear Head
  • Location:Akron, Ohio

Posted Mon Oct 17, 2011 5:20 PM

These will not load for me under SDX 4.44 and IDE + 2.0 (using the X command) and the machine just hangs. The machine is an NTSC 320kB 130XE. Your first demo did.

P.S.
These run under MyDOS 4.53 but that feels dirty and I have to load via SIO, not IDE+ :)

#14 drac030 OFFLINE  

drac030

    Stargunner

  • 1,306 posts
  • Location:Warszawa, Poland

Posted Mon Oct 17, 2011 5:55 PM

These will not load for me under SDX 4.44 and IDE + 2.0 (using the X command) and the machine just hangs. The machine is an NTSC 320kB 130XE. Your first demo did.


This is probably a question of "proper" order of ext allocation. Sparta X uses the order "the farest banks first", i.e. 130XE banks will be allocated last. Programs should allocate in reverse order. But some use the same order as SDX and so the DOS gets destroyed.

These run under MyDOS 4.53 but that feels dirty and I have to load via SIO, not IDE+ :)


You can still load them using the IDE+ binary loader.

Edited by drac030, Mon Oct 17, 2011 5:55 PM.


#15 phaeron OFFLINE  

phaeron

    Stargunner

  • Topic Starter
  • 1,107 posts
  • Location:USA

Posted Tue Oct 18, 2011 2:06 AM

A low-pass filter is what is actually needed here, specifically one that cuts off 15.7KHz and above (they're called low pass and high pass after which frequencies they allow through). This is a bit short of POKEY's capabilities, though.....

My first thought on the SDX load failure was also bank conflict, but that wasn't it... turns out the SDX loader simply didn't like me fiddling with PORTB at all. Changing the banks in the 320K configuration didn't help and didn't work even with 128K and USE OSRAM. I was configuring the extended bank and then letting DOS load into it, which apparently SDX doesn't like, so I had to modify it instead to load through a temporary buffer and then copy in. I've included updated versions that should load now under SDX with the X command, although you'll need to run OSRAM if you're using all of extended memory. There are 128K, 192K, and 320K versions included now. Sorry, I hardcoded the banks because I'm an extended RAM n00b.

Also included is an experiment at reducing the carrier. Switching to polling already helped a little bit -- at least, given my level of hearing, your dog may disagree -- but another thing I'm trying in this version is adding a little bit of inverted carrier using channel 3 to try to partially cancel it. I tried using two channel pairs to get double precision and volume but had problems with excessive distortion. I'm guessing the cause has to do with POKEY's nonlinear output.

Attached Files



#16 serj OFFLINE  

serj

    Star Raider

  • 75 posts
  • Location:Russia, Omsk city.

Posted Tue Oct 18, 2011 2:59 AM

so here is why you named your emulator "altirra", you're a big fan of anime. )))

#17 MaPa OFFLINE  

MaPa

    Dragonstomper

  • 730 posts
  • Location:Czech Republic

Posted Tue Oct 18, 2011 4:55 AM

I would like to hear more test as the first one ;)

#18 Mclaneinc ONLINE  

Mclaneinc

    Stargunner

  • 1,900 posts
  • Location:Northolt, UK

Posted Tue Oct 18, 2011 6:05 AM

so here is why you named your emulator "altirra", you're a big fan of anime. )))



Lol...You took your time Sergey....

This was answered moons ago on the blog after I asked him a few times :)

@Phaeron: Did you see the post from Draco about the broken ATR 1st sector in this thread?

#19 drac030 OFFLINE  

drac030

    Stargunner

  • 1,306 posts
  • Location:Warszawa, Poland

Posted Tue Oct 18, 2011 7:31 AM

@Phaeron: Did you see the post from Draco about the broken ATR 1st sector in this thread?


Yes, he did. We have swapped few PMs about that, but no solution so far. Basically the problem is that when Altirra "mounts" ATR images from the saved configuration, 512-byters are not accessible because the emulator thinks they're 90k SD disks. Therefore the PERCOM block returned on an inquiry is wrong, in consequence SDX and tools get fooled into thinking that the sector size is 128 bytes, etc.

The problem disappears, when you open the File -> Disk drives and "remount" the ATRs in question manually. However, when you quit Altirra and load it back, the problem returns.

Edited by drac030, Tue Oct 18, 2011 7:33 AM.


#20 ANTIQ OFFLINE  

ANTIQ

    Chopper Commander

  • 132 posts

Posted Tue Oct 18, 2011 8:05 AM

I haven't looked at the high-pass filter / polycounters in depth but here are two general observations:

1. Many different bit sequences have the same average but some may integrate better than others.

2. It may be possible to play deeper samples using 4 or 5-bit volume-only mode for the MSBs and PWM / PDM for the LSBs.

#21 Mclaneinc ONLINE  

Mclaneinc

    Stargunner

  • 1,900 posts
  • Location:Northolt, UK

Posted Tue Oct 18, 2011 8:13 AM

@Phaeron: Did you see the post from Draco about the broken ATR 1st sector in this thread?


Yes, he did. We have swapped few PMs about that, but no solution so far. Basically the problem is that when Altirra "mounts" ATR images from the saved configuration, 512-byters are not accessible because the emulator thinks they're 90k SD disks. Therefore the PERCOM block returned on an inquiry is wrong, in consequence SDX and tools get fooled into thinking that the sector size is 128 bytes, etc.

The problem disappears, when you open the File -> Disk drives and "remount" the ATRs in question manually. However, when you quit Altirra and load it back, the problem returns.



Thanks for passing that on Draco..

#22 Rybags OFFLINE  

Rybags

    Quadrunner

  • 12,176 posts
  • Location:Australia

Posted Tue Oct 18, 2011 8:24 AM

I haven't looked at the high-pass filter / polycounters in depth but here are two general observations:

1. Many different bit sequences have the same average but some may integrate better than others.

2. It may be possible to play deeper samples using 4 or 5-bit volume-only mode for the MSBs and PWM / PDM for the LSBs.


Filters - already established they're probably no use for digital stuff but the other factor is that they have no influence when you're using forced volume mode.

2. I reckon that might work really well. Traditional method for the higher bits and PWM to give the lower 3 or 4 bits. The advantage should be that the carrier frequency is a lot quieter.


Request to phaeron - how about some 8-bit stuff, use bits 7-3 with 2 voices in forced volume and bits 2-0 with another voice PWM? Or maybe start simple, just 4 bits forced on 1 voice, 2 or 3 bits PWM on another.

#23 MaPa OFFLINE  

MaPa

    Dragonstomper

  • 730 posts
  • Location:Czech Republic

Posted Tue Oct 18, 2011 12:30 PM

Btw. this Altirra version (test 43) has problem to correct display demo QLKEE i.e. The unlimited balls are not colorful.

#24 analmux OFFLINE  

analmux

    Stargunner

  • 2,088 posts

Posted Tue Oct 18, 2011 4:31 PM

@ phaeron

Don't forget the auto-PWM feature of the sawtooth wave. Using a sawtooth voice at lowest volume (1) you can use it to add some more amplitude precision.

The downside is the capacitor decharging effects. (Not only the non-linear effects of adding volume of multiple voices!)

#25 phaeron OFFLINE  

phaeron

    Stargunner

  • Topic Starter
  • 1,107 posts
  • Location:USA

Posted Tue Oct 18, 2011 11:43 PM

Hmm, lots of interest all of a sudden. I feel like I'm at a time zone disadvantage. :)

Music synthesis is more annoying to deal with than sample playback, so I jumped on the latter for a while. The results seem to be that it's pretty hard to get something significantly better, especially with what little CPU is available in the synth, so I think the digital part of the synth is about as good as it's going to get, except maybe I can add the channel 3 inverse carrier since it's free in terms of CPU time. Mixing volume only with PWM seems doable but much harder to deal with since the analog nature of the output has to be accounted for, and it's a lot harder to make sure the volume levels match up -- emulators are still very far from emulating analog effects properly. Activating more channels also increases distortion from high volume, which might be possible to compensate for with pre-distortion but I haven't looked into that.

In addition, I'd have to beef up the MIDI parser and VBI routine and create some new waveforms to get some new music in. Three channel polyphony isn't much but that could be made to work; the lack of percussion support is what worries me the most. Also, you'll have to suffer through whatever is in my MIDI directory. :-D

I'm working on the issues that Drac030 has identified with double and quad density disk support. I found what was causing the failures on boot -- the reset routine for the disk was reinitializing the PERCOM block to default instead of the one from the disk image -- but I still need to fix up a couple of issues in the SIO hook. Expect an update soon.

Oh yeah, about that demo... it seems to work fine for me (picture attached; test-44 only has disk changes from test-43). Note that Altirra doesn't emulate PAL color blending unless you enable PAL artifacting (this is actually a detail of the TV set decoding). I have to say, very colorful, though.

Attached Thumbnails

  • qlkee.png

Edited by phaeron, Tue Oct 18, 2011 11:48 PM.





0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users