Jump to content
IGNORED

Implementation of Pokey 2-tone-filter in emulation?


analmux

Recommended Posts

Hi all,

 

since Bryan gave me a hint about the 2-tone-filter on Pokey, I've investigated it's features, and if I have some time I would like to type a small doc about it to explain it, and maybe some recordings also.

 

It's quite interesting, because a complete new spectrum of sound types can be added to Pokey's repertoire.

 

The down side is (at least to me :) ) that it isn't supported by the current emulators (same for the triangle waveform).

 

I know a little how to code in C++, so when there's someone that would like to help me I would like to give it a try to implement it in the pokey.dll.

 

I have only some basic knowledge about coding in C++. But, I don't know at which point in the existing sources the 2-tone-filter could be inserted however :(

 

So, who maintains the sources? ...and who did work on the last pokey.dll?

 

 

READ POST 25 (see link below) for a more detailed, but short, explanation of the 2-tone filter and some features

 

http://www.atariage.com/forums/index.php?s...t&p=1432433

Edited by Analogue Multiplexer
Link to comment
Share on other sites

I'm no C programmer, but have had a bit of a look at the code.

 

I think one possible stumbling block is that it generates samples up to 48,000 per second.

 

Unless some smart formula could be worked out, that would probably need to be increased to nearer 200,000 per second to reproduce triangle wave emulation, and 2-tone effects.

 

Referring back to the previous thread on the subject - the triangle isn't actually produced directly but is a resultant effect of the flanging action between 2 voices at extreme frequencies.

Edited by Rybags
Link to comment
Share on other sites

I think one possible stumbling block is that it generates samples up to 48,000 per second. Unless some smart formula could be worked out, that would probably need to be increased to nearer 200,000 per second to reproduce triangle wave emulation, and 2-tone effects.

 

I don't see the problem. The 2-tone-filter is actually an effect of a simple logical function. It's only resetting of the countdown (div-by-N) timer of channel 1 by channel 2...so, it should be very very easy to implement. For me the only difficulty is where exactly to implement it in the existing code of the pokey.dll.

 

...and another problem is that the SKCTL register isn't emulated properly by the present pokey.dll

 

Referring back to the previous thread on the subject - the triangle isn't actually produced directly but is a resultant effect of the flanging action between 2 voices at extreme frequencies.

 

b.t.w. remember that also the sawtooth wave is already supported, and it's also generated by some kind of analogue/smoothing (& non-linear) interference effects on the real machine.

Link to comment
Share on other sites

Referring back to the previous thread on the subject - the triangle isn't actually produced directly but is a resultant effect of the flanging action between 2 voices at extreme frequencies.

 

b.t.w. remember that also the sawtooth wave is already supported, and it's also generated by some kind of analogue/smoothing (& non-linear) interference effects on the real machine.

 

For an understanding of how high-speed Pokey effects create lower-frequency waveforms, study how PWM DAC's work.

 

The 2-tone mode exists so that a single Pokey channel can generate the cassette track. The serial bit chooses which frequency divider will toggle the output of channel 1. The assumption is that channel 2 will be a higher frequency so it always outruns channel 1's divider when selected. When this isn't the case, you get both dividers affecting a single output. Channel 1 will repeatedly toggle based on its own divider, but can also be toggled by channel 2. This allows for some interesting waveforms, and could probably also be combined with the poly counters to generate new distortions.

Edited by Bryan
Link to comment
Share on other sites

hmmm, when we're talking about PWM, what effects can be reached when high pitched (variable pulsewidth) pulses are sent to GTIA's 1 bit generator (CONSOL)? It would need a lot of CPU cycles, but maybe it's just interesting to figure out. I would just like to know some general characteristic values of the GTIA sound circuit, like f.e. the averaging-width (needed to integrate over).

Edited by Analogue Multiplexer
Link to comment
Share on other sites

The graphs I generated did have some interference - a 50 Hz sine wave, probably as I also have my VCR plugged into the computer.

 

I had a bit of a play with PWM some time back, but didn't have a lot of success... although I was using fairly simple techniques, just setting value 0 to the speaker and having a delay before resetting 1.

 

