Jump to content
IGNORED

PWM experiments


Recommended Posts



SAMPLING

By The Gatekeeper

Last issue, there where three great articles about sampling ( by AlphaSys and Frankenstein ! ) This time I would like to tell some more.


6-Bits play routine?
--------------------
First of all, I would like to give some more details about the, which Frankenstein called, 6-bit play method which I also used in my MOD-Player. Within the Pokey chip, the four audio channels are mixed together like this:


Channel1--|
|
Channel2--|
|------Audio Out
Channel3--|
|
Channel4--|


This way, if Channel1 has a volume of 15 and Channel2 one of 15 ( 3 and 4 are zero ) the Audio Out has a volume of 30 ! A little math tells us that 4 channels of 16 different volumes can give us 4*16=64 different Audio Out volumes. Right! Well, not exactly. :-)

C1:15 C2:00 C3:00 C4:00
C1:00 C2:15 C3:00 C4:00
C1:00 C2:00 C3:15 C4:00
C1:00 C2:00 C3:00 C4:15

have the same Audio Out. O.K. then it's three less. You still have 61 different output values. Alas, the XL isn't fast enough to output four values at 'almost' the same time. Take a look at this :-Q

LDA C1
LDX C2
LDY C3
STA $D201
STX $D203
STY $D205
LDA C4
STA $D207

The fourth channel is 'poked' to the right value 9.03 ms after channel one. In practice this turned out to be too slow... This means the XL can only use up to three channels which gives 46 different output values. Here they are:

C1 C2 C3 Result
---------------
00 00 00 00
01 00 00 01
02 00 00 02
. . . .
. . . .
14 00 00 14
15 00 00 15
15 01 00 16 <-- !!!
15 02 00 17
15 03 00 18
. . . .
. . . .
15 14 00 29
15 15 00 30
15 15 01 31 <-- !!!
15 15 02 32
15 15 03 33
. . . .
. . . .
15 15 14 44
15 15 15 45


This is not 6-bits but LOG(46)/LOG(2) = 5.52 bits. This is very unhandy. For example, take the MOD-Player. It has four channels, playing a sample in a resoltion of 4 bits. 4*(2^4) ends up into 64 different combinations, which needs 6 bits to be played without quality loss. Sadly, we only have 5.52 bits... We have to calculate 6 bits into 5.52 bits with this formula :

X=6-bits value
Y=5.52-bits value

Y = X / 64 * 46

Well, try this in Machine Language, and you'll be happy if you get a replay speed of 1 kHz ! Solution : Look-Up Table !!!


The Look-Up Table
-----------------
You build up three tables, one for each channel, containing 64 values, the values that have to be played for that 6-bits combination. Then, a certain sample can be played by this small routine :

TABLE1 EQU $2000
TABLE2 EQU $2040
TABLE3 EQU $2080

PLAY LDX VALUE

LDA TABLE1,X
PHA
LDY TABLE3,X
LDA TABLE2,X
TAX
PLA

STA $D201
STX $D203
STY $D205

RTS

VALUE DFB 0


On Side-B you'll find a small Turbo-Basic program which builds up these three tables. It'S briefly documented, so I won't tell anything more about it here...


Oversampling
------------
Frankenstein mentioned the term oversampling in his theory article. I really agree with him, that the meaning of it is getting vague. A lot of people use it in a different context and don't tell what they actually mean. I'm sorry to say, but to my opinion, Frankenstein is also wrong. He combined two subjects into one. The method of calculating values between to samples and the result of that, having a higher replay frequency. Let's get a clear mind ! (?)

Oversampling : When you digitaly record an audio signal, with a frequency spectrum ranging from 20 Hz to 20 kHz, the theory of Nyquist tells us you need a recording frequency of at least 40 kHz. Two times the highest input frequency that is. Now, it's called oversampling when the samplefrequency is not twice the input frequency, but e.g. 5 or 10 times. It's used to lessen the terrible effect of high frequencies.

But what about that calculating of values between two taken samples ? Well, that is called interpolation. CD-Players use interpolation technics to 'recover' lost data. Take this situation. An (imaginairy) 2-bits CD-Player has read the following values :


A 11|* *l
^ 10|** *o *
| 01|** **s**
00|*****t**
----------
abc --> t


After the second occurance of %11, the player wasn't able to regain the sample information. Now it can just play the %11 again ( 0-order ), but it can also calculate the so called 'expected value'.

b = ( a + c ) / 2

