From cc60e080e0b1f4833583891cf760f92b6ffdcd5b Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 27 Mar 2006 19:41:55 +0000 Subject: [PATCH] update some comments. Update mixer to be more oldstyle Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2559 --- src/dosbox.cpp | 6 ++- src/hardware/mixer.cpp | 102 +++++++++++++++++++++++++++++++---------- 2 files changed, 82 insertions(+), 26 deletions(-) diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 4fbf961c..bb60b66e 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dosbox.cpp,v 1.97 2006-03-13 20:00:41 qbix79 Exp $ */ +/* $Id: dosbox.cpp,v 1.98 2006-03-27 19:41:55 qbix79 Exp $ */ #include #include @@ -115,7 +115,7 @@ static Bit32u ticksLast; static Bit32u ticksAdded; static Bit32s ticksDone; static Bit32u ticksScheduled; -static bool ticksLocked; +bool ticksLocked; static Bitu Normal_Loop(void) { Bits ret; @@ -348,6 +348,7 @@ void DOSBOX_Init(void) { "mixer -- Allow the soundblaster mixer to modify the dosbox mixer.\n" "oplmode -- Type of OPL emulation: auto,cms,opl2,dualopl2,opl3.\n" " On auto the mode is determined by sblaster type.\n" + " All OPL modes are 'Adlib', except for CMS.\n" "oplrate -- Sample rate of OPL music emulation.\n" ); @@ -417,6 +418,7 @@ void DOSBOX_Init(void) { " stopbits, parity (all optional).\n" " for directserial: realport (required).\n" " for modem: listenport (optional).\n" + " Example: serial1=modem listenport:5000\n" ); /* All the DOS Related stuff, which will eventually start up in the shell */ diff --git a/src/hardware/mixer.cpp b/src/hardware/mixer.cpp index 6c286a81..353af4c3 100644 --- a/src/hardware/mixer.cpp +++ b/src/hardware/mixer.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: mixer.cpp,v 1.38 2006-02-11 09:37:16 harekiet Exp $ */ +/* $Id: mixer.cpp,v 1.39 2006-03-27 19:41:55 qbix79 Exp $ */ /* Remove the sdl code from here and have it handeld in the sdlmain. @@ -271,6 +271,13 @@ void MixerChannel::FillUp(void) { SDL_UnlockAudio(); } +extern bool ticksLocked; +static inline bool Mixer_irq_important(void) { + /* In some states correct timing of the irqs is more important then + * non stuttering audo */ + return (ticksLocked || (CaptureState & (CAPTURE_WAVE|CAPTURE_VIDEO))); +} + /* Mix a certain amount of new samples */ static void MIXER_MixData(Bitu needed) { MixerChannel * chan=mixer.channels; @@ -293,7 +300,10 @@ static void MIXER_MixData(Bitu needed) { } CAPTURE_AddWave( mixer.freq, added, (Bit16s*)convert ); } - mixer.done=needed; + //Reset the the tick_add for constant speed + if( Mixer_irq_important() ) + mixer.tick_add = ((mixer.freq) << MIXER_SHIFT)/1000; + mixer.done = needed; } static void MIXER_Mix(void) { @@ -334,55 +344,99 @@ static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) { /* Enough room in the buffer ? */ if (mixer.done < need) { // LOG_MSG("Full underrun need %d, have %d, min %d", need, mixer.done, mixer.min_needed); + if((need - mixer.done) > (need >>7) ) //Max 1 procent stretch. + return; reduce = mixer.done; index_add = (reduce << MIXER_SHIFT) / need; + mixer.tick_add = ((mixer.freq+mixer.min_needed) << MIXER_SHIFT)/1000; } else if (mixer.done < mixer.max_needed) { Bitu left = mixer.done - need; if (left < mixer.min_needed) { - left = (mixer.min_needed - left); - left = 1 + (2*left) / mixer.min_needed; -// left = 1; -// left = 1 + (left / 128); + if( !Mixer_irq_important() ) { + Bitu needed = mixer.needed - need; + Bitu diff = (mixer.min_needed>needed?mixer.min_needed:needed) - left; + mixer.tick_add = ((mixer.freq+(diff*3)) << MIXER_SHIFT)/1000; + left = 0; //No stretching as we compensate with the tick_add value + } else { + left = (mixer.min_needed - left); + left = 1 + (2*left) / mixer.min_needed; //left=1,2,3 + } // LOG_MSG("needed underrun need %d, have %d, min %d, left %d", need, mixer.done, mixer.min_needed, left); reduce = need - left; index_add = (reduce << MIXER_SHIFT) / need; } else { reduce = need; index_add = (1 << MIXER_SHIFT); +// LOG_MSG("regular run need %d, have %d, min %d, left %d", need, mixer.done, mixer.min_needed, left); + + /* Mixer tick value being updated: + * 3 cases: + * 1) A lot too high. >division by 5. but maxed by 2* min to prevent too fast drops. + * 2) A little too high > division by 8 + * 3) A little to nothing above the min_needed buffer > go to default value + */ + Bitu diff = left - mixer.min_needed; + if(diff > (mixer.min_needed<<1)) diff = mixer.min_needed<<1; + if(diff > (mixer.min_needed>>1)) + mixer.tick_add = ((mixer.freq-(diff/5)) << MIXER_SHIFT)/1000; + else if (diff > (mixer.min_needed>>4)) + mixer.tick_add = ((mixer.freq-(diff>>3)) << MIXER_SHIFT)/1000; + else + mixer.tick_add = (mixer.freq<< MIXER_SHIFT)/1000; } } else { /* There is way too much data in the buffer */ +// LOG_MSG("overflow run need %d, have %d, min %d", need, mixer.done, mixer.min_needed); if (mixer.done > MIXER_BUFSIZE) - index_add = MIXER_BUFSIZE - mixer.min_needed; + index_add = MIXER_BUFSIZE - 2*mixer.min_needed; else - index_add = mixer.done - mixer.min_needed; + index_add = mixer.done - 2*mixer.min_needed; index_add = (index_add << MIXER_SHIFT) / need; - reduce = mixer.done - mixer.min_needed; + reduce = mixer.done - 2* mixer.min_needed; + mixer.tick_add = ((mixer.freq-(mixer.min_needed/5)) << MIXER_SHIFT)/1000; } /* Reduce done count in all channels */ for (MixerChannel * chan=mixer.channels;chan;chan=chan->next) { if (chan->done>need) chan->done-=reduce; else chan->done=0; } + + // Reset mixer.tick_add when irqs are important + if( Mixer_irq_important() ) + mixer.tick_add=(mixer.freq<< MIXER_SHIFT)/1000; + mixer.done -= reduce; mixer.needed -= reduce; pos = mixer.pos; mixer.pos = (mixer.pos + reduce) & MIXER_BUFMASK; index = 0; - while (need--) { - Bitu i = (pos + (index >> MIXER_SHIFT )) & MIXER_BUFMASK; - index += index_add; - sample=mixer.work[i][0]>>MIXER_VOLSHIFT; - *output++=MIXER_CLIP(sample); - sample=mixer.work[i][1]>>MIXER_VOLSHIFT; - *output++=MIXER_CLIP(sample); - } - /* Clean the used buffer */ - while (reduce--) { - pos &= MIXER_BUFMASK; - mixer.work[pos][0]=0; - mixer.work[pos][1]=0; - pos++; + if(need != reduce) { + while (need--) { + Bitu i = (pos + (index >> MIXER_SHIFT )) & MIXER_BUFMASK; + index += index_add; + sample=mixer.work[i][0]>>MIXER_VOLSHIFT; + *output++=MIXER_CLIP(sample); + sample=mixer.work[i][1]>>MIXER_VOLSHIFT; + *output++=MIXER_CLIP(sample); + } + /* Clean the used buffer */ + while (reduce--) { + pos &= MIXER_BUFMASK; + mixer.work[pos][0]=0; + mixer.work[pos][1]=0; + pos++; + } + } else { + while (reduce--) { + pos &= MIXER_BUFMASK; + sample=mixer.work[pos][0]>>MIXER_VOLSHIFT; + *output++=MIXER_CLIP(sample); + sample=mixer.work[pos][1]>>MIXER_VOLSHIFT; + *output++=MIXER_CLIP(sample); + mixer.work[pos][0]=0; + mixer.work[pos][1]=0; + pos++; + } } } @@ -531,7 +585,7 @@ void MIXER_Init(Section* sec) { mixer.min_needed=section->Get_int("prebuffer"); if (mixer.min_needed>100) mixer.min_needed=100; mixer.min_needed=(mixer.freq*mixer.min_needed)/1000; - mixer.max_needed=mixer.blocksize * 2 + mixer.min_needed; + mixer.max_needed=mixer.blocksize * 2 + 2*mixer.min_needed; mixer.needed=mixer.min_needed+1; PROGRAMS_MakeFile("MIXER.COM",MIXER_ProgramStart); }