[WIP] Improving SB Mixer emulation

Discussion of development and patch submission.
Post Reply
JosepMa
Posts: 202
Joined: Tue 20 Jun, 2017 6:25 pm

[WIP] Improving SB Mixer emulation

Post by JosepMa »

Hello.
I started working on improving the Soundblaster Mixer emulation.

The current implementation works adequatedly, but my changes try to emulate each of the different chips on the different models, and implement all of its features according to the SoundBlasterProgramming.pdf .

As such, I've implemented the ct1335, ct1345 and ct1745 mixer chips and stored all the values that can be set.
Currently I have added support for the output gain and audio output selectors on sb16/awe32, added the SB 2.0 CD mixer and prepared all mixers for input signals ( ADC could be possible, but I am mostly interested on voice/MIDI recording, so that the spectogram
on the Creative Windows mixer can show data).

I implemented the register defaults that are documented on the PDF, which means that the volume is not at max by default.
Not sure if we should implement a small UI mixer for people that don't have the drivers installed. (at least, to be able to set master and voice to max).

Also, I think we should extract the constants used for volume compensations between the different sound sources and see if they are all correct. For example, we have a division by 3 on the voice output. the EMU8K was also being right shifted one step too much (division by 2) but i removed that on my emu8k patch.

I also wonder if we should obey the PCspeaker volume on SB16/AWE32. It was only useful when the motherboard output was connected to the soundcard pins, and that was rare, but since we don't have a physical pc speaker, it could be interpreted as being output from the soundcard. This, of course, has a drawback, because the default volume is muted. (actually, -18dB)



Next step, modify the DSP implementation to get voice and midi input sources.


Also, one question, is the bass/treble really emulating how a soundblaster sounds, or I am free to improve it and not produce this strange effect where boosting reduces the volume and reducing increases the volume? (even causing clipping!) I don't remember that it did this, but It's been so long...
Attachments
sound_sb.mixerchips.patch
(59.6 KiB) Downloaded 351 times
Battler
Posts: 793
Joined: Sun 06 Jul, 2014 7:05 pm

Re: [WIP] Improving SB Mixer emulation

Post by Battler »

JosepMa wrote:Next step, modify the DSP implementation to get voice and midi input sources.
Please look at bit's patch for the DSP MIDI stuff so that you two don't end up with two mutually incompatible patches.
JosepMa
Posts: 202
Joined: Tue 20 Jun, 2017 6:25 pm

Re: [WIP] Improving SB Mixer emulation

Post by JosepMa »

Hello.

I have a working recording code, which is capable of recording audio from midi (emu and opl3) with soundblaster 16 and awe32 (apparently, the others only record from ADC).
Different samplerates can be used, but I need to add a proper resampler or filter, since recording the EMU8K at 11Khz gives notable aliasing.

Said that, I believe there is a problem with 16bit DMA. (Or that's what I assume).
I've imlemented writing to file from the streams in several places of sound_sb and sound_sb_dsp and can get clean audio from it.
But when I record with Creative Wavestudio inside pcem, I get different glitches.

Initially, I was getting noise bursts (i.e. small fragments from other parts of the buffer). Then I increased the sb16_length by two (sound_sb_dsp.c:1041), and no longer get those glitches. But then, I experimented trying to send a triangle waveform and i get some jumps as it can be seen on the following graphics, so I still think there is some problem. (what is really weird is that the value cannot be a value sent by my code)

Could any of you that know better this part of the code determine what's going wrong?

start of recording
start of recording
recording-start.png (8.25 KiB) Viewed 8984 times
each 2756 samples there's a jump (i guess that's the size of the requested DMA buffer by wavestudio)
each 2756 samples there's a jump (i guess that's the size of the requested DMA buffer by wavestudio)
recording-sample-another.png (2.88 KiB) Viewed 8984 times
Attachments
sb-recording.patch
patch
(78.8 KiB) Downloaded 364 times
JosepMa
Posts: 202
Joined: Tue 20 Jun, 2017 6:25 pm

Re: [WIP] Improving SB Mixer emulation

Post by JosepMa »

Update: I detected one of the problems. The bug that required one more sample is in dma.c line 666. There's an extra "+1".

I still have the random extra sample each 2756 samples.

Update 2: The extra samples is present also when recording in 8bits. I wonder if maybe it's a bug of the driver or something...

What makes this bug strange is that the value is always the value inbetween two consecutive values (the dma end position isn't always at the same place, so the sample value isn't always the same, but it still happens to be the position inbetween two consecutive samples).
Could it be that it thinks that one sample is going to be lost (initialization time or whatever), so when recording, interpolates from the last recorded one of the current block, to the first one of next block?


