MFP / CPU clock ratio

A forum about the Hatari ST/STE emulator - the current version is v2.0.0

Moderators: simonsunnyboy, thothy, Moderator Team

User avatar
BenOVR
Atariator
Atariator
Posts: 25
Joined: Wed Nov 02, 2016 7:54 pm
Contact:

MFP / CPU clock ratio

Postby BenOVR » Fri May 05, 2017 4:39 pm

Hi guys

I wrote a program to measure the MFP/CPU clock ratio. I know it's already been done by others but I like to do my own work.

According to Hatari source file cycInt.c the real CPU is 8021247-hz. Hatari rounds it to 8021248-hz. The first hit with my program measures 8021248.14-hz for Hatari. A longer run seems to drift a bit which is quiet odd as it seems to me that the longer the run the more precise it should be. Anyway overall it's close to the mark.

Running the program on my real 1040STf (pal) gives different timings. I've measured 8010701.3-hz which is much closer to what's written on the crystal clock (8010600-hz). Notice that the results are relative to the MFP clock. Assomption is that the MFP timers are running at an exact 2457600-hz. When it comes to what interest me directly (music emulation) the absolute clock values are not relevant. Only the exact ratio between the MFP timers and the YM clock matters.

Anyway I have attached below my program including the source code in case someone is interested. It a bit rough on the edge. It has to run in medium resolution. It displays on the left column 2 counters vbl and mfp. To compute the CPU clock apply the following formula:

Code: Select all

 cpu-clock = vbl*313*24576/mfp


--
Ben / OVR
You do not have the required permissions to view the files attached to this post.

User avatar
troed
Atari God
Atari God
Posts: 1213
Joined: Mon Apr 30, 2012 6:20 pm
Location: Sweden

Re: MFP / CPU clock ratio

Postby troed » Fri May 05, 2017 4:58 pm

Thanks :) I also recently wrote similar code to make my demo routines work correctly on the four different CPU speeds that exist. (8.05, 8.02, 8.01 and 8.007).

I would expect most tunes to have been written on 8.02 machines. Have you heard any noticeable differences between 8.01 and 8.02 for example?

/Troed

User avatar
BenOVR
Atariator
Atariator
Posts: 25
Joined: Wed Nov 02, 2016 7:54 pm
Contact:

Re: MFP / CPU clock ratio

Postby BenOVR » Fri May 05, 2017 5:26 pm

The way the timers are used usually for sound FX don't really rely on such precision. I'm a bit too lazy to compute the drift but I'm willing to try to find the best matching frequency between the YM and the timer on a standard SID voice by ring modulation. That's the effect that is the more likely to be affected specially noticeable on a long sustained note. The current sc68 clock ratio is wrong. Not only I did not use the good value to begin with but because the code was inherited from my old ARM6@30mhz I had to use a power of two in the integer ratio to avoid division.

Recently Gunstick pointed me out a emulation problem with Tao's Eclipse song. I haven't investigate the problem yet but I can think of 2 possible issues. One would be the problem at hand here, the other would be a YM pulse internal counter reset (which sc68 currently does not simulate properly).

User avatar
BenOVR
Atariator
Atariator
Posts: 25
Joined: Wed Nov 02, 2016 7:54 pm
Contact:

Re: MFP / CPU clock ratio

Postby BenOVR » Fri May 05, 2017 11:35 pm

Attached is an example of sound (sndh) that might differ a bit between different clocks. It might be unnoticeable but if you test it with sc68 you'll hear the difference. Hatari seems to have some problem (may be with the filtering) with this one. It happens when the timer is synced on the low state. As it's actually impossible to determine the YM pulse state the proper way is to start the timer with half the frequency to ensure the modulation to start on clean state (can be either __-_ or _-__ ). Here I didn't on purpose so the sound starts either on the low state ____ or the high state __--. When it's the low state Hatari audibly suffers.
You do not have the required permissions to view the files attached to this post.

User avatar
npomarede
Atari God
Atari God
Posts: 1178
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: MFP / CPU clock ratio

Postby npomarede » Sat May 06, 2017 10:00 am

Hi
last year Troed pointed to some sound emulation issue when working on "Closure" demo with the music by 7an.
It was related to the tone phase that can cancel each other sometimes if you play 2 tones at the same period on 2 voices, since both tone will "randomly" start at an up or down phase.
I rewrote this part in Hatari some weeks ago, but it's not released yet (I'm waiting for 7an's confirmation that results are correct). Basically I now emulate every cycle of the YM2149 by updating the internal tone/noise/env counter at a simulated freq of 250 KHz (as it's done on a real YM2149). Previously Hatari only updated the YM state at the PC output freq (44.1 KHz in most case)

The important part is to determine how the YM2149 handles the tone per value to switch phase on every 1/2 per. AY doc (from which YM2149 is derived) says the counter goes downward, starting at tone_per.until it reaches 0. But this models seemed wrong when emulating some musics and other emulators (MAME) says the counter goes upward, but there's no reference about how it was measured.

