Shop OBEX P1 Docs P2 Docs Learn Events
Console Emulation - Page 64 — Parallax Forums

Console Emulation

16061626466

Comments

  • None at all? Not even glitches? The magic and the mystery of potato knishes.

  • roglohrogloh Posts: 5,642
    edited 2024-09-17 19:29

    Did some more digging through the captured file. I discovered that for the RasPi output that there were a total of 12845 audio samples sent per 7864320 pixels. At the 27MHz pixel rate this is 44099.8 samples/sec or 44.1kHz. This lines up with the strange N/CTS values seen above but does not line up with the SPDIF channel status bits that were sent out indicating a sample rate of 48kHz. I don't understand why this is the case but it is, and it apparently plays back fine on my AVR & Plasma setups over HDMI.

    It also indicates why the CTS fluctuates slightly as these clocks are going to be asynchronous to each other (and the TDMS pixel clock doesn't divide neatly down to 44.1kHz, but does for 48kHz)

    Eg.
    128 x 44100 = Ftmds * N/CTS
    N=5632 , CTS ~ 26938 so Ftmds = 26.999222MHz (close enough to 27MHz).

    R Channel Status:
    00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_
    00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000000_
    00000000_00000000_00000000_00000010_00000010_ 00000000_10000010_00000100_

    Also interesting to see visually where these packets are sent in the data islands. I expanded my PPM image generator to include the inactive pixels and you can see the different audio sample packets going out on almost every line or two, the less frequent clock regeneration packets about every 30-31 scan lines and the infoFrame at the top of the frame. You also see the two video guard pixels just before the first active screen pixel on the left.

  • @rogloh I pushed an extended channel status patch. Maybe double check that it actually sends the right thing. If you want it you can have the full 192 bits.

    Also, something to take note of: NeoYume only starts the audio output when the emulation actually starts, so during loading there will be no sample packets. So maybe try hotplugging it after loading. Though I should fix that anyways, some devices are slow enough at syncing that the beginning of the jingle gets cut off, which is of course unacceptable.

  • roglohrogloh Posts: 5,642

    @Wuerfel_21 said:
    @rogloh I pushed an extended channel status patch. Maybe double check that it actually sends the right thing. If you want it you can have the full 192 bits.

    Cool. It's good if we can have full control of that pattern without impacting actual code path timing like the hack I did.

    Also, something to take note of: NeoYume only starts the audio output when the emulation actually starts, so during loading there will be no sample packets. So maybe try hotplugging it after loading. Though I should fix that anyways, some devices are slow enough at syncing that the beginning of the jingle gets cut off, which is of course unacceptable.

    Will try the hotplug test today.

  • Wuerfel_21Wuerfel_21 Posts: 4,926
    edited 2024-09-18 01:48

    Some more odds&ends: Here's a version of vgatest modified to play non-trivial 44.1kHz data (in the form of heptafon bitstream files - could have made a WAV player, but I already had the heptafon stuff around) with resampling bypass. Maybe useful as another data point. Here's a HEP file to get you started: https://mega.nz/file/HOpWRaKB#uVROwjZJmIcGLJFHtxp3kN041Vca8qm84CoSsiNgJtw

  • roglohrogloh Posts: 5,642
    edited 2024-09-18 03:45

    Just took your latest hdmi-clk-regen-branch (I cloned & checked out a fresh tree to be sure I had everything clean) and ran vgatest.binary. I then hot plugged HDMI into waiting TV input.
    Result : Morse code effect

    Also for fun retried the video-nextgen branch from same clean tree
    Result : No audio at all

    Will take a look at that heptafon stuff next.

    One thing I might also try to do is solder down a proper wire from the 5V HDMI connector to be sure its attached wire is not wiggling around and messing it up. I know if I pull that wire out the audio does drop out. I'd love for that to be the cause of all these problems, but I don't think it is as I've held it in place very firmly many times and it still plays Morse code.

    Update: I also just captured your latest driver HDMI output and do see the SPDIF channel status bits 32-63 being updated with the data from your new extended spdif long variable. So that change seems to be working ok.

  • roglohrogloh Posts: 5,642
    edited 2024-09-18 09:36

    So to help figure out if there are audio buffer problems with the HDMI audio output I've extended the tm.c file to also model an audio FIFO. When an audio sample arrives in the decoded bitstream a buffer size variable is increased by 1. To simulate playing out the sample from the buffer and decrementing the buffer size at the right playback time the code does this once the first CTS & N integer values are known from the first clock regen packet (I'm assuming they remain constant after that for now):

    The code starts counting TMDS clocks from this point forward and divides by "CTS" giving a fractional value which is stored as a double precision number. If you multiply this fraction by N this gives the number of 128xFs audio clocks that should have elapsed by this time. By shifting that number right by 7 bits it divides it by 128 and this number gives us the actual audio sample output clock count. When this value changes from its prior value the FIFO size is decremented by one to account for an audio sample going out of the FIFO. The FIFO size can be monitored throughout the decode and we can see when samples are put in and when they are removed. If the FIFO size ever drops below zero then the FIFO has underflowed and this is identified as well.

    When processing captured NeoVGA HDMI audio output I never see the simulated FIFO underflow or exceed the number of samples stored before the first N/CTS value arrives. I am observing the FIFO sample depth values of 17,18,19,20 and the FIFO hits 20 at the time of the first FIFO read operation at the arrival of first clock regen packet in my simulator. I'm assuming a TV or other HDMI sink would just be throwing away samples until the first clock regen packet arrives as it would have no idea about how to regenerate the audio sample clock until this happens.

    When I monitor the RasPi HDMI audio output I see the buffer doesn't go higher than 39 entries which again is the size of the FIFO the time the first sample is read out in my simulation.

    Next up is looking at jitter to see if that might be different somehow. Perhaps the time between the first audio sample arrival after the first regen packet is important if samples are being thrown away before that is seen?

    The tm.c code is attached in the zipfile and includes the new audio FIFO simulation plus more robustness cleanups and better text column alignment between 32 bit decoder and byte mode decoder variants to try to be more consistent.

    You can use "grep" to search for "sample" and you'll see the FIFO writes and reads and the clock and buffer values in some columns.

  • roglohrogloh Posts: 5,642

    @rogloh said:
    Will take a look at that heptafon stuff next.

    Loaded your Heptafon vgatest version @Wuerfel_21 and gave it a go on my Plasma. Hearing short bursts of the Chipmunk sounding music before it intermittently mutes out for fractions of a second and resumes. I think it's probably playing back at the correct rate based on the backing music, could be more just the style of music is really high pitched. Will try to record it for you to see if you think it's playing at the correct rate...

  • roglohrogloh Posts: 5,642

    Here's the file I recorded re-encoded as wav but sounds the same.

  • Excuse the music taste, I just grabbed what was laying around. You can check what it's supposed to sound like by plugging headphones in, the analog out is active as with NeoYume. But also here's the Youtube upload for that one. Note that the heptafon codec for PC can be used to encode/decode to a heart's desire. I really should've just made a WAV player, the heptacular hubris got to me...

  • roglohrogloh Posts: 5,642

    Listening to the original I'm wondering if the TV is playing it back at 48 instead of 44kHz - almost sounds a little faster... but I've not be able to find the exact part I captured yet to compare fully.

  • roglohrogloh Posts: 5,642

    A WAV file player doing 44.1kHz source would be far better for testing then I could load some known music and could verify the tempo rather than play this unfamilar high pitched music to begin with. I'm really wondering if the TV is trying to output this at 48kHz when it should be played at 44.1 or perhaps this resampling stuff is messing it up somehow.

  • It's definitely too fast. You can even see it:

    So the buffer runs out all the time and that causes the gaps.

  • roglohrogloh Posts: 5,642

    Yeah that's whats happening. Is it approximately 44/48th too little data?

  • roglohrogloh Posts: 5,642

    Another datapoint I found is that NeoVGA is outputting a lot more two sample audio packets containing Samples 0&1 in subpackets (more than half) vs the RasPi which is about 1/4 although this could be resolution related.
    ❯ grep "Sample 0" out-neo | wc
    2830 65090 452800
    ❯ grep "Sample 1" out-neo | wc
    1632 37536 261120

    RasPi @576p50
    ❯ grep "Sample 0" out | wc
    10270 236210 1643200
    ❯ grep "Sample 1" out | wc
    2574 59202 411840

  • @rogloh said:
    Yeah that's whats happening. Is it approximately 44/48th too little data?

    Yes, exactly that much. Very odd. I did change the channel status and clock regen to do 44.1 and bypassed the resampler (in NeoVGA! You are using the one that came with the ZIP, right?)

    I probably should make a WAV version. The temptation to use in-house irqsoft technology, it must not be given in to. (But as said, the codec can convert raw PCM to HEP)

  • @rogloh said:
    Another datapoint I found is that NeoVGA is outputting a lot more two sample audio packets containing Samples 0&1 in subpackets (more than half) vs the RasPi which is about 1/4 although this could be resolution related.
    ❯ grep "Sample 0" out-neo | wc
    2830 65090 452800
    ❯ grep "Sample 1" out-neo | wc
    1632 37536 261120

    RasPi @576p50
    ❯ grep "Sample 0" out | wc
    10270 236210 1643200
    ❯ grep "Sample 1" out | wc
    2574 59202 411840

    The Pi might use more flexible tx scheduling, so during blanking it wouldn't always send them in fixed timeslots once per line. 48/31.5 is roughly 1.52, so it would make sense that slightly more than half the packets hold two samples.

  • roglohrogloh Posts: 5,642
    edited 2024-09-18 13:31

    @Wuerfel_21 said:

    @rogloh said:
    Yeah that's whats happening. Is it approximately 44/48th too little data?

    Yes, exactly that much. Very odd. I did change the channel status and clock regen to do 44.1 and bypassed the resampler (in NeoVGA! You are using the one that came with the ZIP, right?)

    OMG I'm think I using the NeoVGA from your latest top of tree with this..
    spdif_status long %00_00_0010_00000000_10000010_00000100
    '|||| 24 bit sample length (load bearing)
    long %00000000_00000000_00000000_0000_1011

    Can't locate the unzip folder from the downloaded zipfile - it looks like opened up in my Downloads just as vgatest.spin2 at the top level which is really strange.
    Looking at my history it seems that it downloaded as vgatest.spin2 and I thought I could just copy that into a latest NeoYume folder for testing there.

    1758 mv ~/Downloads/vgatest.spin2 ~/Code/Propeller2/NeoYume/heptest.spin2
    1759 mv ~/Downloads/blue44.hep ~/Downloads/test.hep
    1760 ls /Volumes/RL/
    1761 cp ~/Downloads/test.hep /Volumes/RL

    Will retry this from the updated? zip in your post above.

  • I think flexspin's ZIP generator exploded there and tried to include half the libc, maybe your ZIP program got confused. @ermsith this is no bueno

    Owie owie ouch that's a painful one.

  • roglohrogloh Posts: 5,642
    edited 2024-09-18 13:43

    I will retry with that one you just posted now. My command history doesn't make sense other than it barfed on the first zip. I think that will be the issue as I didn't use your custom NeoVGA.spin2. Will update this post with the result.

    RESULT - seems to play fine now at a decent tempo and no dropouts. Now you just need to make your normal NeoVGA work this way and my AV gear will be happy. :smile:

  • So the problem is that regular NeoVGA craps out despite the sampling rate being ostensibly correct... Our accidental misadventure here shows that the TV's buffer can get quite long, so I wouldn't know how exact sample delivery timing would cause a problem. I'll have to triple check the resampler logic.

  • roglohrogloh Posts: 5,642

    Just for fun I took current hdmi-clock-regen vgatest.spin2 and made it play out at 44.1 instead of 48 by patching byte 3 of the channel status.

    spdif_status  long %00_00_0000_00000000_10000010_00000100
                                                          '|||| 24 bit sample length (load bearing)
                     long %00000000_00000000_00000000_0000_1011
    

    Result is the colour bars plus a tone without dropouts but some small amount of (white?) noise added the signal as well. I think it's just dropping samples, not sure if the tone is correct freq or not, needs software analysis of the recording which I'm not setup to do ATM. This is different to the Morse code effect I had before which may be a buffer underrun.

  • ???

    So you're getting a different result just by changing the channel status? That seems very cool and not at all odd.

    The resampler output frequency should be within tolerance for 48 kHz.

  • roglohrogloh Posts: 5,642
    edited 2024-09-18 14:20

    @Wuerfel_21 said:
    ???

    So you're getting a different result just by changing the channel status? That seems very cool and not at all odd.

    Yep.

    The resampler output frequency should be within tolerance for 48 kHz.

    In my simulation in the tm.c file it does seem to send enough to not overflow or underflow based on the given N/CTS values and pixel clocks when samples are sent. Haven't done the jitter analysis but I don't think it would matter much if you send almost every scan line.

  • If the channel status rate matters, then by extension it probably matters that the real-time output rate is within 1000ppm. We see it works with direct non-resampled outputs, so it's the resampler. It can only produce an output sample when a new input sample arrives. It doesn't produce them all the time and that's how it reduces the rate. So it's either the jitter of aligning the output sample timings to the input samples or the phase/ratio logic causes there to be slightly too many or too few samples. I had that issue earlier, where my monitor would take the signal but not the upstairs TV and it turned out there was a typo that was causing the ratio to be off.

  • roglohrogloh Posts: 5,642
    edited 2024-09-18 14:41

    Well 1000ppm is less than 1 in 1000 pixels which less than one scan line if you send 1075 pixels. It'll be important to not underflow on any single scanline then. I do see the buffer vary from 17 to 20.

    EDIT: Also that rounding of the clock you do worries me.
    SAMPLE_OUT_PERIOD = (VIDEO_CLKFREQ+24000)/48000

    Actually on second thoughs it's probably only off by around 1 part in 7000 or so, so it should be okay if the tolerance is 1000ppm.

  • @rogloh said:
    Well 1000ppm is less than 1 in 1000 pixels which less than one scan line if you send 1075 pixels. It'll be important to not underflow on any single scanline then. I do see the buffer vary from 17 to 20.

    EDIT: Also that rounding of the clock you do worries me.
    SAMPLE_OUT_PERIOD = (VIDEO_CLKFREQ+24000)/48000

    Actually on second thoughs it's probably only off by around 1 part in 7000 or so, so it should be okay if the tolerance is 1000ppm.

    It's rounded to an integer period, which is useful/needed for constant N/CTS values. Plain VIDEO_CLKFREQ/48000 is far more off (though you can try that if you want)

  • Wuerfel_21Wuerfel_21 Posts: 4,926
    edited 2024-09-18 15:30

    One silly thing to try would be to change the resampler to do 44.1 instead of 48. To do that, you'd only need to change SAMPLE_OUT_PERIOD and the channel status.
    Resampler seems to correctly stick to the ratio, which is roughly 7:6 for 48k output (really 7049:6048). So for the most part every 7th input sample is "skipped"

  • roglohrogloh Posts: 5,642
    edited 2024-09-18 23:28

    @Wuerfel_21 said:

    @rogloh said:
    Well 1000ppm is less than 1 in 1000 pixels which less than one scan line if you send 1075 pixels. It'll be important to not underflow on any single scanline then. I do see the buffer vary from 17 to 20.

    EDIT: Also that rounding of the clock you do worries me.
    SAMPLE_OUT_PERIOD = (VIDEO_CLKFREQ+24000)/48000

    Actually on second thoughs it's probably only off by around 1 part in 7000 or so, so it should be okay if the tolerance is 1000ppm.

    It's rounded to an integer period, which is useful/needed for constant N/CTS values. Plain VIDEO_CLKFREQ/48000 is far more off (though you can try that if you want)

    Yeah what I was thinking is that the TV & AVR can probably tolerate the occasional excess samples here and there (and just drops them if the buffer is full) but can't deal with a case when samples are missing due to underflow. So losing samples by playing the buffer slightly faster at the sink than the arrival rate using the locally regenerated clock eventually leads to underflows causing it to mute and rebuild the buffer hoping things will stabilise afterwards. If you are rounding up by adding 24000 before dividing it might increase the SAMPLE_OUT_PERIOD by one pixel, according to your code:

    CON ' Clocky business
    
        MVS_CLOCK = 24_000_000
        AES_CLOCK = 24_167_829
        MASTER_CLK = AES_CLOCK
        CLK_MULTIPLIER = 14
        VIDEO_CLKFREQ = MASTER_CLK*CLK_MULTIPLIER
    
        SAMPLE_OUT_PERIOD = (VIDEO_CLKFREQ+24000)/48000
    

    Yep it does:
    (338349606+24000)/48000 = 7049
    33834960/48000 = 7048

    I'm going to try removing the rounding to see if it helps.

    Also the P2 PLL is not going to be able to get so close to this particular VIDEO_CLKFREQ frequency. Using the MVS clock of 24MHz and multiplying by 14 is likely to be closer (336MHz an exact integer) and be easier to achieve with 20MHz P2 XTALs although it will affect your refresh rate slightly and some pitches altered perhaps depending on the resampling you do. I'm going to try that too and report the results here below. The N/CTS would fit nicely with 336MHz as it is also an exact integer multiple of 48000 (specifically 7000).

    @Wuerfel_21 said:
    One silly thing to try would be to change the resampler to do 44.1 instead of 48. To do that, you'd only need to change SAMPLE_OUT_PERIOD and the channel status.
    Resampler seems to correctly stick to the ratio, which is roughly 7:6 for 48k output (really 7049:6048). So for the most part every 7th input sample is "skipped"

    Yeah I may try that. The RasPi sends 44.1kHz audio and also sets the SPDIF channel status to 48kHz and it works although it might be slightly noisy too (I only had a short test speaker sample to listen to and I was more interested in capturing the HDMI than listening to the quality). At some point I'd like to get it to output real 48kHz source material somehow. I'll have to look for something to install like VLC on that device which I can use for playback of other material if it is available on Ubuntu ARM64, or figure out what else I can use.

    RESULT1 - test of removing rounding up VIDEO_CLKFREQ : No improvement - still cuts out audio in bursts.

    RESULT2 - using MVS_CLOCK (and still no rounding too) : Even more frequent cut outs. That one is a strange result. I really though it might help. Perhaps there are some other calculations in the resampler that are thrown off badly by this change.

  • Wuerfel_21Wuerfel_21 Posts: 4,926
    edited 2024-09-18 23:24

    @rogloh said:
    Yeah what I was thinking is that the TV & AVR can probably tolerate the occasional excess samples here and there (and just drops them if the buffer is full) but can't deal with a case when samples are missing due to underflow. So losing samples by playing the buffer slightly faster at the sink than the arrival rate using the locally regenerated clock eventually leads to underflows causing it to mute and rebuild the buffer hoping things will stabilise afterwards.

    But that's what the regen packet is for :) The clock sync is supposed to be exact with no slippage at all (for Hi-Fi audio, dropped or repeated samples would be unacceptable).

    Also the P2 PLL is not going to be able to get so close to this particular VIDEO_CLKFREQ frequency. Using the MVS clock of 24MHz and multiplying by 14 is likely to be closer (336MHz an exact integer) and be easier to achieve with 20MHz P2 XTALs although it will affect your refresh rate slightly and some pitches altered perhaps depending on the resampling you do. I'm going to try that too and report the results here below. The N/CTS would fit nicely with 336MHz as it is also an exact integer multiple of 48000 (specifically 7000).

    I am somewhat convinced part of why they use a faster crystal on the AES is specifically to edge the video frequencies closer to NTSC standard. You could try using the MVS clocks I guess. Everything's done under the assumption that the PLL is running exactly, so it shouldn't really matter that it doesn't.

    Yeah I may try that. The RasPi sends 44.1kHz audio and also sets the SPDIF channel status to 48kHz and it works although it might be slightly noisy too (I only had a short test speaker sample to listen too and I was more interested in capturing the HDMI than listening to the quality). At some point I'd like to get it to output real 48kHz source material somehow. I'll have to look for something to install like VLC on that device which I can use for playback of other material if it is available on Ubuntu ARM64, or figure out what else I can use.

    You'd need to actually go to some accursed settings panel to set the mixer rate to 48k, it ought not to matter what the source format is. I think, anyways. Or maybe GNOME devs decided that no one actually wants to change their mixer rate and it doesn't exist...

Sign In or Register to comment.