This is interpolation of the first order. ( Lineair Interpolation. ) There are also higher order interpolation technics using logarithmic functions, sines and cosines etc.

As Freddy told us, it's possible to calculate all averages of two samples, and play this one between the two known samples. The resulting data-stream has to be played twive as fast as the original, that results in 1 time oversampling. Processing the 1 time oversampled data stream once again results in 2 times oversampling etc.


Analog Filters
--------------
With two components, a resistor and a capacitor, you can filter out either low and high frequencies. Take a look ate the following two schemes :

----
In -----| R1 |-------- Out
---- |
|
___
___ C1
|
|
GND _figure 1_

||C1
In -----||------------ Out
|| |
-
| |
|R|
|1|
| |
-
|
GND _figure 2_

Figure 1 will push down high frequencies above a certain f(R,C) and figure 2 pushes down all frequencies below f(R,C).

f(R,C) = 1 / ( 2*pi*R*C )

e.g. R=1K C=10 pF --> f=15.9 kHz

All frequencies above or under 15.9 kHz will be pushed down.


Digtal Filtering
----------------
First of all, you don't need to use oversampling for digtal filtering. It's based on taking not a 100% of the next sample taken. That way, high frequencies will fade away. You can simulate both RC-Filters seperately, but not together.

The essention of this algorithm is to add only a fraction of the new sample to a fraction of the old one. Watch this :-) a=1/2 b=1/2 (-:

Last Sample New Sample Calculated...
(Y) (X) (aY+bX)

128 140 134
134 (!) 144 139
139 151 145
145 143 144


Mention that a+b=1 and a>=b. All quick changes of amplitudo will dissapear. The imaginairy f(R,C) is very low when a>>b. To simulate the other RC-filter, bY has to be subtracted from aX. ( aX - bY | a+b=1 v a>=b ). All sorts of exotic filters are possible.


Modulation Technics
-------------------
There is a whole range of different modulation methods. Named here are only a few...


PAM - Pulse Amplitudo Modulation

%11 |*
%10 |**
%01 |***
%00 -----
abcd


PPM - Pulse Place Modulation

Pls | * * *
-----------------
a b c d


PWM - Pulse Width Modulation

Pls |*** ** *
-----------------
a b c d


PNM - Pulse Number Modulation

Pls |* * * * * *
---------------------------------
a b c d


PCM - Pulse Code Modulation

Pls |*** *
---------
a b c d


PAM is used on our XL/XE and so it is on ST(E)'s, Amigoes, MSX(2) and C64s. You can generate and n number of pulses, all with a different amplitudo. IBM compatible PC'S could use PAM, but they only have one bit and can therefore only generate block-waves. But wait a minute, all the other modulation technics only require two states. ( Pulse or no pulse ! ) That's why MOD-Players on PC use PWM. They just vary the width of the pulse. Be carefull, every pulse, no matter the length of the one before, starts at a certain frequency! Offcourse, there are a lot of disadvantages. The frequency of the starting points have to be very high so that one pulse sounds like PAM. Luckily the PC sound producer is VERY VERY BAD. It isn't able to produce sounds higher than 8kHz, therefore a starting point frequency of about 10 kHz is fine. Still you need at least a 12 MHz AT. Imagine you want an 4-bit play routine. The length of one period is 16. ( e.g. 15 times 1 and one time 0. ) Now the replay rate of all zeroes and ones is 160 kHz !!! ( This is still slow compared to the 2.56 MHz for an 8-bits player !!! )

Probably you think, why do you tell me this ? Our XL/XE is much too slow for this ! Then I must admit that you are right, but this last paragraph about modulation is not meant to be used in practice on an XL. It's just some more theoretical background. Maybe it inspires somebody to get one of these modulation technics working on a XL. ( What about some external hardware, producing a 1-bit PWM output from an 8-bit paralell digital input ? )


Well, this is the end. ( Finally. ) Let me tell you this, Frankenstein, I can secure you that there were two people that liked your article. ( Me and you that is ! ) I hope we like this one also !

Editor: Yes, I liked it. Thanx!


  • Like 5
Link to comment
Share on other sites

Is that understanding correct?

And why set 1.79 MhZ/16 bit and then keep the high value of the divisior at 255? More linear results? Or is the CPU simply to slow to set lo/hi of the frequency fas enough?

I have the same doubt about the setup. Probably Phaeron and Xuel can explain it better.

I would need to see some graphics to really understand how this technique works x)

 