So, I wrote my own test program on STF, using video sync code to be able to start a fixed tone sound and to precisely change the tone_per regs at a cycle precise position into each phase of the sound and recording the output at high freq on my PC audio card, to precisely study the WAV file using Audacity for example.

When writing specific new tone_per values at 1/2 phase for example, it becomes clear that any new value written into tone_per regs becomes the new "max" value at which phase should be inverted. This also meant that the YM counts upward from 0 until it reaches the current value of tone_per (as opposite to what the doc tells).
Any change to tone_per is taken immediately as the new max value (it is not "cached" until the current phase change using the previous tone_per).
This is why writing 0 or 1 to tone_per is often seen as "reseting" the phase, because any new tone_per written after (0x500 for example) will start immediately a new full phase (up or low) so you can synchronize this with starting an MFP timer at the same time and the tone and MFP period will have a common starting point.

Regarding TAO's Eclipse song, it's quite possible the problem is similar to 7an's music and you need to implement individual counter for each tone/noise/env and emulate the internal freq of 250 KHz to precisely update those counters.
When playing Eclipse, at which position in time are we supposed to hear the bad emulated sound ? Is this only in sc68, or is it bad in Hatari 2.0 too ?

Also note that Hatari has some filters that are supposed to mimic those in the STF, but it can sometimes suppress more high freqs that I can hear on my STF, this is rather complicated to fine tune (emulating analog filtering in all cases can prove to be very difficult)

Nicolas

User avatar
BenOVR
Atariator
Atariator
Posts: 25
Joined: Wed Nov 02, 2016 7:54 pm
Contact:

Re: MFP / CPU clock ratio

Postby BenOVR » Sat May 06, 2017 11:27 am

About the phase cancel out here is another example for you. That one puzzled me a bit until I used the channel masking capability of sc68. With sc68 the effect is even worst as the simulation is cycle less both channels are exactly in sync. As sc68 is deterministic the chip state is always the same when the music starts contrary to a real machine. You bore won't always sound the same on a real ST (according to 505) just as the sndh I have attached above. The cycle less thing is the reason the period reset does not work with sc68 at the moment as it only process the last value for each register in simulated player pass. That can very easily be fixed.

Eclipse problem appears at 2'30". It works properly with Hatari.

I had the same feeling that the downward model was wrong despite the documentation. I'm glad you did the test. It's quiet some time I wanted to do that too. But I did not have the setup to do it properly. The ``no caching'' was quiet easy to determine by just starting a low frequency sound and change it to a high frequency soon after.

Back in the 90's I had a real oscilloscope that was handy. That's how I developed my first sync-buzz. Not the timer one. It was synced on the video so that the musician could perfectly control the phase between the tone and the envelop. This is when I figured out the way to reset the phase with a 0-period tone but unfortunately it was always a problem that you could not determine the pulse state (low/high).

Just to be clear when you say ``when it reach'' you mean a higher or equal test, right ? Because an equality test would cause a problem when the counter is already higher to the goal (a la SID LFSR bug). The fact that a period of 0 and 1 is equivalent suggest the test is done after the counter is incremented, do you agree ?

Another unrelated thing. I have noticed Hatari used a weird 4-bit to 5-bit value mapping when converting direct 4-bit volume value to 5-bit DAC input. How did you come up with this table ? sc68 uses N*2+1 which mean the sound is never exactly quiet. I wish I still had an oscilloscope.

I have been snooping around Hatari's work. I've seen a lot of interesting thing. I still use the BLEP synthesis as the main engine for sc68. I have in project to include it in the pulse engine (my legacy engine) as a filter in the future. I might add float support someday too. ARM's days are over. I also use a ``new'' volume table since 2009. Not sure if you noticed that. It's an hybrid between the good old recorded table and the interpolated one. I've sampled all the extremum on a real ST (the faces of the cube). Then I've used the normal formula to interpolate in between.

I might use some inspiration from Hatari code the day I decide to update my terrible STE emulation.

User avatar
npomarede
Atari God
Atari God
Posts: 1178
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: MFP / CPU clock ratio

Postby npomarede » Sat May 06, 2017 1:29 pm

BenOVR wrote:About the phase cancel out here is another example for you. That one puzzled me a bit until I used the channel masking capability of sc68. With sc68 the effect is even worst as the simulation is cycle less both channels are exactly in sync. As sc68 is deterministic the chip state is always the same when the music starts contrary to a real machine. You bore won't always sound the same on a real ST (according to 505) just as the sndh I have attached above. The cycle less thing is the reason the period reset does not work with sc68 at the moment as it only process the last value for each register in simulated player pass. That can very easily be fixed.

I don't hear a difference with Hatari's not yet released new sound, but I guess I would need to run the music several times before the randomness appears.
Have you considered writing a small sndh file as the one you wrote for the sid effet above, but with 2 voices trying to cancel each other ? This could be useful to compare real STF and emulators, without having to run a complete music file.
Eclipse problem appears at 2'30". It works properly with Hatari.

