RayeR

CZ, 24.01.2025, 19:56 |
SBEMU dirty hotfix for playback speed on SB Audigy (Live) (Announce) |
I tried to localize the commit where it breaks.
The last OK: https://github.com/crazii/SBEMU/releases/tag/UserBuild_2024.02.05_06-40
The 1st broken: https://github.com/crazii/SBEMU/releases/tag/UserBuild_2024.02.06_02-04
I compared source files and only 2 has changed: main.c and au_base.c.
I suspect the code in au_base.c function mixer_speed_lq() that has something to do with interpolation of emulated fs to real sound device fs. So I just tried to reverse 2 lines change and yes, it plays correctly on my SBA (only Doom tested yet). Then I tried the same for current 1.0.0 beta 5 sources and also works for me. But I don't know how this code works and if it didn't break somewhere else and on other sound devices. So it may help if someone else would try it on his HW against official beta 5 if there's no sideeffect and for those with SBA/SBL if fixed the speed.
diff au_base.ok au_base.bad
1020c1020
< const unsigned int inend=(sourcesample/channels) << 12;
---
> const unsigned int inend=(sourcesample/channels - 1) << 12; //for n samples,
interpolation n-1 steps
1047c1047
< intmp2=ipi < total-ch ? intmp1+ch : intmp1;
---
> intmp2=intmp1+ch;
Compiled binary here: http://rayer.g6.cz/download/download.htm#SBEMU_SBA_HOTFIX
p.s. Crazii seems to be currently busy with other stuff so no response on my github issue for a half of year. I'm also busy so I'm happy with this dirty patch and not going to dig deeper inside... --- DOS gives me freedom to unlimited HW access. |
Japheth

Germany (South), 25.01.2025, 02:00
@ RayeR
|
SBEMU dirty hotfix for playback speed on SB Audigy (Live) |
> I suspect the code in au_base.c function mixer_speed_lq() that has
> something to do with interpolation of emulated fs to real sound device fs.
Correct. AFAIR it's the 2. of 3 conversions. The HW sound device is feeded with 16-bit, stereo, 22050 or 44100 Hz:
1. convert bitness (8 to 16-bit)
2. convert frequency
3. convert channel (mono to stereo)
In VSBHDA, it's in sndisr.c, func cv_rate():
static unsigned int cv_rate( PCM_CV_TYPE_S *pcmsrc, unsigned int samplenum, unsigned int channels, unsigned int srcrate, unsigned int dstrate)
{
/* todo: what algorithm for instep is best? */
//const unsigned int instep = ((srcrate / dstrate) << 12) | (((4096 * (srcrate % dstrate) - 1) / (dstrate - 1)) & 0xFFF);
const unsigned int instep = ((srcrate / dstrate) << 12) | (((4096 * (srcrate % dstrate) + dstrate - 1 ) / dstrate) & 0xFFF);
const unsigned int inend = (samplenum / channels) << 12;
PCM_CV_TYPE_S *pcmdst;
unsigned long ipi;
unsigned int inpos = 0;//(srcrate < dstrate) ? instep/2 : 0;
int total;
#if MALLOCSTATIC
static int maxsample = 0;
static PCM_CV_TYPE_S* buff = NULL;
#else
PCM_CV_TYPE_S* buff;
#endif
if(!samplenum)
return 0;
#if MALLOCSTATIC
if ( samplenum > maxsample ) {
if ( buff )
free( buff );
buff = (PCM_CV_TYPE_S*)malloc(samplenum * sizeof(PCM_CV_TYPE_S));
maxsample = samplenum;
}
#else
buff = (PCM_CV_TYPE_S*)malloc(samplenum * sizeof(PCM_CV_TYPE_S));
#endif
memcpy( buff, pcmsrc, samplenum * sizeof(PCM_CV_TYPE_S) );
pcmdst = pcmsrc;
total = samplenum / channels;
do{
int m1,m2;
unsigned int ipi,ch;
PCM_CV_TYPE_S *intmp1,*intmp2;
ipi = inpos >> 12;
m2 = inpos & 0xFFF;
m1 = 4096 - m2;
ch = channels;
ipi *= ch;
intmp1 = buff + ipi;
intmp2 = ipi < total - ch ? intmp1 + ch : intmp1;
do{
*pcmdst++= ((*intmp1++) * m1 + (*intmp2++) * m2) / 4096;// >> 12; //don't use shift, signed right shift impl defined, maybe logical shift
}while (--ch);
inpos += instep;
}while( inpos < inend );
//dbgprintf(("cv_rate(src/dst rates=%u/%u chn=%u smpl=%u step=%x end=%x)=%u\n", srcrate, dstrate, channels, samplenum, instep, inend, pcmdst - pcmsrc ));
#if !MALLOCSTATIC
free(buff);
#endif
return pcmdst - pcmsrc;
}
It has been optimized to reduce malloc/free calls. And I guess interpolation between the last sample and the first one of the next block is missing. --- MS-DOS forever! |
RayeR

CZ, 27.01.2025, 22:10
@ RayeR
|
SBEMU dirty hotfix for playback speed on SB Audigy (Live) |
BTW another fooook appeared: VSBHDASF
https://github.com/Cacodemon345/VSBHDASF
With SW MIDI emulation via soundfont. I wish a one day all this forks reunite to one powerful version with all the nice features instead messing with multiple forks and incompatible hdpmi32i... --- DOS gives me freedom to unlimited HW access. |
Zyzzle
28.01.2025, 02:48
@ RayeR
|
SBEMU dirty hotfix for playback speed on SB Audigy (Live) |
> BTW another fooook appeared: VSBHDASF
> https://github.com/Cacodemon345/VSBHDASF
>
> With SW MIDI emulation via soundfont. I wish a one day all this forks
> reunite to one powerful version with all the nice features instead messing
> with multiple forks and incompatible hdpmi32i...
My wish as well. One program with one version of hdmpi32i.
As an alternate, seperate optimized binaries for each emulated card (ie, one for HDA, one for AC97, one for SB Audigy, one for ES1371/73, etc) to keep the binary fast and small. Otherwise bloat sets in with all of this combined into one do-it-all binary compilation. |
RayeR

CZ, 28.01.2025, 12:27
@ Zyzzle
|
SBEMU dirty hotfix for playback speed on SB Audigy (Live) |
> As an alternate, seperate optimized binaries for each emulated card (ie,
> one for HDA, one for AC97, one for SB Audigy, one for ES1371/73, etc) to
> keep the binary fast and small.
I think it's not serious problem as the real soundcard drivers code is (I think so) loaded somewhere in XMS memory and only some minimal trapping code needs to be kept in low memory. I don't care if it takes 1MB or 10MB of my 4GB XMS :) --- DOS gives me freedom to unlimited HW access. |
Zyzzle
28.01.2025, 15:20
@ RayeR
|
SBEMU dirty hotfix for playback speed on SB Audigy (Live) |
> > As an alternate, seperate optimized binaries for each emulated card (ie,
> > one for HDA, one for AC97, one for SB Audigy, one for ES1371/73, etc) to
> > keep the binary fast and small.
>
> I think it's not serious problem as the real soundcard drivers code is (I
> think so) loaded somewhere in XMS memory and only some minimal trapping
> code needs to be kept in low memory. I don't care if it takes 1MB or 10MB
> of my 4GB XMS :)
Good point, as this is for "modern" CPUs with tons of XMS after all!
I was thinking low memory might be conserved a bit by separate binaries. (VSBHDA takes up 5-6 kb less of low memory than SBEMU for me, and earlier versions of SBEMU take less low memory than release 1.5 for example). |