Beyond 109, the pulse doesn't occur before the next scan line resets everything again with STIMER. The effect is that you get clipping.

Yep, I assumed 114 cycles for a scan line, without the 4 cycles for the next STA STIMER (110 different values, range from 0 to 109 for every sample).

For my 31KHz experiment I used 57-4 = 53 different values.

 

Can you reupload those pdm stuff with .car extension, so I could test it on Ultimate Cart? Thanks in advance! :)

Sure. I was waiting for people checking on more hardware, for the correct setup values.

Right now my previous PCM4+4 examples (ex PDM) only work in Altirra.

But it seems the values found by Phaeron are good to go (X=3, Y=5).

So here are the previous PDM examples converted for real hardware and also in .car format:

pdm_carts_rh.zip

 

At least in Altirra 3.10 test24 they should sound bad for now (with noise).

 

The PWM examples in the thread, already have .car files included.

By the way I generated the .car by saving the .bin from inside Altirra (with "Save Firmware").

 

Regards.

  • Like 3
Link to comment
Share on other sites

I have the same doubt about the setup. Probably Phaeron and Xuel can explain it better.

I would need to see some graphics to really understand how this technique works x)

 

I believe this is explained in the last paragraph of the "Linked Timers" section in the Altirra Hardware Reference Manual. You are taking advantage of the one-shot produced by channel 1 of a channel 1+2 linked timer setup. Setting AUDF2 to anything greater than or equal to 1 will work. That insures that channel 1 will behave as follows: it will pulse after AUDF1 cycles and won't pulse again for another 256 cycles. This occurs because AUDF1 keeps running without reloading even though it has underflowed. This occurs because when the timers are linked, they both reload only when AUDF2 has underflowed. Since STIMER is strobed every 114 cycles, you never reach that second pulse.

 

Yep, I assumed 114 cycles for a scan line, without the 4 cycles for the next STA STIMER (110 different values, range from 0 to 109 for every sample).

I think the max value is actually 100 not 109. phaeron's audio encoder for 60FPS video uses 100. See here. This probably has to do with the number of cycles required for resetting the counters with STIMER.

Edited by Xuel
  • Like 4
Link to comment
Share on other sites

Sure. I was waiting for people checking on more hardware, for the correct setup values.

Right now my previous PCM4+4 examples (ex PDM) only work in Altirra.

But it seems the values found by Phaeron are good to go (X=3, Y=5).

 

TBH, I've already converted them with JAC!'s Atari ROMmaker and was a bit curious why it plays right with Alirra 3.00 and not on on my trusty 800XE.

But I was near sure I've done something wrong. Thanks for infos anyway! :)

Link to comment
Share on other sites

Right now my previous PCM4+4 examples (ex PDM) only work in Altirra.

 

Hehe, so if people implement new hardware tricks first on the emulator, I guess that says a lot about the assumed level of emulation we have reached there :-)

  • Like 6
Link to comment
Share on other sites

I think the max value is actually 100 not 109. phaeron's audio encoder for 60FPS video uses 100. See here. This probably has to do with the number of cycles required for resetting the counters with STIMER.

 

My memory's a bit hazy on this, but I think you have to be a bit conservative because there is a small window where the clock pulse from the last underflow can leak through even after you've hit STIMER, due to the delay it takes for the underflow pulse to get through the circuitry. You'd expect it to just clamp because the pulse never occurs, but you actually get some pretty distorted sound instead. This also makes the max value dependent upon how tight you can get the timing -- the more jitter you have in samples, the more you'll need to lower the max value and therefore the dynamic range. The best version of the 60fps player I posted still has a couple of cycles of jitter in the sample playback.

  • Like 4
Link to comment
Share on other sites

  • 1 month later...

I did some experiments with the screen "on", sometime ago, and this is one of them.

Music was provided by Rybags, from the RoadBlasters arcade game (who has a Yamaha chip and a Pokey :)).

 

post-11240-0-18114100-1529808909.gif

 

roadb.zip

 

Source and 1MB carts provided.. (NTSC and PAL).

 

At some point I was going for this:

 

post-11240-0-66297100-1529808914.gif

 

But I don't have the cpu time to activate the players for now.

That would need another round of optimization and a little of luck :)

 

The code can play different tracks, in a sequence set in a table, so maybe it can be useful for someone.

 

Colors are done using a table indexed by VCOUNT.

Animation is done completely by Antic :D

Samples played using PCM4+4, at 8 bit depth, and 15720 Hz (one sample per scan line).

  • Like 13