Hatari 2.0 will immediately starts a new phase when writing a new period value ; this is not accurate, but it prooved to give good results in fact with SID voices :)
I had the same feeling that the downward model was wrong despite the documentation. I'm glad you did the test. It's quiet some time I wanted to do that too. But I did not have the setup to do it properly. The ``no caching'' was quiet easy to determine by just starting a low frequency sound and change it to a high frequency soon after.

Back in the 90's I had a real oscilloscope that was handy. That's how I developed my first sync-buzz. Not the timer one. It was synced on the video so that the musician could perfectly control the phase between the tone and the envelop. This is when I figured out the way to reset the phase with a 0-period tone but unfortunately it was always a problem that you could not determine the pulse state (low/high).

Just to be clear when you say ``when it reach'' you mean a higher or equal test, right ? Because an equality test would cause a problem when the counter is already higher to the goal (a la SID LFSR bug). The fact that a period of 0 and 1 is equivalent suggest the test is done after the counter is incremented, do you agree ?

Yes, any value >= will trigger the phase change. Having per 0 == 1 also suggests counter is incremented first, then tested after, but that's harder to confirm without a complete chip decapping (as it was done by Ijor for the MMU and the Shifter)
As an example, consider period is 500 and you manage to change period when current counter is 200 (counting up) :
- if you write a new per 50 for example, phase will alternate and restart from 0 with a new max = 50
- if you write a new per 1000 for example, current phase will be extended, it won't alternate until you reach the new max = 1000
Another unrelated thing. I have noticed Hatari used a weird 4-bit to 5-bit value mapping when converting direct 4-bit volume value to 5-bit DAC input. How did you come up with this table ? sc68 uses N*2+1 which mean the sound is never exactly quiet. I wish I still had an oscilloscope.

Do you mean the table "YmVolume4to5" ? In fact it's a direct interpretation of the YM2149 doc, figure 1, page 8, "D-A convertor". Left scale is 4 bit value, right scale is 5 bit value (used by envelope). I just mapped each value on the left to its equivalent value on the right and from there all internal volume operations are made on 5 bits. But on a real ST, it's very hard to hear a difference between volume 0 and 1. Maybe there's one when measuring directly at the YM's pin, but once the signal goes through the filters and the monitor/tv's speaker, it sounds like 0.
I have been snooping around Hatari's work. I've seen a lot of interesting thing. I still use the BLEP synthesis as the main engine for sc68. I have in project to include it in the pulse engine (my legacy engine) as a filter in the future. I might add float support someday too. ARM's days are over. I also use a ``new'' volume table since 2009. Not sure if you noticed that. It's an hybrid between the good old recorded table and the interpolated one. I've sampled all the extremum on a real ST (the faces of the cube). Then I've used the normal formula to interpolate in between.

I might use some inspiration from Hatari code the day I decide to update my terrible STE emulation.

I think Hatari uses a more recent table made by Paulo/LJKB that he posted on atari-forum when writing his hextracker, at this time his table sounded better when playing digisound under Hatari, but it's hard to judge which table is better. As for filtering, trying to model an analog signal can be complicated, especially when the 3 voices are wired together and can give some feedback effect on each other depending on their period.

The BLEP synthesis articles were really interesting, too bad Antti Lankila stopped working on this. It's a really nice approach to replacing the standard ending filtering stage by including it directly in the tone generator.
That's the difficulty to find a correct filter ; back in the days, we were used to some bad quality monitor's speakers, or connecting the ST directly to a better HIFI system, so 2 people having STs might disagree on the results produced by emulators, depending on how much the sound is "soften" by filtering or not.
Back in the '90s, I had a modified STF on which I added a "stereo" output (from an old french ST Magazine article), the sound was "sharper" which IMO gave a better rendering for chip tunes, but for digisound the lack of filtering gave more "noisy" result, so it was not always better.


Nicolas

User avatar
Steven Seagal
Atari God
Atari God
Posts: 1982
Joined: Sun Dec 04, 2005 9:12 am
Location: Undisclosed
Contact:

Re: MFP / CPU clock ratio

Postby Steven Seagal » Sat May 06, 2017 4:54 pm

As I mentioned in the Steem thread some weeks back, the answers are already in MAME, ay8910.cpp by Couriersud, unless of course it is wrong/buggy.

Code: Select all

Careful studies of the chip output prove that the chip counts up from 0
until the counter becomes greater or equal to the period. This is an
important difference when the program is rapidly changing the period to
modulate the sound. This is worthwhile noting, since the datasheets
say, that the chip counts down.
Also, note that period = 0 is the same as period = 1. This is mentioned
in the YM2203 data sheets. However, this does NOT apply to the Envelope
period. In that case, period = 0 is half as period = 1.


They were first on this!

Here's the main function, quite short.

Code: Select all

