PCM audio streaming error
-
- Posts: 503
- Joined: Sat Jul 11, 2020 3:30 pm
PCM audio streaming error
I've been trying to get another video demo put together, but the audio (long a solved problem) has been a stumbling block this time around. I don't know whether this is due to an error in the emulator or if it's actually a problem with VERA. I think what's happening is that the PCM goes silent while new data is being written to the FIFO buffer. This wasn't the case in r41 or earlier versions.
Here's what I'm doing. I've got my audio at 16 bit 12970 Hz (audio rate of $22). I have the audio chopped up into 1/10 of a second chunks (2594 bytes) interlaced in a big file with the video image data (5kb per frame, also at 10 frames per second). The file is read sequentially using MACPTR. First 2594 bytes of audio data is stored in VRAM at $10000, then 5kb of video data is stored at $01000 or $03800, whichever isn't currently being displayed. The audio data gets pushed from VRAM to the PCM audio data in a very quick subroutine.
To start, the first clip of audio is loaded, and the first frame of video. Then with the audio rate set at 0, the first audio clip is pushed to the PCM FIFO, and the second audio clip and second frame of video loaded. Then I turn on the screen showing the first frame of video, set the audio rate to $22, and turn on interrupts. My Interrupt routine scans the ISR looking for bit 3 (AFLOW) to be one. If not, then it just goes to the default IRQ, but if it's a 1 the next audio clip is pushed to the FIFO, and a flag is set telling the main program to switch the video frame and load the next audio clip and video frame before going to the default IRQ.
All of that loading should take place in less than 1/10 of a second, I estimate about 75/1000 of a second. This leaves plenty of time remaining in the audio clip, so the audio should be seamless. Instead I'm getting "chatter" as the PCM goes silent between clips, and doesn't seem to play 1/10 of a second for each clip anyway. I took some recordings of what's happening in Audacity and saved some images: Anyhow, this is new behavior for the PCM. Is it an emulator error, or does the PCM audio go silent when streaming on the real hardware too? Because you can't push a whole lot of audio in just 4 kb between silences.
Here's what I'm doing. I've got my audio at 16 bit 12970 Hz (audio rate of $22). I have the audio chopped up into 1/10 of a second chunks (2594 bytes) interlaced in a big file with the video image data (5kb per frame, also at 10 frames per second). The file is read sequentially using MACPTR. First 2594 bytes of audio data is stored in VRAM at $10000, then 5kb of video data is stored at $01000 or $03800, whichever isn't currently being displayed. The audio data gets pushed from VRAM to the PCM audio data in a very quick subroutine.
To start, the first clip of audio is loaded, and the first frame of video. Then with the audio rate set at 0, the first audio clip is pushed to the PCM FIFO, and the second audio clip and second frame of video loaded. Then I turn on the screen showing the first frame of video, set the audio rate to $22, and turn on interrupts. My Interrupt routine scans the ISR looking for bit 3 (AFLOW) to be one. If not, then it just goes to the default IRQ, but if it's a 1 the next audio clip is pushed to the FIFO, and a flag is set telling the main program to switch the video frame and load the next audio clip and video frame before going to the default IRQ.
All of that loading should take place in less than 1/10 of a second, I estimate about 75/1000 of a second. This leaves plenty of time remaining in the audio clip, so the audio should be seamless. Instead I'm getting "chatter" as the PCM goes silent between clips, and doesn't seem to play 1/10 of a second for each clip anyway. I took some recordings of what's happening in Audacity and saved some images: Anyhow, this is new behavior for the PCM. Is it an emulator error, or does the PCM audio go silent when streaming on the real hardware too? Because you can't push a whole lot of audio in just 4 kb between silences.
Re: PCM audio streaming error
Audio is and always was very choppy in the emulator for me on several machines, even high-end ones. I don't think it ever was actually usable (in any accurate sense)
Re: PCM audio streaming error
Can you do something really silly and poke the PSG registers with some data to make one of the channels play a continuous tone, and then try running the program again while that's happening? I'd like to know if the entire emulator's audio is stuttering or if it's just the PCM portion of it.
The reason is because, I saw there was a big change in how the emulator simulates the audio and keeps it in sync from r41 to r42, but I haven't been able to spot any obvious issues that would cause stuttering this bad on just the PCM, so I'm wondering if the entire emulator is slowing down instead.
Otherwise, I spotted two minor things that I don't think are causing your issue but still can affect emulation accuracy slightly:
1) In main.c, in emulator_loop, the web version of the emulator can delay IRQs by an extra 6502 instruction if they happen to occur at the same time the emulator wants to repaint the screen (code that forwards IRQs to the 6502 emulator is just after a conditional statement that will return 0).
2) In audio.c, audio_step() specifically waits until it's time for the FM chip to output a sample before it even looks at the VERA's PSG and PCM subsystems. Sound-wise, this is fine, but simulation-wise, I'd suspect that this can cause the VERA's AFLOW interrupt to sometimes be delayed 143 CPU cycles, depending on how the VERA and FM clocks line up. For reference, the PCM's maximum playback speed will output a new sample every 163.84 CPU cycles.
The reason is because, I saw there was a big change in how the emulator simulates the audio and keeps it in sync from r41 to r42, but I haven't been able to spot any obvious issues that would cause stuttering this bad on just the PCM, so I'm wondering if the entire emulator is slowing down instead.
Otherwise, I spotted two minor things that I don't think are causing your issue but still can affect emulation accuracy slightly:
1) In main.c, in emulator_loop, the web version of the emulator can delay IRQs by an extra 6502 instruction if they happen to occur at the same time the emulator wants to repaint the screen (code that forwards IRQs to the 6502 emulator is just after a conditional statement that will return 0).
2) In audio.c, audio_step() specifically waits until it's time for the FM chip to output a sample before it even looks at the VERA's PSG and PCM subsystems. Sound-wise, this is fine, but simulation-wise, I'd suspect that this can cause the VERA's AFLOW interrupt to sometimes be delayed 143 CPU cycles, depending on how the VERA and FM clocks line up. For reference, the PCM's maximum playback speed will output a new sample every 163.84 CPU cycles.
-
- Posts: 503
- Joined: Sat Jul 11, 2020 3:30 pm
Re: PCM audio streaming error
I guess the best way to determine if this is an emulator error is to upload what I've got. If someone with the actual hardware tries this and it works, then it's an emulator error. If it doesn't work on the actual hardware either, then streaming into PCM audio might not work at all.
To try this, download and unzip the files into the same folder as the r42 emulator, or on the actual hardware into the root folder of the SD card. There's INDY.PRG and an INDY folder containing INDY.DAT, PAL1.DAT, PALD.DAT, and TMAP.DAT. To run it, just
LOAD"INDY.PRG",8,1
RUN
After the video is over, press a key to return to BASIC.
To try this, download and unzip the files into the same folder as the r42 emulator, or on the actual hardware into the root folder of the SD card. There's INDY.PRG and an INDY folder containing INDY.DAT, PAL1.DAT, PALD.DAT, and TMAP.DAT. To run it, just
LOAD"INDY.PRG",8,1
RUN
After the video is over, press a key to return to BASIC.
- Attachments
-
- INDY.zip
- (7.5 MiB) Downloaded 438 times
Re: PCM audio streaming error
VPOKE 1,$F9C0,$9D VPOKE 1,$F9C1,$04 VPOKE 1,$F9C2,$F0This makes a continuous tone. When I did this, then ran your program, it was all of the audio stuttering, not just the PCM. Therefore, I'm pretty sure the entire emulator is lagging while running your program, but I'm not sure why.
Re: PCM audio streaming error
That tone is stuttering for me right from the start, no need to run anything.
- desertfish
- Posts: 1098
- Joined: Tue Aug 25, 2020 8:27 pm
- Location: Netherlands
Re: PCM audio streaming error
The INDY.PRG stutters on the official emulator, but runs without any stutters on box16 on my system (Linux, Ryzen 5600X)
So choice of emulator also matters
So choice of emulator also matters
-
- Posts: 503
- Joined: Sat Jul 11, 2020 3:30 pm
Re: PCM audio streaming error
When I try the vpokes by themselves on the emulator I get a continuous tone. If I run Indy after that, I get both the tone and PCM chattering, making the tone sound like Morse code.
Hey @wavicle, care to try this out on the real hardware?
Hey @wavicle, care to try this out on the real hardware?
Re: PCM audio streaming error
I tried Box16 as well, it made no difference. I then went and changed
to
in audio.h, and got clean sound output as a result.
Code: Select all
# define SAMPLES_PER_BUFFER (256)
Code: Select all
# define SAMPLES_PER_BUFFER (1024)
-
- Posts: 503
- Joined: Sat Jul 11, 2020 3:30 pm
Re: PCM audio streaming error
OK then, based on the results that desertfish and grml got, this is an emulator issue. I'd still like someone to try it out on the actual hardware though.