Link to comment
Share on other sites

I did some experiments with the screen "on", sometime ago, and this is one of them.

Music was provided by Rybags, from the RoadBlasters arcade game (who has a Yamaha chip and a Pokey :)).

 

attachicon.gifroadb4c.gif

 

attachicon.gifroadb.zip

 

Source and 1MB carts provided.. (NTSC and PAL).

 

At some point I was going for this:

 

attachicon.gifroadb4d.gif

 

But I don't have the cpu time to activate the players for now.

That would need another round of optimization and a little of luck :)

 

The code can play different tracks, in a sequence set in a table, so maybe it can be useful for someone.

 

Colors are done using a table indexed by VCOUNT.

Animation is done completely by Antic :D

Samples played using PCM4+4, at 8 bit depth, and 15720 Hz (one sample per scan line).

That is awesome.

Link to comment
Share on other sites

Hehe, a still picture would do it for me - show the (converted) cover of a single, a maxi or an album, while playing the song, e.g. show the cover of Bon Jovi's "Living on a prayer", while playing this song. But then we should agree to one or several supported gfx formats, I guess (G2F, Rasta, G15 PAL blending, etc. would be nice, but I am not sure if CPU time would allow it; hopefully we are not limited to Gr.7, Gr.8 or Gr. 9)...

 

But as an animation, displaying a (fake) VU meter (digital or analog) or some kind of (fake) equalizer while playing a song would also be very nice...again, not sure if CPU time would allow it...

 

post-3782-0-30220800-1529865264.jpg post-3782-0-33048000-1529865276.jpg

 

post-3782-0-41129200-1529865287.jpg

 

  • Like 1
Link to comment
Share on other sites

 

SAMPLING
 
By The Gatekeeper
 
Last issue, there where three great articles about sampling ( by AlphaSys and Frankenstein ! ) This time I would like to tell some more.
 
 
6-Bits play routine?
--------------------
First of all, I would like to give some more details about the, which Frankenstein called, 6-bit play method which I also used in my MOD-Player. Within the Pokey chip, the four audio channels are mixed together like this:
 
 
Channel1--|
          |
Channel2--|
          |------Audio Out
Channel3--|
          |
Channel4--|
 
 
This way, if Channel1 has a volume of 15 and Channel2 one of 15 ( 3 and 4 are zero ) the Audio Out has a volume of 30 ! A little math tells us that 4 channels of 16 different volumes can give us 4*16=64 different Audio Out volumes. Right! Well, not exactly. :-)
 
C1:15 C2:00 C3:00 C4:00
C1:00 C2:15 C3:00 C4:00
C1:00 C2:00 C3:15 C4:00
C1:00 C2:00 C3:00 C4:15
 
have the same Audio Out. O.K. then it's three less. You still have 61 different output values. Alas, the XL isn't fast enough to output four values at 'almost' the same time. Take a look at this :-Q
 
     LDA C1
     LDX C2
     LDY C3
     STA $D201
     STX $D203
     STY $D205
     LDA C4
     STA $D207
 
The fourth channel is 'poked' to the right value 9.03 ms after channel one. In practice this turned out to be too slow... This means the XL can only use up to three channels which gives 46 different output values. Here they are:
 
C1 C2 C3 Result
---------------
00 00 00 00
01 00 00 01
02 00 00 02
.  .  .  .
.  .  .  .
14 00 00 14
15 00 00 15
15 01 00 16      <-- !!!
15 02 00 17
15 03 00 18
.  .  .  .
.  .  .  .
15 14 00 29
15 15 00 30
15 15 01 31      <-- !!!
15 15 02 32
15 15 03 33
.  .  .  .
.  .  .  .
15 15 14 44
15 15 15 45
 
 
This is not 6-bits but LOG(46)/LOG(2) = 5.52 bits. This is very unhandy. For example, take the MOD-Player. It has four channels, playing a sample in a resoltion of 4 bits. 4*(2^4) ends up into 64 different combinations, which needs 6 bits to be played without quality loss. Sadly, we only have 5.52 bits... We have to calculate 6 bits into 5.52 bits with this formula :
 
X=6-bits value
Y=5.52-bits value
 
Y = X / 64 * 46
 
Well, try this in Machine Language, and you'll be happy if you get a replay speed of 1 kHz ! Solution : Look-Up Table !!!
 
 
The Look-Up Table
-----------------
You build up three tables, one for each channel, containing 64 values, the values that have to be played for that 6-bits combination. Then, a certain sample can be played by this small routine :
 