void ay8910_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
{
   stream_sample_t *buf[AY8910_NUM_CHANNELS];
   int chan;

   buf[0] = outputs[0];
   buf[1] = nullptr;
   buf[2] = nullptr;
   if (m_streams == AY8910_NUM_CHANNELS)
   {
      buf[1] = outputs[1];
      buf[2] = outputs[2];
   }

   /* hack to prevent us from hanging when starting filtered outputs */
   if (!m_ready)
   {
      for (chan = 0; chan < AY8910_NUM_CHANNELS; chan++)
         if (buf[chan] != nullptr)
            memset(buf[chan], 0, samples * sizeof(*buf[chan]));
   }

   /* The 8910 has three outputs, each output is the mix of one of the three */
   /* tone generators and of the (single) noise generator. The two are mixed */
   /* BEFORE going into the DAC. The formula to mix each channel is: */
   /* (ToneOn | ToneDisable) & (NoiseOn | NoiseDisable). */
   /* Note that this means that if both tone and noise are disabled, the output */
   /* is 1, not 0, and can be modulated changing the volume. */

   /* buffering loop */
   while (samples)
   {
      for (chan = 0; chan < AY8910_NUM_CHANNELS; chan++)
      {
         m_count[chan]++;
         if (m_count[chan] >= TONE_PERIOD(chan))
         {
            m_output[chan] ^= 1;
            m_count[chan] = 0;
         }
      }

      m_count_noise++;
      if (m_count_noise >= NOISE_PERIOD())
      {
         /* toggle the prescaler output. Noise is no different to
          * channels.
          */
         m_count_noise = 0;
         m_prescale_noise ^= 1;

         if ( m_prescale_noise)
         {
            /* The Random Number Generator of the 8910 is a 17-bit shift */
            /* register. The input to the shift register is bit0 XOR bit3 */
            /* (bit0 is the output). This was verified on AY-3-8910 and YM2149 chips. */

            m_rng ^= (((m_rng & 1) ^ ((m_rng >> 3) & 1)) << 17);
            m_rng >>= 1;
         }
      }

      for (chan = 0; chan < AY8910_NUM_CHANNELS; chan++)
      {
         m_vol_enabled[chan] = (m_output[chan] | TONE_ENABLEQ(chan)) & (NOISE_OUTPUT() | NOISE_ENABLEQ(chan));
      }

      /* update envelope */
      if (m_holding == 0)
      {
         m_count_env++;
         if (m_count_env >= ENVELOPE_PERIOD() * m_step )
         {
            m_count_env = 0;
            m_env_step--;

            /* check envelope current position */
            if (m_env_step < 0)
            {
               if (m_hold)
               {
                  if (m_alternate)
                     m_attack ^= m_env_step_mask;
                  m_holding = 1;
                  m_env_step = 0;
               }
               else
               {
                  /* if CountEnv has looped an odd number of times (usually 1), */
                  /* invert the output. */
                  if (m_alternate && (m_env_step & (m_env_step_mask + 1)))
                     m_attack ^= m_env_step_mask;

                  m_env_step &= m_env_step_mask;
               }
            }

         }
      }
      m_env_volume = (m_env_step ^ m_attack);

      if (m_streams == 3)
      {
         for (chan = 0; chan < AY8910_NUM_CHANNELS; chan++)
            if (TONE_ENVELOPE(chan) != 0)
            {
               if (type() == AY8914) // AY8914 Has a two bit tone_envelope field
               {
                  *(buf[chan]++) = m_env_table[chan][m_vol_enabled[chan] ? m_env_volume >> (3-TONE_ENVELOPE(chan)) : 0];
               }
               else
               {
                  *(buf[chan]++) = m_env_table[chan][m_vol_enabled[chan] ? m_env_volume : 0];
               }
            }
            else
            {
               *(buf[chan]++) = m_vol_table[chan][m_vol_enabled[chan] ? TONE_VOLUME(chan) : 0];
            }
      }
      else
      {
         *(buf[0]++) = mix_3D();
      }
      samples--;
   }
}



This beautifully explains tone period "quantize", 0==1, sample playing with tone and noise disabled, and phase difference.

User avatar
npomarede
Atari God
Atari God
Posts: 1178
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: MFP / CPU clock ratio

Postby npomarede » Sat May 06, 2017 5:06 pm

As I wrote above, this doesn't explain why per 0 == per 1, we don't know the inner counting logic of the YM2149 chip unless someone decap / analyze the chip.
It's just some code that matched the observed behaviour of the chip in such a way that per=0 sounds like per=1. But maybe when we write a per=0 value in the chip this is internally converted to 1 before incrementing/testing the counter, who knows ?

Incrementing counter first then checking if counter >= per is a code implementation that will "naturally" give the same results (ie phase duration) the YM would give, but we have no idea it's done in that order in the YM2149. Only thing we know is that the counter is incremented until it is >= per.

EDIT : I'm also not convinced envper=0 is also half envper=1 on the YM2149 (as in the MAME source header), unfortunately I was not able to capture a sound recording of this as this exceeds the sampling rate of my audio card. This would require a more precise logic analyzer. But given that tone_per=0 is same as tone_per=1 and noise_per=0 is same as noise_per=1, I don't see why env_per would be counted differently. Only answer is to measure the signal :)