The delay factor was equivalent to the wave sample value I was looking for (ie what you'd normally store into AUDC bits 3-0 in forced output mode).

 

I guess more in-depth research would be needed there - I didn't bother capturing any of the sounds I generated.

Link to comment
Share on other sites

hmmm, when we're talking about PWM, what effects can be reached when high pitched (variable pulsewidth) pulses are sent to GTIA's 1 bit generator (CONSOL)? It would need a lot of CPU cycles, but maybe it's just interesting to figure out. I would just like to know some general characteristic values of the GTIA sound circuit, like f.e. the averaging-width (needed to integrate over).

 

That's the only way people ever did anything cool on the Apple II's speaker.

 

Note however that the triangle waveform isn't explained by PWM only. There's some non-linear effect that makes the upper peaks sharper than the lower peaks (seen in a recording graph that Rybags showed us in the polycounter thread).

 

Here's how the triangle works. Two fast channels are driven at close frequencies. They will drift in and out of phase with each other and the triangle is the result of this phase relationship. When the channels are in phase, they both drive at the same time, giving a 2-channel 50/50 PWM. When they are out of phase, they alternately drive so the output is equivalent to a single channel being on.

Link to comment
Share on other sites

I have been following this and the other amux pokey threads loosly. This is very interesting coming from a DSP background...

 

I have a few questions, has anyone plotted the spectral analysis of the pure tone output of the pokey?

 

An ideal square wave will look like the following in the time and frequency domains. I am sure that the real-world pokey is not as clean... I am interested in such plots:

 

4-5.gif

 

Also, has anyone looked at the aliasing effects that, I am guessing, can be generated based on the fact that pokey will sample a square wave (or output from the "noise" polycounters) at a rate that is lower than the actual bandwidth of the signal. Thus, aliasing of the frequencies can occur (look here: http://en.wikipedia.org/wiki/Nyquist%E2%80...ampling_theorem).

The pokey spec says that this acts as a low-pass filter, but in reality it acts like modulus math on the frequency.

 

Anyway, I have another question, when you select mode "A", or pure tone, what is the pure tone frequency that gets sampled by the divide-by-N circuitry? Can it be 1.79MHz, 64kHz or 15KHz or any of these? Can the pure tone be a different frequency from the divide-by-N circuit? (okay, 3 questions... :) )

Link to comment
Share on other sites

Real Pokey square wave has a kind of attack/decay on the waveform (which has been raised elsewhere).

 

But, researching elsewhere, that doesn't have too much of an effect on the purity of the sound.

 

Given no other interaction from filters, other voices etc. - the wave transitions occur at <base frequency> / (N+1)

 

Guess I might have to do some more samples - maybe at high frequencies the waveform becomes drasically different due to the transitions occuring so fast that the normal attack/decay sequence is truncated?

Link to comment
Share on other sites

The triangle wave is produced as I explained in the other thread.

 

I made a test program that produced two high-frequency pure square waves differing in frequency by a small amount.

 

When linear addition is used, the result is silence as expected.

 

When non-linear addition is used (eg sum(1,1)=1.5 and not 2), the result is a triangle wave.

 

This is obvious when the signal is low-pass filtered. I could see a perfect triangle wave in audacity after low-pass filtering.

 

Emulation of the triangle wave requires the non-linear mixing function.

 

If anyone wants to help, you can run the test program I put in the other thread and send me the results. This will be a large file so I'll arrange for you to upload it to me.

Link to comment
Share on other sites

An ideal square wave will look like the following in the time and frequency domains. I am sure that the real-world pokey is not as clean... I am interested in such plots:

 

The spectrum should be nearly the same. For some pictures of the actual waveforms see my 'Pokey information page' (below in signature) which is still under construction.

 

The signal consists of 2 phases. When the countdown timer (div-by-N) reaches zero, the signal will flip (high->low or low->high). This is offcourse not immediate. There's something called 'charging time' which is in the order of 0.000045 seconds. The charging is an almost linear rising/lowering of the signal voltage. After charging the decharging cycle will start, which is described best by an exponential decay of half-time in the order of 0.0025 seconds.

 

The exponential decay is in fact best described by something called 'Laplace transformation'. This will correspond to a purely imaginary Fourier-component (in the non-periodic case), which has an absolute value directly related to the half-time (or more precisely, to the time which is needed for the signal to die out with a factor of 1/e = 1/2.7182....). Off-course it is a cut-off decay, which gives some correction in the complex plane.

 

So, in fact this part is added to the spectrum, but I don't know exactly where in the spectrum. But I don't think it has a large effect. A similar story lies behind the charging signal, but this has little effect when using mid-range notes. High pitched notes look like triangle waves, as the charging time gets into the same order as the wavelength. So, beware, making a spectrum plot always gives a loss of information, because Fourier components are always complex numbers. That's why phase differences f.e. are hard to detect, when looking at a spectrum.

 

 

Also, has anyone looked at the aliasing effects that, I am guessing, can be generated based on the fact that pokey will sample a square wave (or output from the "noise" polycounters) at a rate that is lower than the actual bandwidth of the signal.

 

I'm not sure what you mean by sampling. Pure tones are generated directly without sampling. Only for the polycounters we have a different story, as they always run at 1.79mhz speed. They are sampled by the countdown-timers, but when we take f.e. poly5 (distortion 2: 31 steps = prime number --> no degeneracy) we are always dealing with the same number of sample-steps before the waveform starts to repeat itself. This would be different when we would be dealing with non-integer ratios e.a.

 

That's why notes can be obtained (f.e. from poly5 clocked at 1.79mhz) in the usual way.

 

When the poly5 sequence is sampled at different rates, the patterns change (by permutations), but the effect isn't audible. This is also a feature of the polycounter.

 

Note detail:

poly4 has 2^4-1 = 15 steps. The signal is simply periodic.

poly5 has 2^5-1 = 31 steps BUT the signal has an inversion point, so it is antiperiodic: thus, the period is 62 steps

that's why the notation of poly5 (dist.2) clocked at 1.79mhz is nearly the same as dist. 'A' clocked at 64khz (it differs a frequency factor of 28/31).

 

 

The pokey spec says that this acts as a low-pass filter, but in reality it acts like modulus math on the frequency.

 

This low-pass effect is best heard when using the white noise generators (poly17&5)....but this 'modulus math' or 'alias frequencies' is not a thing I see.

 

 

Anyway, I have another question, when you select mode "A", or pure tone, what is the pure tone frequency that gets sampled by the divide-by-N circuitry? Can it be 1.79MHz, 64kHz or 15KHz or any of these? Can the pure tone be a different frequency from the divide-by-N circuit? (okay, 3 questions... :) )

 