TABLE1    EQU $2000
TABLE2    EQU $2040
TABLE3    EQU $2080
 
PLAY      LDX VALUE
 
          LDA TABLE1,X
          PHA
          LDY TABLE3,X
          LDA TABLE2,X
          TAX
          PLA
 
          STA $D201
          STX $D203
          STY $D205
 
          RTS
 
VALUE     DFB 0
 
 
On Side-B you'll find a small Turbo-Basic program which builds up these three tables. It'S briefly documented, so I won't tell anything more about it here...
 
 
Oversampling
------------
Frankenstein mentioned the term oversampling in his theory article. I really agree with him, that the meaning of it is getting vague. A lot of people use it in a different context and don't tell what they actually mean. I'm sorry to say, but to my opinion, Frankenstein is also wrong. He combined two subjects into one. The method of calculating values between to samples and the result of that, having a higher replay frequency. Let's get a clear mind ! (?)
 
Oversampling : When you digitaly record an audio signal, with a frequency spectrum ranging from 20 Hz to 20 kHz, the theory of Nyquist tells us you need a recording frequency of at least 40 kHz. Two times the highest input frequency that is. Now, it's called oversampling when the samplefrequency is not twice the input frequency, but e.g. 5 or 10 times. It's used to lessen the terrible effect of high frequencies.
 
But what about that calculating of values between two taken samples ? Well, that is called interpolation. CD-Players use interpolation technics to 'recover' lost data. Take this situation. An (imaginairy) 2-bits CD-Player has read the following values :
 
 
A  11|*   *l  
^  10|**  *o *
|  01|** **s**
   00|*****t**
   ----------
          abc    --> t
 
 
After the second occurance of %11, the player wasn't able to regain the sample information. Now it can just play the %11 again ( 0-order ), but it can also calculate the so called 'expected value'.
 
b = ( a + c ) / 2
 
This is interpolation of the first order. ( Lineair Interpolation. ) There are also higher order interpolation technics using logarithmic functions, sines and cosines etc.
 
As Freddy told us, it's possible to calculate all averages of two samples, and play this one between the two known samples. The resulting data-stream has to be played twive as fast as the original, that results in 1 time oversampling. Processing the 1 time oversampled data stream once again results in 2 times oversampling etc.
 
 
Analog Filters
--------------
With two components, a resistor and a capacitor, you can filter out either low and high frequencies. Take a look ate the following two schemes :
 
         ----
In -----| R1 |-------- Out
         ----     |
                  |
                 ___
                 ___ C1
                  |
                  |
                 GND        _figure 1_
 
        ||C1
In -----||------------ Out
        ||        |
                  -
                 | |
                 |R|
                 |1|
                 | |
                  -
                  |
                 GND        _figure 2_
 
Figure 1 will push down high frequencies above a certain f(R,C) and figure 2 pushes down all frequencies below f(R,C).
 
f(R,C) = 1 / ( 2*pi*R*C )
 
e.g.  R=1K  C=10 pF --> f=15.9 kHz
 
All frequencies above or under 15.9 kHz will be pushed down.
 
 
Digtal Filtering
----------------
First of all, you don't need to use oversampling for digtal filtering. It's based on taking not a 100% of the next sample taken. That way, high frequencies will fade away. You can simulate both RC-Filters seperately, but not together.
 