User avatar
Steven Seagal
Atari God
Atari God
Posts: 1982
Joined: Sun Dec 04, 2005 9:12 am
Location: Undisclosed
Contact:

Re: MFP / CPU clock ratio

Postby Steven Seagal » Sat May 06, 2017 5:26 pm

npomarede wrote:EDIT : I'm also not convinced envper=0 is also half envper=1 on the YM2149 (as in the MAME source header), unfortunately I was not able to capture a sound recording of this as this exceeds the sampling rate of my audio card. This would require a more precise logic analyzer. But given that tone_per=0 is same as tone_per=1 and noise_per=0 is same as noise_per=1, I don't see why env_per would be counted differently. Only answer is to measure the signal :)


Code: Select all

         m_count_env++;
         if (m_count_env >= ENVELOPE_PERIOD() * m_step )


It seems quite clear from the code that for the YM2149 (m_step==1), 0==1 for the envelope.
For the AY8910 (m_step==2) it is half.
I guess the guy did measure it with more precision.
The explanation may seem ambiguous because it's an AY8910 emu foremost.

User avatar
npomarede
Atari God
Atari God
Posts: 1178
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: MFP / CPU clock ratio

Postby npomarede » Sat May 06, 2017 5:42 pm

Once again, I agree the code will give env_per=0 half of env_per=1, but it's not a proof, it's just an implementation to reach this behaviour.

For example, if you read various AY or YM datasheets for several models, you will see that the datasheets sometimes say that per=0 is half of per=1 for some chips and sometimes per=0 is the same as per=1 for other chip models, even if they all belong to the AY/YM family.

So, although I have HUGE respect for the MAME project, it's just that I think the source header is not precise enough : how was it measured ? On which chip ? AY8910 only, or also YM2149 ?

Overall, many MAME arcade machines use the AY chip more often than the YM, so I wonder if they did not study the AY in depth and just extrapolated to the YM, assuming it would behave the same ?

Nicolas

User avatar
BenOVR
Atariator
Atariator
Posts: 25
Joined: Wed Nov 02, 2016 7:54 pm
Contact:

Re: MFP / CPU clock ratio

Postby BenOVR » Sat May 06, 2017 5:50 pm

There is no doubt that env=0 is equ. to env=1. It's in the audible spectrum (8000hz for sawtooth / 4000hz for triangle). If it were different you would absolutly hear it.

I don't hear a difference with Hatari's not yet released new sound, but I guess I would need to run the music several times before the randomness appears.

It's actually Gunstick who spoke to 505 but that's what I remember he told me.

Have you considered writing a small sndh file as the one you wrote for the sid effet above, but with 2 voices trying to cancel each other ? This could be useful to compare real STF and emulators, without having to run a complete music file.

Done ! It includes 4 songs with 4 different ways to initialize the 4 registers (perAL/perAH/perBL/perBH). But the PC I'm using to transfert files between my ST and the rest of the world is super capricious. At the moment it's refusing to boot ! I hope to fix that ASAP.

Do you mean the table "YmVolume4to5" ? In fact it's a direct interpretation of the YM2149 doc, figure 1, page 8, "D-A convertor"

I don't know which version of this document you have. Mine is too LQ to read the lower values.

I think Hatari uses a more recent table made by Paulo/LJKB that he posted on atari-forum when writing his hextracker, at this time his table sounded better when playing digisound under Hatari, but it's hard to judge which table is better. As for filtering, trying to model an analog signal can be complicated, especially when the 3 voices are wired together and can give some feedback effect on each other depending on their period.

Yeah it's a mess. I should have kept track of the musics that made me change things for future test but I didn't.

What about the noise generator period ? Because in sc68 I use noise_per*2 but I'm not too sure about it. The documentation IMO is not very clear . But as I remember it if I don't do it the noise does not sound right.

User avatar
npomarede
Atari God
Atari God
Posts: 1178
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: MFP / CPU clock ratio

Postby npomarede » Sat May 06, 2017 6:23 pm

BenOVR wrote:I don't know which version of this document you have. Mine is too LQ to read the lower values.

see the attached png, it's a little hard to read for the lowest value, but I'm not sure it matters that much for such low values.
ym_volumes.png

What about the noise generator period ? Because in sc68 I use noise_per*2 but I'm not too sure about it. The documentation IMO is not very clear . But as I remember it if I don't do it the noise does not sound right.

I found it quite hard to compare noise per difference by just listening to it ; I can use my STF program to measure tone per behaviour to also check noise per too (that's something I intented to do but didn't have time yet) ; with high noise_per value it should be possible to record a wav that is not too much filtered and compare the phase length with a tone of similar period.

For now, I use the same method for tone and noise in Hatari, noise_per is not multiplied by 2.
You do not have the required permissions to view the files attached to this post.