The real signal is 'anti-periodic, with 'anti-period' related to the value stored in AUDFn, which is the number of baseclock cycles that need to be counted. Thus, the signal is periodic in 2 times the 'anti-period'. Again, I'd like to point out that mode 'A' sound is not based on sampling at all. What is meant by 1.79mhz, 64khz or 15khz is the clock-frequency that drives the divide-by-N circuit itself. So in 1.79mhz mode, the div-by-N counter changes 1.79 million times per second.

Edited by Analogue Multiplexer
Link to comment
Share on other sites

The triangle wave is produced as I explained in the other thread.

 

I made a test program that produced two high-frequency pure square waves differing in frequency by a small amount.

 

When linear addition is used, the result is silence as expected.

 

When non-linear addition is used (eg sum(1,1)=1.5 and not 2), the result is a triangle wave.

 

Yep, this is indeed what you see in the graph (see a bit earlier). Upper peaks are more 'compressed', lower peaks (valeys) are sharp. In fact, this non-linear effect is best described in terms of an audio-signal compressor (used to kill exceptional high peaks in a signal).....

 

This is obvious when the signal is low-pass filtered. I could see a perfect triangle wave in audacity after low-pass filtering.

 

....? this is the part I don't understand. Isn't low-pass filtering by definition linear? A.f.a.i.k. it is done by the following sequence (in the theoretical case):

 