The essention of this algorithm is to add only a fraction of the new sample to a fraction of the old one. Watch this :-) a=1/2  b=1/2  (-:
 
Last Sample  New Sample  Calculated...
   (Y)          (X)        (aY+bX)
 
128          140         134
134 (!)      144         139
139          151         145
145          143         144
 
 
Mention that a+b=1 and a>=b. All quick changes of amplitudo will dissapear. The imaginairy f(R,C) is very low when a>>b. To simulate the other RC-filter, bY has to be subtracted from aX. ( aX - bY | a+b=1 v a>=b ). All sorts of exotic filters are possible.
 
 
Modulation Technics
-------------------
There is a whole range of different modulation methods. Named here are only a few...
 
 
PAM - Pulse Amplitudo Modulation
 
%11 |*
%10 |**
%01 |***
%00 -----
     abcd
 
 
PPM - Pulse Place Modulation
 
Pls |   *  *  *
    -----------------
     a   b   c   d
 
 
PWM - Pulse Width Modulation
 
Pls |*** **  *
    -----------------
     a   b   c   d
 
 
PNM - Pulse Number Modulation
 
Pls |* * *   * *     *
    ---------------------------------
     a       b       c       d
 
 
PCM - Pulse Code Modulation
 
Pls |***  *
    ---------
     a b c d
 
 
PAM is used on our XL/XE and so it is on ST(E)'s, Amigoes, MSX(2) and C64s. You can generate and n number of pulses, all with a different amplitudo. IBM compatible PC'S could use PAM, but they only have one bit and can therefore only generate block-waves. But wait a minute, all the other modulation technics only require two states. ( Pulse or no pulse ! ) That's why MOD-Players on PC use PWM. They just vary the width of the pulse. Be carefull, every pulse, no matter the length of the one before, starts at a certain frequency! Offcourse, there are a lot of disadvantages. The frequency of the starting points have to be very high so that one pulse sounds like PAM. Luckily the PC sound producer is VERY VERY BAD. It isn't able to produce sounds higher than 8kHz, therefore a starting point frequency of about 10 kHz is fine. Still you need at least a 12 MHz AT. Imagine you want an 4-bit play routine. The length of one period is 16. ( e.g. 15 times 1 and one time 0. ) Now the replay rate of all zeroes and ones is 160 kHz !!! ( This is still slow compared to the 2.56 MHz for an 8-bits player !!! )
 
Probably you think, why do you tell me this ? Our XL/XE is much too slow for this ! Then I must admit that you are right, but this last paragraph about modulation is not meant to be used in practice on an XL. It's just some more theoretical background. Maybe it inspires somebody to get one of these modulation technics working on a XL. ( What about some external hardware, producing a 1-bit PWM output from an 8-bit paralell digital input ? )
 
 
Well, this is the end. ( Finally. ) Let me tell you this, Frankenstein, I can secure you that there were two people that liked your article. ( Me and you that is ! ) I hope we like this one also !
 
Editor: Yes, I liked it. Thanx!

 

 

Hehe, nice! Megazine #5 and #6 had some good articles about sampling :P

http://www.ataripreservation.org/websites/freddy.offenga/megazine/

Link to comment
Share on other sites

I did some experiments with the screen "on", sometime ago, and this is one of them.

Music was provided by Rybags, from the RoadBlasters arcade game (who has a Yamaha chip and a Pokey :)).

 

attachicon.gifroadb4c.gif

 

attachicon.gifroadb.zip

 

Source and 1MB carts provided.. (NTSC and PAL).

 

At some point I was going for this:

 

attachicon.gifroadb4d.gif

 

But I don't have the cpu time to activate the players for now.

That would need another round of optimization and a little of luck :)

 

The code can play different tracks, in a sequence set in a table, so maybe it can be useful for someone.

 

Colors are done using a table indexed by VCOUNT.

Animation is done completely by Antic :D

Samples played using PCM4+4, at 8 bit depth, and 15720 Hz (one sample per scan line).

Is there a cartridge boot bypass built into your player?

 

After trying your demo on my 800XL with an Atarimax 8mbit cartridge I had to use the 'hot swap' technique to reflash it.

 

I think used to use QMEG's monitor to disable the cartridge and reboot (to boot the flasher ATR) but the hot swap worked on the first try.

 

BTW, the demo worked well. Fun stuff! Thanks!

Edited by a8isa1
Link to comment
Share on other sites

But I don't have the cpu time to activate the players for now.

That would need another round of optimization and a little of luck :)

 

The code can play different tracks, in a sequence set in a table, so maybe it can be useful for someone.

 

Colors are done using a table indexed by VCOUNT.

Animation is done completely by Antic :D

Samples played using PCM4+4, at 8 bit depth, and 15720 Hz (one sample per scan line).

So the quality of unfinishable software has reached a higher level, at least ;)

Link to comment
Share on other sites

Is there a cartridge boot bypass built into your player?

 

After trying your demo on my 800XL with an Atarimax 8mbit cartridge I had to use the 'hot swap' technique to reflash it.

 

I think used to use QMEG's monitor to disable the cartridge and reboot (to boot the flasher ATR) but the hot swap worked on the first try.

Not that I know :)

 

I'm not sure what a cartridge boot bypass is in this case..

Link to comment
Share on other sites

I'm not sure what a cartridge boot bypass is in this case..i

Well, with Atarimax's menu if you hold down OPTION while powering up then the cartridge is disabled. This prevents the cartridge from grabbing control and it enables one to boot a disk. Makes it simple to reprogram the cartridge.

 

