Re: [hatari-devel] Re: Interesting sound problems with Hatari? |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/hatari-devel Archives
]
- To: hatari-devel@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [hatari-devel] Re: Interesting sound problems with Hatari?
- From: David Savinkoff <dsavnkff@xxxxxxxxx>
- Date: Sun, 20 Apr 2014 12:21:19 -0600 (MDT)
- Thread-index: +mssBDG00ewCY2TdZ8gtVnLG+3N9cw==
- Thread-topic: Interesting sound problems with Hatari?
Hi,
Your computer is to slow for the Falcon.
----- Douglas Little wrote:
> Hi, another update.
>
> I mentioned before that I traced MixBuffer[] content, as the output to the
> Falcon DAC. No unexpected zeroes were present in this data from what I
> could see.
>
>
> I have now done the same with the audio buffer in audio.c, before it goes
> to the host OS. This buffer *does* contain zeroes.... at 56 sample
> intervals, as predicted ;-)
>
> This means there's a bug somewhere in between the two stages in Hatari. I
> don't know the nature of the bug but there is enough complexity (!) and
> special cases in the buffer size calculations that it's not to be
> completely unexpected :)
>
> I don't have any more time today, but perhaps somebody knows this code
> better than me can spot it until I get a chance to debug it.....
>
> Edited code from audio.c below...
>
> D
>
>
>
> /*-----------------------------------------------------------------------*/
> /**
> * SDL audio callback function - copy emulation sound to audio system.
> */
> static void Audio_CallBack(void *userdata, Uint8 *stream, int len)
> {
> Sint16 *pBuffer;
> int i, window, nSamplesPerFrame;
> static int counter = 0;
>
> pBuffer = (Sint16 *)stream;
> len = len / 4; // Use length in samples (16 bit stereo), not in bytes
>
> /* Adjust emulation rate within +/- 0.58% (10 cents) occasionally,
> * to synchronize sound. Note that an octave (frequency doubling)
> * has 12 semitones (12th root of two for a semitone), and that
> * one semitone has 100 cents (1200th root of two for one cent).
> * Ten cents are desired, thus, the 120th root of two minus one is
> * multiplied by 1,000,000 to convert to microseconds, and divided
> * by nScreenRefreshRate=60 to get a 96 microseconds swallow size.
> * (2^(10cents/(12semitones*100cents)) - 1) * 10^6 / nScreenRefreshRate
> * See: main.c - Main_WaitOnVbl()
> */
>
> pulse_swallowing_count = 0; /* 0 = Unaltered emulation rate */
>
> if (ConfigureParams.Sound.bEnableSoundSync)
> {
> /* Sound synchronized emulation */
> nSamplesPerFrame = nAudioFrequency/nScreenRefreshRate;
> window = (nSamplesPerFrame > SoundBufferSize) ? nSamplesPerFrame :
> SoundBufferSize;
>
> /* Window Comparator for SoundBufferSize */
> if (nGeneratedSamples < window + (window >> 1))
> /* Increase emulation rate to maintain sound synchronization */
> pulse_swallowing_count = -5793 / nScreenRefreshRate;
> else
> if (nGeneratedSamples > (window << 1) + (window >> 2))
> /* Decrease emulation rate to maintain sound synchronization */
> pulse_swallowing_count = 5793 / nScreenRefreshRate;
>
> /* Otherwise emulation rate is unaltered. */
> }
>
> if (nGeneratedSamples >= len)
> {
> /* Enough samples available: Pass completed buffer to audio system
> * by write samples into sound buffer and by converting them from
> * 'signed' to 'unsigned' */
> for (i = 0; i < len; i++)
> {
> *pBuffer++ = MixBuffer[(CompleteSndBufIdx + i) %
> MIXBUFFER_SIZE][0];
> *pBuffer++ = MixBuffer[(CompleteSndBufIdx + i) %
> MIXBUFFER_SIZE][1];
> }
> CompleteSndBufIdx += len;
> nGeneratedSamples -= len;
> }
> else /* Not enough samples available: */
> {
> for (i = 0; i < nGeneratedSamples; i++)
> {
> *pBuffer++ = MixBuffer[(CompleteSndBufIdx + i) %
> MIXBUFFER_SIZE][0];
> *pBuffer++ = MixBuffer[(CompleteSndBufIdx + i) %
> MIXBUFFER_SIZE][1];
> }
> /* If the buffer is filled more than 50%, mirror sample buffer to
> fake the
> * missing samples */
> if (nGeneratedSamples >= len/2)
> {
> int remaining = len - nGeneratedSamples;
> memcpy(pBuffer, stream+(nGeneratedSamples-remaining)*4,
> remaining*4);
> }
> CompleteSndBufIdx += nGeneratedSamples;
> nGeneratedSamples = 0;
>
> }
>
> *// dml: debug code added here to print stream content*
>
>
>
>
>
>
>
>
>
>
>
> * if (--counter < 0) { int c; counter = 100;
> pBuffer = (Sint16 *)stream; for (c = 0; c < len; ++c) {
> printf("l:%d r:%d\n", (int)pBuffer[0], (int)pBuffer[1]);
> pBuffer+=2; } }*
> CompleteSndBufIdx = CompleteSndBufIdx % MIXBUFFER_SIZE;
> }
>
>
> output:
>
> l:2175 r:2175
> l:2175 r:2175
> l:2239 r:2239
> *l:0 r:0*
> l:2239 r:2239
> l:2303 r:2303
> l:2303 r:2303
> l:2367 r:2367
> l:2367 r:2367
> l:2367 r:2367
> l:2431 r:2431
> l:2431 r:2431
> l:2495 r:2495
> l:2495 r:2495
> l:2495 r:2495
> l:2559 r:2559
> l:2559 r:2559
> l:2559 r:2559
> l:2623 r:2623
> l:2623 r:2623
> l:2687 r:2687
> l:2687 r:2687
> l:2751 r:2751
> l:2751 r:2751
> l:2815 r:2815
> l:2879 r:2879
> l:2879 r:2879
> l:2943 r:2943
> l:2623 r:2623
> l:447 r:447
> l:-1280 r:-1280
> l:-1152 r:-1152
> l:-832 r:-832
> l:-1088 r:-1088
> l:-3264 r:-3264
> l:-4928 r:-4928
> l:-4864 r:-4864
> l:-4480 r:-4480
> l:-4288 r:-4288
> l:-4160 r:-4160
> l:-4096 r:-4096
> l:-4032 r:-4032
> l:-3904 r:-3904
> l:-3904 r:-3904
> l:-3776 r:-3776
> l:-3712 r:-3712
> l:-3584 r:-3584
> l:-3520 r:-3520
> l:-3456 r:-3456
> l:-3392 r:-3392
> l:-3264 r:-3264
> l:-3200 r:-3200
> l:-3136 r:-3136
> l:-3072 r:-3072
> l:-3008 r:-3008
> l:-2880 r:-2880
> l:-2816 r:-2816
> l:-2752 r:-2752
> l:-2688 r:-2688
> *l:0 r:0*
> l:-2560 r:-2560
> l:-2496 r:-2496
> l:-2432 r:-2432
> l:-2368 r:-2368
>
>
>
>
> On 19 April 2014 22:56, Douglas Little <doug694@xxxxxxxxxxxxxx> wrote:
>
> > Hi David,
> >
> > Yes I will give it a try - however some more recent tests tonight show
> > that the filling of the DAC/output buffer (MixBuffer) does not contain
> > these zeroes. So I have started looking at the last stage, which couples
> > the MixBuffer out to the OS. I have already noticed that adding debug code
> > greatly influences the output sound (mainly echos, due to falling behind -
> > but also absent the 'glitch').
> >
> > Might be out of time on this tonight but I'll update when I know more.
> >
> > D
> >
> >
> > On 19 April 2014 22:40, David Savinkoff <dsavnkff@xxxxxxxxx> wrote:
> >
> >> Hi Douglas,
> >>
> >> I've been following your thread, and it appears you can compile
> >> Hatari. Can you compile with fifo.patch from a previous email,
> >> and give a quick summary of what you notice.
> >>
> >> Thank You,
> >> David Savinkoff
> >>
> >> ----- Douglas Little wrote:
> >> > Another update on this.
> >> >
> >> > Changing the DMA replay buffer from 256 samples to 1024 produces the
> >> same
> >> > result - zeroes inserted into the audio data every 56 samples.
> >> >
> >> > Changing the sample stepping rate from 1.0 to 2.0 in the software mixer
> >> > doubles the playback frequency of the tone as it should, but still
> >> produces
> >> > zeroes every 56 samples.
> >> >
> >> > The zeroes are not present in the source data, or in the written DMA
> >> pages.
> >> > I did what I could to record the same data to secondary linear buffers
> >> to
> >> > debug it, and to diff the recording against the original sample. I also
> >> > inspected the DMA pages themselves.
> >> >
> >> > Having tried to rule out everything of my own, I have to conclude that
> >> > something is going wrong when Hatari receives this data, or when it
> >> passes
> >> > the final mixed audio to the OS. Bear in mind I have 2 different builds
> >> -
> >> > one Windows native, and one Cygwin, obviously using different libraries
> >> and
> >> > each having their own interesting pros and cons. But they both exhibit
> >> this
> >> > problem.
> >> >
> >> > I tried '--trace crossbar' to see if something could be seen in the
> >> data,
> >> > but this just emits a lot of messages showing which devices are
> >> connected
> >> > (interestingly - it reports 3 output devices when only 1 has actually
> >> been
> >> > configured via crossbar via XBios #$8b). It also reports register
> >> writes to
> >> > the DMA address registers but not data being transferred in the pages.
> >> > '--trace dmasound' does nothing on Falcon, because the DMA/codec mixing
> >> > stuff is all done by crossbar.c, and 'dmasound' is only logged by
> >> dmaSnd.c,
> >> > which is STE-only.
> >> >
> >> >
> >> > The code below configures crossbar in my test. Only one output device is
> >> > connected. I don't understand why Hatari thinks all 3 (DSP, DMA, Codec)
> >> are
> >> > connected. It's not related to the main problem I have but it's still
> >> > strange.
> >> >
> >> > move.w #1,-(sp) ; protocol = handshaking
> >> > move.w #0,-(sp) ; prescale = 0 / STE compat.
> >> > move.w #0,-(sp) ; srcclk = 25mhz
> >> > move.w #1<<3,-(sp) ; dst = DAC
> >> > move.w #0,-(sp) ; src = DMA
> >> > move.w #$8B,-(sp)
> >> > trap #14
> >> > lea 12(sp),sp
> >> >
> >> >
> >> >
> >> > I haven't had any response on the 56-sample-spaced zeroes so far, so I
> >> have
> >> > to assume nobody else has seen it. Maybe somebody will find the time to
> >> > *record* audio output from Hatari and see if they can reproduce this?
> >> >
> >> > For reference I'm playing a waveform note 'D4' sampled @ 12294Hz, with
> >> > Hatari configured at 12khz audio quality + synchronize, capturing the
> >> sound
> >> > being emitted through the system mixer, and comparing with the source
> >> > sample.
> >> >
> >> > I'll see if I can mod Hatari to show me what's being passed to the OS,
> >> to
> >> > narrow down the point where the zeroes first appear (assuming it's not
> >> the
> >> > OS itself).
> >> >
> >> > D
> >> >
> >> >
> >> >
> >> > On 17 April 2014 22:33, Douglas Little wrote:
> >> >
> >> > > So I'm still digging into this audio replay noise/glitching problem
> >> via
> >> > > Hatari and still haven't found a cause I can tie to my own code.
> >> > >
> >> > > One of the things I did was change the size of the DMA replay buffer,
> >> to
> >> > > see if the glitches changed frequency / spacing. This did not affect
> >> the
> >> > > result. Several captures with different sized DMA buffers resulted in
> >> the
> >> > > same spacing between glitches.
> >> > >
> >> > > I also tried a Windows native build (daily build FTP) with my own
> >> Cygwin
> >> > > build, in a bid to rule out any stuff specific to SDL libraries etc.
> >> > > Problem is still present.
> >> > >
> >> > >
> >> > > Played via Hatari at 12khz, captured via Audacity at 44khz and with
> >> the
> >> > > spacing measured in samples and rescaled, it amounts to something
> >> like 200
> >> > > samples between each glitch in the capture, or 56 samples in real
> >> terms,
> >> > > between each glitch in the source data @ 12khz. This seems quite
> >> > > consistent, although occasional glitches have appeared in-between
> >> these
> >> > > regular spacings.
> >> > >
> >> > >
> >> > > The 'glitch' when examined up close, looks like zeroes placed into
> >> the DMA
> >> > > stream at regular intervals. See snap below:
> >> > >
> >> > > https://dl.dropboxusercontent.com/u/12947585/glitch.png
> >> > >
> >> > > I can't explain this, and can't see it in the data I'm feeding into
> >> the
> >> > > DMA pages. Does anyone have a clue where these zeroes might originate?
> >> > >
> >> > > D
> >> > >
> >> > >
> >> > >
> >> > > On 16 April 2014 19:05, Douglas Little wrote:
> >> > >
> >> > >> ...have scraped a little more information on this one.
> >> > >>
> >> > >> I dumped the DMA pages for the sample painted in memory, and
> >> performed a
> >> > >> binary diff against the original sample data on disk, with the WAV
> >> header
> >> > >> stripped off. The data is a perfect match, up to the first loop point
> >> > >> (which is about 18k into the sample - quite far). Beyond the loop
> >> point the
> >> > >> deltas correspond to the original sample at the intended loop point.
> >> > >>
> >> > >> So the source data being painted into memory is perfect.
> >> > >>
> >> > >> This seems to leave 3 possible points of failure:
> >> > >>
> >> > >> 1) It is somehow being painted into the wrong place in memory, but
> >> not so
> >> > >> wrong that it results in more than periodic glitches (this seems very
> >> > >> unlikely, especially as the 'glitches' correspond to page swaps)
> >> > >> 2) What has been painted into the DMA pages is not what is actually
> >> going
> >> > >> to the 'codec'
> >> > >> 3) What is going to the 'codec' is not what is going to the Windows
> >> sound
> >> > >> system
> >> > >>
> >> > >> I'm leaning towards #2 or more likely #3, which means a problem in
> >> Hatari
> >> > >> or with the coupling of Hatari to the OS sound API, on Windows at
> >> least.
> >> > >>
> >> > >> I'll keep digging though, just in case ;)
> >> > >>
> >> > >> D
> >> > >>
> >> > >>
> >> > >>
> >> > >>
> >> > >> On 16 April 2014 18:34, Douglas Little wrote:
> >> > >>
> >> > >>>
> >> > >>> So apart from the issues already discussed by Laurent/David, I'm
> >> having
> >> > >>> my own world of pain at the moment with another sound issue, and
> >> which
> >> > >>> *seems* to be limited to Hatari based on what I have been able to
> >> try so
> >> > >>> far.
> >> > >>>
> >> > >>>
> >> > >>> I am doing my best to narrow this down but it is difficult indeed
> >> :) So
> >> > >>> here is what I can tell you.
> >> > >>>
> >> > >>> 1) I'm getting distortion while playing back samples in Hatari while
> >> > >>> emulating F030. (I've been trying to rule out real HW but I'm
> >> having other
> >> > >>> problems with the machine so haven't managed it quite yet).
> >> > >>>
> >> > >>> 2) The distortion seems to be related to double-buffering of the DMA
> >> > >>> pointers which keep the Codec fed continuously with data (think
> >> modplayer
> >> > >>> here). The distortion seems to have a period which roughly matches
> >> the
> >> > >>> buffer length. I currently use a DMA page size of 246 samples, if
> >> that
> >> > >>> means anything to anyone (12khz @ 50hz period).
> >> > >>>
> >> > >>> 3) The values involved in the distortion seem to be random but I am
> >> not
> >> > >>> 100% sure since I'm looking at captures of audio output from the
> >> emulator.
> >> > >>>
> >> > >>> 4) The distortion does not seem to be present in the memory pages
> >> being
> >> > >>> DMA'd to the Codec - filling a circular buffer with the same data
> >> and
> >> > >>> dumping it out looks *correct* and contiguous.
> >> > >>>
> >> > >>> 5) The addressing used to increment through the sample has been
> >> fixed at
> >> > >>> one unit (i.e. a direct 1:1 copy of the sample to the DMA buffers
> >> with no
> >> > >>> skipping/duplication of bytes). I have ruled out the mixer code
> >> being
> >> > >>> faulty also - 3 different variants produce identical results.
> >> > >>>
> >> > >>> 6) Recording the individual sample *indexes* to a circular buffer
> >> shows
> >> > >>> the expected pattern of 0,1,2,3... until the loop point, after
> >> which it
> >> > >>> resets to 0 and continues for as long as I let it. No problems there
> >> > >>> either. Loop point in source sample never varies.
> >> > >>>
> >> > >>> 7) I tried decoupling the DMA pages using 8 buffers and reading
> >> (codec)
> >> > >>> / writing (my mixer code) 4 buffers apart to be absolutely sure the
> >> DMA'd
> >> > >>> pages are not being written while in use - no improvement. Not the
> >> cause.
> >> > >>>
> >> > >>>
> >> > >>> Other interesting points:
> >> > >>>
> >> > >>> - A very large noise signature can be obtained by just changing
> >> Hatari's
> >> > >>> 'playback quality'. Setting it to 50khz while playing samples at
> >> 12khz via
> >> > >>> the Falcon's Codec results in... mostly noise and not much signal
> >> left (see
> >> > >>> linked capture below). This might just be due to a lack of
> >> filtering but it
> >> > >>> seems to be really, really bad (!).
> >> > >>> - Changing the playback quality does not stop the periodic
> >> distortion -
> >> > >>> it just adds more noise per individual sample event.
> >> > >>>
> >> > >>>
> >> > >>> I have linked a screengrab of what I get from Hatari in the 2
> >> 'quality'
> >> > >>> modes, playing one looped sample.
> >> > >>>
> >> > >>> https://dl.dropboxusercontent.com/u/12947585/wavefm.png
> >> > >>>
> >> > >>> The top capture is the original sample @ 22khz.
> >> > >>>
> >> > >>> The middle capture is replay within Hatari @ 12khz codec rate, but
> >> 50khz
> >> > >>> Hatari quality (yikes! look at the noise levels!).
> >> > >>>
> >> > >>> The lower capture is the same, but set to 12khz Hatari quality.
> >> This is
> >> > >>> the most interesting one - notice the spikes/glitches at spaced
> >> intervals?
> >> > >>>
> >> > >>>
> >> > >>> I'm still looking into this and doing what I can to isolate possible
> >> > >>> causes but I'm running out of things to look at in my code. Can
> >> anything
> >> > >>> strange be going on in Hatari which could cause the glitches on
> >> each DMA
> >> > >>> page change? Could it be related to the host OS sound interface, or
> >> must it
> >> > >>> be within the emulation layer or the emulated code?
> >> > >>>
> >> > >>> D
> >> > >>>
> >>
> >>
> >>
> >>
> >