User avatar
troed
Atari God
Atari God
Posts: 1213
Joined: Mon Apr 30, 2012 6:20 pm
Location: Sweden

Re: MFP / CPU clock ratio

Postby troed » Sat May 06, 2017 6:46 pm

Not that I understand most of your discussion, but one difference between sc68 and Hatari is in the hi-hats of all recent 7an songs. sc68 is much closer to real hw, Hatari renders them very loud. AFAIK they're mostly pure noise (but I'm not the musician of the group so that's my assumption ... )

/Troed

User avatar
BenOVR
Atariator
Atariator
Posts: 25
Joined: Wed Nov 02, 2016 7:54 pm
Contact:

Re: MFP / CPU clock ratio

Postby BenOVR » Sat May 06, 2017 7:07 pm

Okay that the same documentation. I'm not sure it matters either. I was just wandering how values were picked.

That noise thing was something I did age ago. At the time I was positive about it. I'm going to look for musics. In the meantime my PC boot is back ! I've attached the cancel-out sndh and sources.
You do not have the required permissions to view the files attached to this post.

User avatar
npomarede
Atari God
Atari God
Posts: 1178
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: MFP / CPU clock ratio

Postby npomarede » Sat May 06, 2017 9:50 pm

troed wrote:Not that I understand most of your discussion, but one difference between sc68 and Hatari is in the hi-hats of all recent 7an songs. sc68 is much closer to real hw, Hatari renders them very loud. AFAIK they're mostly pure noise (but I'm not the musician of the group so that's my assumption ... )
/Troed

Yes, while comparing today the same musics without the filters enabled in Hatari at the moment, some instruments sound clearer and less attenuated. Maybe the current filters remove too much high freq ; on the other hand if we leave too much high freq we can obtain wrong results too, so it's a difficult balance to find.
I think in the end there might be a choice in the UI to choose between several methods.

Nicolas

User avatar
npomarede
Atari God
Atari God
Posts: 1178
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: MFP / CPU clock ratio

Postby npomarede » Sat May 06, 2017 10:03 pm

BenOVR wrote:That noise thing was something I did age ago. At the time I was positive about it. I'm going to look for musics. In the meantime my PC boot is back ! I've attached the cancel-out sndh and sources.

Thanks, I just tested it with Hatari 2.0 and new sound emulation :
- with Hatari 2.0, phases never cancel each other completely, but they sometimes overlap a little, which gives a slightly lower sound
- with new YM emulation : phases will really cancel each other after randomly restarting 4 or 5 times the song. This is not not exactly the theoretical value of 50%, but it's a good confirmation of this behaviour.

Nicolas

User avatar
BenOVR
Atariator
Atariator
Posts: 25
Joined: Wed Nov 02, 2016 7:54 pm
Contact:

Re: MFP / CPU clock ratio

Postby BenOVR » Sat May 06, 2017 10:35 pm

npomarede wrote:
BenOVR wrote:That noise thing was something I did age ago. At the time I was positive about it. I'm going to look for musics. In the meantime my PC boot is back ! I've attached the cancel-out sndh and sources.

Thanks, I just tested it with Hatari 2.0 and new sound emulation :
- with Hatari 2.0, phases never cancel each other completely, but they sometimes overlap a little, which gives a slightly lower sound
- with new YM emulation : phases will really cancel each other after randomly restarting 4 or 5 times the song. This is not not exactly the theoretical value of 50%, but it's a good confirmation of this behaviour.

Nicolas


On the real machine with the track #1 you have 3 cases (in reality it's probably 4 but both cases without cancel are indistinguable). Most of the time you have either cancel or no cancel, but what seems to be less often (more test needed) you have a almost cancel. That case is really interesting as the sound is not stable. My best guest is that the configuration of channel A and channel B happens between 2 cycles (250kz). The resulting in a very small high front that is being filtered slowly causing the unstability. Unfortunately I have to listen on the awful speaker of my TV so it could be just me :)

Regarding the noise. I've compared some musics with noise_per, noise_per*2 and the record from SNDH Record. Looking at the waveform I'd say my hearing did not betray me. It seems pretty clear to me that there is indeed a factor 2. Now the follow up question is: is it a per * 2 or just the increment happening 2 times less (@125khz). The latter seems more likely. Anyway it's almost the same except for the per=0 / per=1 cases. More investigation to do.

User avatar
npomarede
Atari God
Atari God
Posts: 1178
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: MFP / CPU clock ratio

Postby npomarede » Sun May 07, 2017 10:06 am

BenOVR wrote:On the real machine with the track #1 you have 3 cases (in reality it's probably 4 but both cases without cancel are indistinguable). Most of the time you have either cancel or no cancel, but what seems to be less often (more test needed) you have a almost cancel. That case is really interesting as the sound is not stable. My best guest is that the configuration of channel A and channel B happens between 2 cycles (250kz). The resulting in a very small high front that is being filtered slowly causing the unstability. Unfortunately I have to listen on the awful speaker of my TV so it could be just me :)