To reprogram a cartridge that doesn't have this feature we start the machine booting the flasher disk (or ATR), insert the cartridge (hot swap), and proceed with the reprogramming. Sometimes this works. Sometimes the machine hangs or reboots. With either of the latter two cases we repeat the procedure until we are successful.

 

If one has a monitor debugger equipped OS one can disable the cartridge by writing to an adress $D580 to $D5FF and do a reboot. This avoids the need for a hot swap

Edited by a8isa1
Link to comment
Share on other sites

A diag mode cartridge will bypass disk and tape booting.

A normal mode cart that takes control at Init but doesn't return will also bypass both boots.

A normal mode cart can disable disk boot by the flag at $BFFD (set bit 0 = 0)

 

Also note, Atarimax carts if you coldstart but not by powerup can be in an indeterminate bank state, so the system will just assume whatever it finds which usually won't be valid flags and vectors.

Link to comment
Share on other sites

  • 1 year later...
On 5/11/2018 at 11:30 AM, ivop said:

If you preprocess the mod's samples to 6-bit, adding the four channels together yields you an 8-bit value. The problem is that this value cannot simply be written to pokey. You need two LUTs (hi,x and lo,x), which is slower than four covox writes, but I guess would not be that different from three lookups that were needed to get 5.5 bits by using three pokey channels volume-only.

 