Update3: Seems that the dma.c bug is something that was supposed to be changed on revision 55, but by mistake it was not fixed, and revision 768 did not correct.
What I also see is that dma16 write is also used by the esdi_hdd, so I wonder if that code needs to be revised once dma.c is fixed.
Also, I don't know if the change in revision 152 applies to dma_channel_write or is only relevent for dma_channel_read
User avatar
SarahWalker
Site Admin
Posts: 2054
Joined: Thu 24 Apr, 2014 4:18 pm

Re: [WIP] Improving SB Mixer emulation

Post by SarahWalker »

Fixed the off-by-one DMA error in rev 861.

It looks like the SB16 drivers are starting the DSP recording before programming the DMA controller. This can be catered for with a couple of small modifications :

Code: Select all

int sb_16_write_dma(sb_dsp_t *dsp, uint16_t val)
{
        int ret = dma_channel_write(5, val);
#ifdef SB_DSP_RECORD_DEBUG        
        if (!soundf) soundf=fopen("sound_dsp.pcm","wb");
        fwrite(&val,2,1,soundf);
#endif
        return (ret == DMA_NODATA);
}

Code: Select all

                switch (dsp->sb_16_format)
                {
                        case 0x00: /*Unsigned mono. As the manual says, only the left channel is recorded*/
                        case 0x10: /*Signed mono. As the manual says, only the left channel is recorded*/
                        if (sb_16_write_dma(dsp, counttest))
                                return;
                        counttest+=0x1000;
                        counttest&=0xFFFF;
                        dsp->sb_16_length--;
                        break;
                        case 0x20: /*Unsigned stereo*/
                        case 0x30: /*Signed stereo*/
                        if (sb_16_write_dma(dsp, counttest))
                                return;
                        sb_16_write_dma(dsp, counttest);
                        counttest+=0x1000;
                        counttest&=0xFFFF;
                        dsp->sb_16_length -= 2;
                        break;

//                        default:
//                                fatal("Unrecognised SB 16-bit input format %02X\n",sb_16_format);
                }
                
                if (dsp->sb_16_length < 0)
                {
//                        pclog("16iDMA over %i\n",sb16_autoinit);
                        if (dsp->sb_16_autoinit) dsp->sb_16_length = dsp->sb_16_autolen;
                        else                     dsp->sb_16_enable = dsp->sb_enable_i = 0;
                        sb_irq(dsp, 0);
                }
Haven't yet found a logical explanation for the weird additional inbetween sample - maybe it's being added by the drivers or Wavestudio itself? One possibility is it's actually a hardware workaround, either for the SB16 or leftover from code for an earlier card - it's the sort of thing you might add if you were expecting the hardware to miss a sample.
Battler
Posts: 793
Joined: Sun 06 Jul, 2014 7:05 pm

Re: [WIP] Improving SB Mixer emulation

Post by Battler »

The extra sample is probably due to an error with PCem's timers, as it sounds a lot like what I'm seeing when measuring the emulated floppy drive's RPM with FLOPRPM - with the code done right, it alternates between the correct RPM and slightly slower RPM which implies that sometimes, extra timer pulses are being executed. It wouldn't surprise me if the same problem is causing both these issues as the symptoms seem the exact same to me.
User avatar
SarahWalker
Site Admin
Posts: 2054
Joined: Thu 24 Apr, 2014 4:18 pm

Re: [WIP] Improving SB Mixer emulation

Post by SarahWalker »

Unlikely - we can log exactly what's written out through DMA, and the extra sample isn't there - and isn't one of the values ever written out in any case. It looks to be invented by software.
Battler
Posts: 793
Joined: Sun 06 Jul, 2014 7:05 pm

Re: [WIP] Improving SB Mixer emulation

Post by Battler »

If the driver measures the time, and then determines the amount of memory to read based on it, and the measured time is off by one, I can see it reading more memory than needed. This would also explain why the extra sample has seemingly random contents, as it would simply be what follows the DMA-written samples in memory.
User avatar
SarahWalker
Site Admin
Posts: 2054
Joined: Thu 24 Apr, 2014 4:18 pm

Re: [WIP] Improving SB Mixer emulation

Post by SarahWalker »

Only a drunken idiot would write a sound driver like that. The SB fires an interrupt when a buffer transfer is complete, there's no need to know anything else timing related.

The extra byte does not have random contents - it's an interpolation of the previous and next samples. It's exactly what you'd want to add if you were expecting the hardware to miss a sample. Hence my suspicion that it was a hardware workaround.
Post Reply