Re: [hatari-devel] Preserving YM2149 sound phase

[ Thread Index | Date Index | More Archives ]

Hi Nicolas,

I just found a revealing article by gwEm:

The second half of the article after **** is what caught my attention:

 Alive 9
 Start synchronisation techniques,
       YM sampling and
    a brand new YM effect

Many times I hear  the tip that all  you have to do  to speed up YM  replay into
half a scanline  is to sample  the YM register  every 50Hz and  simply dump them
back to the chip on replay without calculation.

This is simply wrong ;) Sure, it will work for many tunes - but dumb YM sampling
like this will  fail to capture  some YM effects  using techniques developed  by
classic  chip composer  Dark Angel/Aura.  This is  also why  tunes using  these
techniques are not reproduced correctly  in JAM for Windows, which  also ignores
the special YM behaviour used.

MusicMon2 and my up-coming editor  maxYMiser use this behaviour to  create whats
best described as note start synchronised phasing effects.

Most people know that writing to the YM buzzer waveform register retriggers  the
envelope from its  start (as stated  in the YM2149  datasheet). Whats not  often
known is  that its  possible to  retrigger the  squarewave in  this way as well.
Heres a bit of code that does just that for YM squarewave channel A:

        move.l      #$00000000,$ffff8800.w
        move.l      #$01000000,$ffff8800.w
        move.l      #$0000xx00,$ffff8800.w
        move.l      #$0100xx00,$ffff8800.w

as you see the two YM  registers for squarewave frequencies are cleared  to zero
shortly, before being immediately set for the required frequency. Obviously this
effect is impossible to record using simple YM2149 sampling.

You can  create a  combined buzzer/squarewave  sound, and  by synchronising both
square and  buzzer waves  at the  start of  the note  you can achieve repeatable
phasing,  which  great for  smooth  pad and  dirty  bass sounds  with  the right

  The sync-square
  a new YM effect?

You  might think, ok so we can  sync the squarewave - why not apply  this method
to create  a kind of syncbuzzer sound,  but for the square  wave. I also thought
this  ;)  The  problem   is   that   synchronising   the   squarewave   is   not
completely reliable. Actually  the squarewave is  only restarted  from  the last
time  it changed   state, and  not from  a known  phase.  This  gives two  sync
possibilities, either  where it syncs with the square starting again low(1),  or
when it starts again high(2):

  |  | (1)
--+  +-->

--+  +-->
  |  |

If you play  with MusicMon2 you'll  be able to  hear two distinct  variations in
phasing, seemingly at random. Its not possible to retrigger the squarewave  with
the timer each time with enough precision to give repeatablity, except for  very
low bass notes.  Normally you might  hear some glitchy  distorted tones unusable
for melodic instruments.

STeem and SainT  emulate this YM  squarewave synchronisation such  that the wave
restarts at  a given  phase reliably,  but remember  on real  YM this is not the
case. If you wish to experiment  further with this effect, you'll find  the code
fragment shown  above gives  the best  performance, or  wait for  the release of

gwEm                                                                    Jan 2005

----- Nicolas Pomarède wrote:
> Le 17/10/2016 à 23:46, David Savinkoff a écrit :
> > Hi Nicolas,
> >
> > The following was posted on Atari Forum, and was
> > partially investigated:
> > ****
> >
> >
> > "Postby troed » Sun Dec 20, 2015 10:20 pm
> > Re: some questions about YM2149F vs emulators vs MIST
> >
> > There are several ways in which Hatari doesn't sound like an
> > original machine. The first version of 7an's song for our
> > STNICCC demo "Closure" had to be scrapped altogether.
> > He wrote the song(s) in Hatari which apparently always plays
> > all voices in phase, while on actual hardware they fall in
> > and out of phase (sometimes cancelling each other out completely).
> > This is somewhat better emulated by SC68."
> > ****
> >
> > The enclosed patch tested ok on the few demos that I tried.
> > Please see if it works for you.
> >
> > This patch preserves the value in posA, posB and posC
> > rather than over-writing the value when stepA, stepB
> > or stepC is zero. Thus reducing interference with the phase.
> >
> > stepA, stepB and/or stepC are no longer set to zero when a
> > frequency is higher than the sampling rate, this affects
> > phase also.
> >
> > I'm hoping this patch solves the phase problem.
> >
> > Sincerely,
> > David Savinkoff
> >
> Hi
> thanks for your patch ; I'm aware of the problem, but before applying 
> any new patch, I'd like to do some "high frequency" recording of the 
> analog YM output of my STF to carefully measure what happens exactly 
> when PerLo/PerHi are changed, depending on which point of the square 
> wave we're at the moment of the change.
> Basically, this all depends on own the YM uses the PerLo/Hi value :
>   - does it starts an internal counter from 0 and change phase when 
> counter reaches Per ?
>   - does it starts an internal counter from Per and decrement it and 
> change phase when it reaches 0
> - If so, does it change phase when reaching Per (or 0) or at the next 
> iteration ?
> I saw numerous implementations of the YM (or its derivative), each one 
> claiming "compatibilty" with the original chip (fpga, vhdl, MAME, ...), 
> but each one with a different way to count :(  It seems the correct way 
> is to start at 0 and change when reaching Per, but that's I want to 
> measure (that's not how Hatari works at the moment, hence the problem)
> To do so, I'm planning some very precise writes in the sound register 
> (sync'ed with the video counter) to get a very reproducable test and to 
> be able to change PerLo or PerHi at some exact point where the phase is 
> supposed to change in the YM (or just after/before).
> Depending on whether each write will have an effect or not, I will be 
> able to determine how the YM takes Per regs into account and if a change 
> to them is immediate or not.
> Nicolas

Mail converted by MHonArc 2.6.19+