Instead of 2 look-ups, I think you could just use a single 256x2-byte table that takes an 8-bit PCM value (whatever format you want to use, unsigned, signed 2's complement, sign-magnitude, etc) and spit out 2 nybbles of POKEY volume data unpacked into 2 bytes. Then it should just be a matter of 2 writes to POKEY volume registers.

 

That sort of look-up table system might be faster or friendlier on a processor with more registers to work with (load both 8-bit values into register space), but it's still probably the fastest option. You could also buffer some length of those volume byte pairs in zero page and keep overhead during the interrupt routine to a minimum, assuming you're using interrupts and not cycle-counted code for the playback routine. (you'd then probably have 2 sets of buffers, one normal, linear 8-bit PCM stream mixing buffer, for adding channels together and scaling note frequencies, etc, and then the second buffer made up of converted bytes)

 

Doing the same thing on a single covox style DAC would still be faster and a bit simpler, though. I'm not sure how comparing 4 DAC ports would compare. (with that you've got less overhead on the mixing end of things, but you have 4 PCM streams to manage during the playback routine, and even more work than that if you're also doing frequency scaling during that portion of playback and not just reading from 4 PCM mixing buffers at a constant DAC sample rate)

 

Albeit with the single 8-bit DAC you can also use interleave/multiplex mixing to allow full 8-bit samples to be played back at the expense of oversampling (and loss of effective playback rate). Ie a 32 kHz playback routine could be used to interleave mix 4 8 kHz 8-bit PCM streams.

 

That latter method of multiplex (or interleave) mixing would also favor the straight PWM technique since the oversampling would shift the squeal artifacting well out of the audible range (and would tend to be filtered out more by the sound circuits more, either intentional filters or just exceeding the bandwidth of the existing circuits/amps/etc).

With straight PWM you also just need 1 look-up from a simple 256x1 byte table, but the playback routine is still more complex. (using that byte to set a POKEY timer to count down the desired pulse duration/width, and if using interrupts and not precise code and/or polling timer status, you'd need 2x as many interrupts as a single covox channel)

 

 The hi/low 2-pokey channel method also still needs 2x the interrupts (using 2 POKEY timers), like straight PWM, but is simpler in using the same pulse-width setting at all times and not making PWM part of the sample-setting (or look-up) routine, but instead as part of an 8-bit DAC emulator routine.

 

PWM could potentially be used for better than 8-bit resolution, but using POKEY timers would make that tricky (at least in 8-bit timer mode) though there might be some other work-arounds. (like taking the POKEY channel being used for 256-step PWM and also modulating its 16 volume levels, so you get a linear 12-bit output)

Given that'd need 12-bit math for adding channels, it's also probably not that useful compared to just adding to saturation at 8-bits, especially with preprocessed samples (so no need to clamp at 8-bits and prevent overflow errors) though it'd be a neat trick nevertheless. (like if POKEY had been included in the Atari ST)

 

Except you could still stick with 8-bit precision and use PWM on a channel simultaneously using 4-bit volume modulation. You'd then just need 16 linear (or rather 15 linear, non-zero) pulse width steps to complement the 16 volume levels.

 

Too bad POKEY only has the random pulse-wave and square wave outputs, if it had variable pulse width, you could use actual PDM (with tons of oversampling). Though using the random pulse-waveform might be interesting in trying to hide or dither the PWM squeal noise. (you might need to drop the channel frequency down close to or into the audible range to do that, and it might just make things worse, but might shape the noise into more of hiss) Or if nothing else, doing some fort of sample playback through a random-pulse wave tone output might make for weird/interesting distortion sound effects.

 

The SID chip has 12-bit precision duty cycle control over its pulse wave channel, so the C64 could potentially use that for up to 12-bit DAC output (though simple 8-bit would be more useful), and while you could also use the lowpass filter to hide the squeal, you'd effectively be doing PDM and not PWM by having the oscillator set to max frequency and modulating the pulse duty cycle. (... and then this just feeds into if the Atari ST had been a Commodore product and ended up including one or more SID chips for its sound output, not that they also wouldn't go well in an Amiga ... or 2 SIDs with PAULA's L/R outputs wired through each, with SID filters and all)

 

 

I think PDM is also a misnomer with the technique I originally suggested in the other thread:

It's really just amplitude-modulation, and even straight 4-bit PCM on POKEY is actually a special case of pulse-amplitude-modulation (since you're actually volume-modulating a square wave signal, not just a line voltage signal) ... which is also kind of funny given PAM could refer to the Atari 5200 as well. And since my suggested method (with the paired channels) uses a fixed pulse width on the low channel, it's still really just pulse-amplitude modulation.

 

But that other method I just mentioned: combining a variable pulse width with variable pulse amplitude would be some sort of hybrid pulse-frequency-pulse-amplitude modulation. (and unless I'm mistaken, that's not one of the earlier PWM techniques used in the demo ROM, I had the impression those were straight 1-bit on/off pulses with all the volume/amplitude data being expressed via the pulse width alone)

 

You'd also still have the problem with audible squeal even if you did use the volume modulation, but maybe not as bad. (since the upper 4-bits would be handled by channel volume, that'd mean 0 would be silent with no squeal and that low/quiet samples would have proportionally quiet squeal, so you'd only get the full volume pulse-carrier frequency tone/squeal for samples in the 240-255 range, and for really loud samples the squeal also becomes less obvious and annoying)

 

With the 2-channel additive 'PDM' method, the noise is just further reduced as the low-duty-cycle pulse channel is effectively at half the linear amplitude when it's on, so what squeal there is from that is going to be half as loud in the worst case and much quieter than that on average.

In fact, you could reduce that to practically zero if you used 2 channels, but instead of setting the volume of both, the low channel gets modulated between volume settings 1 and 0 and you use PWM to achieve the 16 effective amplitude steps for the low 4-bits of pseudo-DAC output.

 

Edit: re-reading my original post in that other thread, it seems I already suggested the single-channel pulse-width+amplitude modulation route as well. I'll have to check out what methods people have actually been working with. (OTOH I didn't specifically mention setting the second channel to volume level 1 and using very quiet PWM to achieve the low 4 bits of an 8-bit linear amplitude output)

 

But given the actual implementation of the 2-channel method still ends up monopolizing 3 POKEY channels due to the way the timers have to be configured, the method of using a single channel for the sound output with PWM only used to provide the low 4-bits might be appealing. (I think you could get away with using 2 channels for that and leaving 2 free to use for other things; you'd need one channel with timer interrupts to set the sample rate and to provide the actual sample sound output, then you'd need another channel with a timer dedicated to providing the pulse width timing)

You could even use a third POKEY timer to control a second pulse-width parameter and use that on the fourth channel to get 2-channel 8-bit DAC output, but that's more work and 3 interrupts instead of 2, plus twice as many look-ups compared to just adding channels together and outputting them as a single stream.

 

It's a shame POKEY doesn't support a one-shot timer pulse mode like the MOS 6522 VIA and maybe RIOT does, since that effectively does the work for you. (and you have 2 16-bit interval timers to use, so one could set the sample rate and the other could provide the variable-width pulse output ... say toggling GTIA's beeper output routed through a lowpass filter to cut the squeal) Atari already had POKEY covering the serial port end and VIA's had that bug to work around anyway, so it's obvious why they went with the cheaper PIA. (and RIOT would've presumably been more expensive, too)

Edited by kool kitty89
  • Like 4
Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...