Re: [hatari-devel] Re: Interesting sound problems with Hatari?

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


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 = ""> >     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
> >>>







Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/