That's also something I wondered : it's known that writing per=0 then per=xxx will "reset" the square wave and immediately starts a new phase. But 1 cycle at 250 KHz is 32 cpu cycles à 8 MHz. So, if we write per=0 then write per=500 less than 32 cpu cycles later, we could expect that per=0 might be ignored sometimes as we don't leave enough time to reach the next 250 KHz clock tick. I didn't try this on my ST, but as it would be random anyway, I don't think that matter on the sound result.
At least this could explain why emulation (which doesn't take into account this 32 cycles limit) and real STF don't necessarily give the same percentage of phase cancellation.
Regarding the noise. I've compared some musics with noise_per, noise_per*2 and the record from SNDH Record. Looking at the waveform I'd say my hearing did not betray me. It seems pretty clear to me that there is indeed a factor 2. Now the follow up question is: is it a per * 2 or just the increment happening 2 times less (@125khz). The latter seems more likely. Anyway it's almost the same except for the per=0 / per=1 cases. More investigation to do.

I will try to do a record of this case on my STF, it should give us the answer. But the AY doc tells tone and noise counters work the same way, I would expect it to be the same on the YM, as both AY and YM have the same formula to compute tone/noise freq in the YM doc.

User avatar
BenOVR
Atariator
Atariator
Posts: 25
Joined: Wed Nov 02, 2016 7:54 pm
Contact:

Re: MFP / CPU clock ratio

Postby BenOVR » Sun May 07, 2017 11:22 am

npomarede wrote:That's also something I wondered : it's known that writing per=0 then per=xxx will "reset" the square wave and immediately starts a new phase. But 1 cycle at 250 KHz is 32 cpu cycles à 8 MHz. So, if we write per=0 then write per=500 less than 32 cpu cycles later, we could expect that per=0 might be ignored sometimes as we don't leave enough time to reach the next 250 KHz clock tick. I didn't try this on my ST, but as it would be random anyway, I don't think that matter on the sound result.
At least this could explain why emulation (which doesn't take into account this 32 cycles limit) and real STF don't necessarily give the same percentage of phase cancellation.


That's why I have included 4 tracks in the cancelout sndh.

I've updated it with a few nops between the 2 movep.l instructions in order to separate both programmation by exactly 32 cycles. That way the subsong #3 and #4 never cancel ``perfectly'' (it's never perfect but I assume it's because of the wiring) while subsong #1 and #2 are the same as described before.

npomarede wrote: this case on my STF, it should give us the answer. But the AY doc tells tone and noise counters work the same way, I would expect it to be the same on the YM, as both AY and YM have the same formula to compute tone/noise freq in the YM doc.


Nice. I wish I could help with that. I had a modified SCART to get the audio but I can't find it anymore.

Back on the original topic. I've modified the perfectsid sndh to start in a clean stat. It took a bit more than 30 minutes (~93440 VBLs) to reach the cancel out. I have yet to do the maths and compare to my measured clock ratio.

ijor
Hardware Guru
Hardware Guru
Posts: 3138
Joined: Sat May 29, 2004 7:52 pm
Contact:

Re: MFP / CPU clock ratio

Postby ijor » Sun May 07, 2017 12:14 pm

npomarede wrote:but that's harder to confirm without a complete chip decapping (as it was done by Ijor for the MMU and the Shifter)


Well ... may be we should.

...see the attached png, it's a little hard to read for the lowest value, but I'm not sure it matters that much for such low values.


This one seems to be perfectly readable: http://www.ym2149.com/ym2149.pdf

BenOVR wrote:I've updated it with a few nops between the 2 movep.l instructions in order to separate both programmation by exactly 32 cycles. That way the subsong #3 and #4 never cancel ``perfectly'' (it's never perfect but I assume it's because of the wiring) while subsong #1 and #2 are the same as described before.


Be aware that GLUE introduces wait states when accessing the PSG. See this http://www.atari-forum.com/viewtopic.ph ... 75#p303683 . There might be a tiny wake up effect here as well.

User avatar
npomarede
Atari God
Atari God
Posts: 1178
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: MFP / CPU clock ratio

Postby npomarede » Sun May 07, 2017 10:09 pm

Hi
I was able to complete my recording of noise and envelope periods to improve counters study ; measures were still made with my sync lock test program, which allows highly repeatable results and fine measurements of the phase duration in the recorded wav.

- envelope comparison : I tested 3 sounds using voice A + envelope wave $A, for 3 env period : 0, 1 and 2. wave $A gives the pattern down/up/down/up/...
during the same duration, I count 9 volumes at max for env_per=0, 9 volumes at max for env_per=1 and 5 volumes at max for env_per=2
Conclusion is that env_per=0 gives the same result as env_per=1 ; further, I see that env_per=2 is half env_per=1 (as expected) which somehow validates my measure test is not wrong. This is already handled in Hatari.
So, the YM doesn't have half period for env_per=0 as on the AY (and MAME is wrong, assuming they really described the YM and not the AY)

- noise phase duration : I compared 2 waves, one with toneA and tone_per=31 and another one with noiseA and noise_per=31. Here, as Ben thought (and as not handled in current emulators I guess), noise phase duration is in fact twice longer than a tone phase, which means noise_per is in fact multiplied by 2 (or that the YM increments noise counter at 125 KHz, while tone counter is incremented at 250 KHz). See these 2 extracts :
stf_tone_31.png
During 0.0005 sec, we have 2 up and 2 down

stf_noise_31.png
During 0.0005 sec, we have only 1 up and 1 down

As noise is random, the phase can of course be longer when random generator returns several 0 or 1 in a row. Here I measured the shortest phase possible, which means the random generator returned 0,1,0,1

I can't compare noise_per=0 with noise_per=1 to check if it's the same result, because per<7 are filtered too much at the STF output and can't be cleanly recorded with a simple audio card ; a logic analyzer would be needed for this.

But as we already know that tone_per=0 is similar to tone_per=1 and that env_per=0 is similar to env_per=1 (as measured above), I think it's safe for now to assume all counters are handled the same and noise_per=0 is similar to noise_per=1.

With these results, sound emulation can be improved, even if per=0 and per=1 are not often used ; I will add the noise_per change in the next Hatari version.

Nicolas
You do not have the required permissions to view the files attached to this post.

User avatar
BenOVR
Atariator
Atariator
Posts: 25
Joined: Wed Nov 02, 2016 7:54 pm
Contact:

Re: MFP / CPU clock ratio

Postby BenOVR » Sun May 07, 2017 10:40 pm

Thank you for that.

It's pretty much what I do with sc68. I've never doubted for the envelop as I said it's in the audible spectrum (4000hz for a triangle). Both perE==0 and perE==1 sound exactly the same.

npomarede wrote:But as we already know that tone_per=0 is similar to tone_per=1 and that env_per=0 is similar to env_per=1 (as measured above), I think it's safe for now to assume all counters are handled the same and noise_per=0 is similar to noise_per=1.
Nicolas


Probably. What I tried to explained above is that if the logic is that the counter is x2 then 0->0 1->2. With the assumption that it's a post increment+test logic then 0 would not be equivalent to 1. If it's the clock that is divided all should be the same. in sc68 I have assumed the latter. However my implementation uses something like:

Code: Select all

if (perN == 0) perN = 1;
perN *= 2;


At such high frequency it's most probably impossible to hear the difference anyway.

User avatar
npomarede
Atari God
Atari God
Posts: 1178
Joined: Sat Dec 01, 2007 7:38 pm
Location: France

Re: MFP / CPU clock ratio

Postby npomarede » Mon May 08, 2017 10:16 am

BenOVR wrote:Thank you for that.

It's pretty much what I do with sc68. I've never doubted for the envelop as I said it's in the audible spectrum (4000hz for a triangle). Both perE==0 and perE==1 sound exactly the same.

I also used per=0 == per=1 for emulation since the beginning, as it can be heard there's no difference if you simply play a tone with env_per=1 or env_per=0 on STF. At least, recording the STF output as a wav gives some kind of reproducible "proof" compared to our aging ears :)

Probably. What I tried to explained above is that if the logic is that the counter is x2 then 0->0 1->2. With the assumption that it's a post increment+test logic then 0 would not be equivalent to 1. If it's the clock that is divided all should be the same. in sc68 I have assumed the latter. However my implementation uses something like:

Code: Select all

if (perN == 0) perN = 1;
perN *= 2;


At such high frequency it's most probably impossible to hear the difference anyway.

We don't have precise idea of the electronic logic in the YM2149, but I doubt they multiplied per by 2, a simple flip-flop to divide clock by 2 would be enough to ensure the noise counter gets 125 KHz from the base 250 KHz for tone/env.
Also note that from an emulation point of view, if you do "PerN *=2" and a new perN=4 value is written, then it's more "complicated" to check if a new phase should be restarted, because you must in fact compare with 4*2 instead of 4. So I think that just incrementing noise counter every 2 emulation calls is much simpler.

ijor
Hardware Guru
Hardware Guru
Posts: 3138
Joined: Sat May 29, 2004 7:52 pm
Contact:

Re: MFP / CPU clock ratio

Postby ijor » Mon May 08, 2017 12:42 pm

npomarede wrote:We don't have precise idea of the electronic logic in the YM2149, but I doubt they multiplied per by 2, a simple flip-flop to divide clock by 2 would be enough to ensure the noise counter gets 125 KHz from the base 250 KHz for tone/env.


May be, and I'm not very familiar with the chip internals to judge what logic they could have used. But it is not exact that a flip-flop division is "simpler". A flip-flop takes lot of transistors. Most older chips avoided flops as much as possible. OTOH, multiplying a value by 2 is actually "free" in some cases. Because this is just a shift, all you have to do in hardware is to wire the source and the target correctly. That is, connect D0 to D1, D1 to D2, etc.


Social Media

     

Return to “Hatari”

Who is online

Users browsing this forum: No registered users and 1 guest