-sample input signal

-fourier transform (which is linear by definition)

-multiply obtained spectrum with a 'filter function'

-inverse fourier transform

-output result

 

maybe it's related to the fact that in practice the fourier-transforms can't be performed with 100% accuracy, as we're dealing with 'windowed' integration instead of integration over the whole real line in practice?

 

anyway, how is the sawtooth wave emulated? wouldn't it take much more processing time to emulate it, compared to older pokey.dll without sawtooth support?

 

could it be possible to 'fake' the triangle instead of totally emulating the non-linear effect?

 

-------------------------

 

anyway, I'd also like to return to the original subject of the 2-tone-filter :)

Link to comment
Share on other sites

on Rasters website there are the sa_pokey DLLs incl.source...can these not be altered and improved to get an improved pokey sound in RMT and if so later in atari800win?

 

I took a look, but it seems that Raster maintains a stripped down version of it, minimalized for sound generation only. I don't know if the stripped down version has full SKCTL-register support.

 

thanks anyway

Link to comment
Share on other sites

This is obvious when the signal is low-pass filtered. I could see a perfect triangle wave in audacity after low-pass filtering.

....? this is the part I don't understand. Isn't low-pass filtering by definition linear?

The low-pass filter is just so that I could see the waveform. It removes the ultrasounds, but it doesn't change the audible frequencies. This filter does not generate the triangle wave sound. It is caused by the non-linear mixing only.

 

anyway, how is the sawtooth wave emulated?

As I understand it, it is just the pokey "high-pass filter", due to PWM. PWM works if we do correct resampling.

 

could it be possible to 'fake' the triangle instead of totally emulating the non-linear effect?

 

Emulating the triangle wave is easy, since all that is needed is an improved volume table. I can make a volume table with 65,536 values and look up the output signal level as a function of the lower 4 bits of AUDC(1-4) and the channel on/off status.

 

anyway, I'd also like to return to the original subject of the 2-tone-filter :)

 

I think that adding the two-tone filter to atari800 is also easy. It is just a digital effect, so just add some code for it in the pokey channel event-handling.

Link to comment
Share on other sites

Emulating the triangle wave is easy, since all that is needed is an improved volume table. I can make a volume table with 65,536 values and look up the output signal level as a function of the lower 4 bits of AUDC(1-4) and the channel on/off status.

 

Thus, we need some recording of real Pokey which shows us the non-linear effect.

 

Wasn't that the goal of your .pl code? Could you (maybe) make the same thing as an atari-executable (.xex)?

 

I can make recordings and upload them to my own public space.

Link to comment
Share on other sites

Emulating the triangle wave is easy, since all that is needed is an improved volume table. I can make a volume table with 65,536 values and look up the output signal level as a function of the lower 4 bits of AUDC(1-4) and the channel on/off status.

 

Thus, we need some recording of real Pokey which shows us the non-linear effect.

 

Wasn't that the goal of your .pl code? Could you (maybe) make the same thing as an atari-executable (.xex)?

 

I can make recordings and upload them to my own public space.

 

The perl code is for me to analyze the data. It calcuates the results from the data.

 

The post I made in the other thread prior to the one with the perl code has the has the .xex file:

pokeyvol.zip ( 10.36K )

http://www.atariage.com/forums/index.php?a...st&id=90202

 

There is a loud tone at the beginning that should be used to calibrate the recording level. This tone should not be clipped. It is the loudest possible tone.

 

The recoding will be 10-15 minutes long. I would like a .wav or .flac file, not .mp3 because it might distort the data. It will be a fairly large file.

Link to comment
Share on other sites

What do you mean by 2-tone-filter? 2-tone mode used for cassette recording? If so, I can add emulation of it in ASAP. Do you have any examples of it being useful for music?

Two tone mode allows you to use 2 dividers to reset channel 1 (and you would normally silence the 2nd channel). They run in parallel, so if channel 1 is first reset by its own divider then is reset by divider 2 before divider 1 counts down again, you get a programmable duty cycle. What's more, it doesn't have to be based on a single cycle. Channel 1 can flip several times based on divider 1 before divider 2 times out creating a shortened 3rd or 4th half-cycle.

 

The cool part is being able to smoothly slide between different duty cycles.

Link to comment
Share on other sites

So it's simply 2-tone mode normally used for cassette recordings. Its schema is drawn in pokeydoc. What I still wonder is whether it's useful for normal music?

 

Yes, it is even very useful for music. It's comparable to the 'sync' effect on the SID. With this effect it is possible to add resonances in the soundtype.

 

Not only variable duty cycle is possible...this is just one of the features.

 

The main frequency of the wanted note is controlled by voice 2 timer. The voice 1 timer adds more timbre variations.

 

so, getting results is very easy.

 

 

explanation of the filter and its use will follow here.

Link to comment
Share on other sites

So it's simply 2-tone mode normally used for cassette recordings. Its schema is drawn in pokeydoc. What I still wonder is whether it's useful for normal music?

 

Yes, it is even very useful for music. It's comparable to the 'sync' effect on the SID. With this effect it is possible to add resonances in the soundtype.

 

Not only variable duty cycle is possible...this is just one of the features.

 

The main frequency of the wanted note is controlled by voice 2 timer. The voice 1 timer adds more timbre variations.

 

so, getting results is very easy.

 

 

explanation of the filter and its use will follow here.

It's the only way I know of to slide between two timbres on Pokey, so I think it would be very desirable for music.

Link to comment
Share on other sites

It's the only way I know of to slide between two timbres on Pokey, so I think it would be very desirable for music.

 

Well, the standard way to generate variable width pulses is by using the standard 'high-pass filter'. It's a pity it's never been properly explained in books, but the trick relies on controlling (f.e.) channel 1 and 3 timers with the right relative timing (phase difference) offset. This can be controlled by the 'STIMER' register and some additional stuff. After that you can morph between timbres with some simple procedures.

 

The more interesting stuff to obtain from the 2-tone mode filter comes in play when using pitchratios pitch2 > N * pitch1, with N => 3. Then typical sync timbres are possible.

Edited by Analogue Multiplexer
Link to comment
Share on other sites

Here I made some diagrams to explain some of the features of the 2-tone-filter

 

Explanation of some symbols:

 

F1, F2: the real pitch-number, corresponding to the number of cycles counted by a divide-by-N counter

F1: for channel 1

F2: for channel 2

T: period of the sound signal, i.e. the signal is totally periodic with period T

 

 

The 2-tone-filter is activated by simply doing the following:

1) set bits 3 and 7 of $d20f (SKCTL)

2) select a volume/distortion on channel 1: $d201 (AUDC1)

3) selecting a desired pitch F2: subtract a clocking-dependant constant C2 and store result in $d202 (AUDF2)

4) selecting a desired pitch F1: subtract a clocking-dependant constant C1 and store result in $d200 (AUDF1)

 

C1 and C2 are (resp.) depending on how the channels 1 and 2 are clocked:

C = 1 if clocking is 64khz or 15khz

C = 4 if clocking is 1.79mhz

C = 7 if clocking is 1.79mhz and 16bit mode is activated (though we don't want to use this in combination with 2-tone-filter)

 

The value of F2 is chosen by the desired note

The value of F1 is chosen by the desired sound type

 

 

Especially note one rule:

 

When we have settings of type N (explained in the picture), i.e. N * F1 =< F2 < (N+1) * F1, then:

-for even N, the signal of the waveform is periodic

-for odd N, the signal of the waveform is antiperiodic

 

! When the signal is antiperiodic, then the resulting note will sound one octave lower. After transition of an odd N to an even N, the note will rise one octave.

 

 

 

Remarks:

 

1) In the figure I didn't take in account that F1 and F2 are integers in practice.)

2) The interesting effects happen when the ratio F2/F1 is not integer, i.e. F2 is not close to an integer multiple of F1.

3) The resolution of the timbre-control is off course dependant on F2. The lower the desired note, the higher the value of F2, and thus the better resolution of the timbre-control

4) The higher the value of N, the more complex the sound.

Edited by Analogue Multiplexer
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...