New mixer code with interpolation.
New prebuffering scheme. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1911
This commit is contained in:
parent
a10d8f9bf0
commit
b77308510d
1 changed files with 210 additions and 151 deletions
|
@ -9,7 +9,7 @@
|
|||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "SDL.h"
|
||||
#include "mem.h"
|
||||
#include "pic.h"
|
||||
#include "dosbox.h"
|
||||
#include "mixer.h"
|
||||
#include "timer.h"
|
||||
|
@ -38,34 +39,14 @@
|
|||
#include "hardware.h"
|
||||
#include "programs.h"
|
||||
|
||||
#define MIXER_MAXCHAN 8
|
||||
#define MIXER_BUFSIZE (16*1024)
|
||||
#define MIXER_SSIZE 4
|
||||
#define MIXER_SHIFT 16
|
||||
#define MIXER_SHIFT 14
|
||||
#define MIXER_REMAIN ((1<<MIXER_SHIFT)-1)
|
||||
#define MIXER_WAVESIZE MIXER_BUFSIZE
|
||||
#define MIXER_VOLSHIFT 14
|
||||
|
||||
#define MIXER_CLIP(SAMP) (SAMP>MAX_AUDIO) ? (Bit16s)MAX_AUDIO : (SAMP<MIN_AUDIO) ? (Bit16s)MIN_AUDIO : ((Bit16s)SAMP)
|
||||
|
||||
#define MAKE_m8(CHAN) ((Bit8s)(mixer.temp.m8[pos][CHAN]^0x80) << 8)
|
||||
#define MAKE_s8(CHAN) ((Bit8s)(mixer.temp.s8[pos][CHAN]^0x80) << 8)
|
||||
#define MAKE_m16(CHAN) mixer.temp.m16[pos][CHAN]
|
||||
#define MAKE_s16(CHAN) mixer.temp.s16[pos][CHAN]
|
||||
|
||||
#define MIX_NORMAL(TYPE, LCHAN,RCHAN) { \
|
||||
(chan->handler)(((Bit8u*)&mixer.temp)+sizeof(mixer.temp.TYPE[0]),sample_toread); \
|
||||
Bitu sample_index=(1 << MIXER_SHIFT) - chan->sample_left; \
|
||||
for (Bitu mix=0;mix<samples;mix++) { \
|
||||
Bitu pos=sample_index >> MIXER_SHIFT;sample_index+=chan->sample_add; \
|
||||
mixer.work[mix][0]+=chan->vol_mul[LCHAN]*MAKE_##TYPE( LCHAN ); \
|
||||
mixer.work[mix][1]+=chan->vol_mul[RCHAN]*MAKE_##TYPE( RCHAN ); \
|
||||
} \
|
||||
chan->remain=*(Bitu *)&mixer.temp.TYPE[sample_index>>MIXER_SHIFT]; \
|
||||
chan->sample_left=sample_total-sample_index; \
|
||||
break; \
|
||||
}
|
||||
|
||||
struct MIXER_Channel {
|
||||
double vol_main[2];
|
||||
Bits vol_mul[2];
|
||||
|
@ -90,19 +71,11 @@ static Bit8u wavheader[]={
|
|||
};
|
||||
|
||||
static struct {
|
||||
struct {
|
||||
Bit16s data[MIXER_BUFSIZE][2];
|
||||
Bitu read,write;
|
||||
} out;
|
||||
Bit32s work[MIXER_BUFSIZE][2];
|
||||
union {
|
||||
Bit16s m16[MIXER_BUFSIZE][1];
|
||||
Bit16s s16[MIXER_BUFSIZE][2];
|
||||
Bit8u m8[MIXER_BUFSIZE][1];
|
||||
Bit8u s8[MIXER_BUFSIZE][2];
|
||||
} temp;
|
||||
double mastervol[2];
|
||||
MIXER_Channel * channels;
|
||||
Bitu pos,done;
|
||||
Bitu needed,min_needed;
|
||||
float mastervol[2];
|
||||
MixerChannel * channels;
|
||||
bool nosound;
|
||||
Bitu freq;
|
||||
Bitu blocksize;
|
||||
|
@ -115,24 +88,22 @@ static struct {
|
|||
} wave;
|
||||
} mixer;
|
||||
|
||||
MIXER_Channel * MIXER_AddChannel(MIXER_MixHandler handler,Bitu freq,char * name) {
|
||||
//TODO Find a free channel
|
||||
MIXER_Channel * chan=new MIXER_Channel;
|
||||
if (!chan) return 0;
|
||||
chan->playing=false;
|
||||
chan->mode=MIXER_16STEREO;
|
||||
Bit8u MixTemp[MIXER_BUFSIZE];
|
||||
|
||||
MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,char * name) {
|
||||
MixerChannel * chan=new MixerChannel();
|
||||
chan->handler=handler;
|
||||
chan->name=name;
|
||||
chan->sample_add=(freq<<MIXER_SHIFT)/mixer.freq;
|
||||
chan->sample_left=0;
|
||||
chan->SetFreq(freq);
|
||||
chan->next=mixer.channels;
|
||||
chan->SetVolume(1,1);
|
||||
chan->enabled=false;
|
||||
mixer.channels=chan;
|
||||
MIXER_SetVolume(chan,1,1);
|
||||
return chan;
|
||||
}
|
||||
|
||||
MIXER_Channel * MIXER_FindChannel(const char * name) {
|
||||
MIXER_Channel * chan=mixer.channels;
|
||||
MixerChannel * MIXER_FindChannel(const char * name) {
|
||||
MixerChannel * chan=mixer.channels;
|
||||
while (chan) {
|
||||
if (!strcasecmp(chan->name,name)) break;
|
||||
chan=chan->next;
|
||||
|
@ -140,129 +111,212 @@ MIXER_Channel * MIXER_FindChannel(const char * name) {
|
|||
return chan;
|
||||
}
|
||||
|
||||
void MIXER_SetFreq(MIXER_Channel * chan,Bitu freq) {
|
||||
if (!chan) return;
|
||||
chan->freq=freq;
|
||||
chan->sample_add=(freq<<MIXER_SHIFT)/mixer.freq;
|
||||
}
|
||||
|
||||
void MIXER_SetMode(MIXER_Channel * chan,Bit8u mode) {
|
||||
if (chan) chan->mode=mode;
|
||||
void MixerChannel::UpdateVolume(void) {
|
||||
volmul[0]=(Bits)((1 << MIXER_VOLSHIFT)*volmain[0]*mixer.mastervol[0]);
|
||||
volmul[1]=(Bits)((1 << MIXER_VOLSHIFT)*volmain[1]*mixer.mastervol[1]);
|
||||
}
|
||||
|
||||
void MIXER_UpdateVolume(MIXER_Channel * chan) {
|
||||
chan->vol_mul[0]=(Bits)((1 << MIXER_VOLSHIFT)*chan->vol_main[0]*mixer.mastervol[0]);
|
||||
chan->vol_mul[1]=(Bits)((1 << MIXER_VOLSHIFT)*chan->vol_main[1]*mixer.mastervol[1]);
|
||||
void MixerChannel::SetVolume(float _left,float _right) {
|
||||
volmain[0]=_left;
|
||||
volmain[1]=_right;
|
||||
UpdateVolume();
|
||||
}
|
||||
|
||||
void MIXER_SetVolume(MIXER_Channel * chan,float left,float right) {
|
||||
if (!chan) return;
|
||||
if (left>=0) chan->vol_main[0]=left;
|
||||
if (right>=0) chan->vol_main[1]=right;
|
||||
MIXER_UpdateVolume(chan);
|
||||
void MixerChannel::Enable(bool _yesno) {
|
||||
if (_yesno==enabled) return;
|
||||
enabled=_yesno;
|
||||
if (enabled) {
|
||||
freq_index=MIXER_REMAIN;
|
||||
SDL_LockAudio();
|
||||
if (done<mixer.done) done=mixer.done;
|
||||
SDL_UnlockAudio();
|
||||
}
|
||||
}
|
||||
|
||||
void MIXER_Enable(MIXER_Channel * chan,bool enable) {
|
||||
if (chan) chan->playing=enable;
|
||||
void MixerChannel::SetFreq(Bitu _freq) {
|
||||
freq_add=(_freq<<MIXER_SHIFT)/mixer.freq;
|
||||
}
|
||||
|
||||
void MixerChannel::Mix(Bitu _needed) {
|
||||
needed=_needed;
|
||||
while (enabled && needed>done) {
|
||||
Bitu todo=needed-done;
|
||||
todo*=freq_add;
|
||||
if (todo & MIXER_REMAIN) {
|
||||
todo=(todo >> MIXER_SHIFT) + 1;
|
||||
} else {
|
||||
todo=(todo >> MIXER_SHIFT);
|
||||
}
|
||||
handler(todo);
|
||||
}
|
||||
}
|
||||
|
||||
void MixerChannel::AddSilence(void) {
|
||||
if (done<needed) {
|
||||
done=needed;
|
||||
last[0]=last[1]=0;
|
||||
freq_index=MIXER_REMAIN;
|
||||
}
|
||||
}
|
||||
|
||||
template<bool _8bits,bool stereo>
|
||||
INLINE void MixerChannel::AddSamples(Bitu len,void * data) {
|
||||
Bits diff[2];
|
||||
Bit8u * data8=(Bit8u*)data;
|
||||
Bit16s * data16=(Bit16s*)data;
|
||||
Bitu mixpos=mixer.pos+done;
|
||||
freq_index&=MIXER_REMAIN;
|
||||
Bitu pos=0;
|
||||
goto thestart;
|
||||
while (1) {
|
||||
Bitu new_pos=freq_index >> MIXER_SHIFT;
|
||||
if (pos<new_pos) {
|
||||
last[0]+=diff[0];
|
||||
if (stereo) last[1]+=diff[1];
|
||||
pos=new_pos;
|
||||
thestart:
|
||||
if (pos>=len) return;
|
||||
if (_8bits) {
|
||||
if (stereo) {
|
||||
diff[0]=(((Bit8s)(data8[pos*2+0] ^ 0x80)) << 8)-last[0];
|
||||
diff[1]=(((Bit8s)(data8[pos*2+1] ^ 0x80)) << 8)-last[1];
|
||||
} else {
|
||||
diff[0]=(((Bit8s)(data8[pos] ^ 0x80)) << 8)-last[0];
|
||||
}
|
||||
} else {
|
||||
if (stereo) {
|
||||
diff[0]=data16[pos*2+0]-last[0];
|
||||
diff[1]=data16[pos*2+1]-last[1];
|
||||
} else {
|
||||
diff[0]=data16[pos]-last[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
Bits diff_mul=freq_index & MIXER_REMAIN;
|
||||
freq_index+=freq_add;
|
||||
mixpos&=MIXER_BUFMASK;
|
||||
Bits sample=last[0]+((diff[0]*diff_mul) >> MIXER_SHIFT);
|
||||
mixer.work[mixpos][0]+=sample*volmul[0];
|
||||
if (stereo) sample=last[1]+((diff[1]*diff_mul) >> MIXER_SHIFT);
|
||||
mixer.work[mixpos][1]+=sample*volmul[1];
|
||||
mixpos++;done++;
|
||||
}
|
||||
}
|
||||
|
||||
void MixerChannel::AddStretched(Bitu len,Bit16s * data) {
|
||||
if (done>=needed) {
|
||||
LOG_MSG("Can't add, buffer full");
|
||||
return;
|
||||
}
|
||||
Bitu outlen=needed-done;Bits diff;
|
||||
freq_index=0;
|
||||
Bitu temp_add=(len << MIXER_SHIFT)/outlen;
|
||||
Bitu mixpos=mixer.pos+done;done=needed;
|
||||
Bitu pos=0;
|
||||
diff=data[0]-last[0];
|
||||
while (outlen--) {
|
||||
Bitu new_pos=freq_index >> MIXER_SHIFT;
|
||||
if (pos<new_pos) {
|
||||
pos=new_pos;
|
||||
last[0]+=diff;
|
||||
diff=data[pos]-last[0];
|
||||
}
|
||||
Bits diff_mul=freq_index & MIXER_REMAIN;
|
||||
freq_index+=temp_add;
|
||||
mixpos&=MIXER_BUFMASK;
|
||||
Bits sample=last[0]+((diff*diff_mul) >> MIXER_SHIFT);
|
||||
mixer.work[mixpos][0]+=sample*volmul[0];
|
||||
mixer.work[mixpos][1]+=sample*volmul[1];
|
||||
mixpos++;
|
||||
}
|
||||
};
|
||||
|
||||
void MixerChannel::AddSamples_m8(Bitu len,Bit8u * data) {
|
||||
AddSamples<true,false>(len,data);
|
||||
}
|
||||
void MixerChannel::AddSamples_s8(Bitu len,Bit8u * data) {
|
||||
AddSamples<true,true>(len,data);
|
||||
}
|
||||
void MixerChannel::AddSamples_m16(Bitu len,Bit16s * data) {
|
||||
AddSamples<false,false>(len,data);
|
||||
}
|
||||
void MixerChannel::AddSamples_s16(Bitu len,Bit16s * data) {
|
||||
AddSamples<false,true>(len,data);
|
||||
}
|
||||
|
||||
void MixerChannel::FillUp(void) {
|
||||
SDL_LockAudio();
|
||||
if (!enabled || done<mixer.done) {
|
||||
SDL_UnlockAudio();
|
||||
return;
|
||||
}
|
||||
Bitu filled=(done-mixer.done)*1000/(mixer.needed-mixer.done);
|
||||
Bitu index=PIC_Index();
|
||||
if (filled<index) {
|
||||
Bitu temp=mixer.done+((index*(mixer.needed-mixer.done))/1000);
|
||||
Mix(temp);
|
||||
}
|
||||
SDL_UnlockAudio();
|
||||
}
|
||||
|
||||
/* Mix a certain amount of new samples */
|
||||
static void MIXER_MixData(Bitu samples) {
|
||||
if (!samples) return;
|
||||
if (samples>MIXER_BUFSIZE) samples=MIXER_BUFSIZE;
|
||||
MIXER_Channel * chan=mixer.channels;
|
||||
static void MIXER_MixData(Bitu needed) {
|
||||
MixerChannel * chan=mixer.channels;
|
||||
while (chan) {
|
||||
if (chan->playing) {
|
||||
/* This should always allocate 1 extra sample */
|
||||
Bitu sample_total=(samples*chan->sample_add)-chan->sample_left;
|
||||
Bitu sample_toread=sample_total >> MIXER_SHIFT;
|
||||
if (sample_total & MIXER_REMAIN) sample_toread++;
|
||||
sample_total=(sample_toread+1)<<MIXER_SHIFT;
|
||||
*(Bitu *)&mixer.temp=chan->remain;
|
||||
switch (chan->mode) {
|
||||
case MIXER_8MONO:
|
||||
MIX_NORMAL(m8,0,0);
|
||||
break;
|
||||
case MIXER_8STEREO:
|
||||
MIX_NORMAL(m8,0,1);
|
||||
break;
|
||||
case MIXER_16MONO:
|
||||
MIX_NORMAL(m16,0,0);
|
||||
break;
|
||||
case MIXER_16STEREO:
|
||||
MIX_NORMAL(s16,0,1);
|
||||
break;
|
||||
default:
|
||||
E_Exit("MIXER:Illegal sound mode %2X",chan->mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
chan->Mix(needed);
|
||||
chan=chan->next;
|
||||
}
|
||||
Bitu index=mixer.out.write;
|
||||
for (Bitu read=0;read<samples;read++) {
|
||||
Bits temp=mixer.work[read][0] >> MIXER_VOLSHIFT;
|
||||
mixer.out.data[index][0]=MIXER_CLIP(temp);
|
||||
mixer.work[read][0]=0;
|
||||
temp=mixer.work[read][1] >> MIXER_VOLSHIFT;
|
||||
mixer.out.data[index][1]=MIXER_CLIP(temp);
|
||||
mixer.work[read][1]=0;
|
||||
index=(index+1)&(MIXER_BUFSIZE-1);
|
||||
}
|
||||
mixer.out.write=index;
|
||||
if (mixer.wave.handle) {
|
||||
index=(MIXER_BUFSIZE+mixer.out.write-samples);
|
||||
while (samples--) {
|
||||
index=index&(MIXER_BUFSIZE-1);
|
||||
mixer.wave.buf[mixer.wave.used][0]=mixer.out.data[index][0];
|
||||
mixer.wave.buf[mixer.wave.used][1]=mixer.out.data[index][1];
|
||||
index++;mixer.wave.used++;
|
||||
}
|
||||
if (mixer.wave.used>(MIXER_WAVESIZE-1024)){
|
||||
fwrite(mixer.wave.buf,1,mixer.wave.used*MIXER_SSIZE,mixer.wave.handle);
|
||||
mixer.wave.length+=mixer.wave.used*MIXER_SSIZE;
|
||||
mixer.wave.used=0;
|
||||
}
|
||||
}
|
||||
mixer.done=needed;
|
||||
}
|
||||
|
||||
static void MIXER_Mix(void) {
|
||||
SDL_LockAudio();
|
||||
MIXER_MixData(mixer.needed);
|
||||
mixer.tick_remain+=mixer.tick_add;
|
||||
Bitu count=mixer.tick_remain>>MIXER_SHIFT;
|
||||
mixer.tick_remain&=((1<<MIXER_SHIFT)-1);
|
||||
Bitu size=MIXER_BUFSIZE+mixer.out.write-mixer.out.read;
|
||||
if (size>=MIXER_BUFSIZE) size-=MIXER_BUFSIZE;
|
||||
if (size>mixer.blocksize*2) return;
|
||||
MIXER_MixData(count);
|
||||
mixer.needed+=(mixer.tick_remain>>MIXER_SHIFT);
|
||||
mixer.tick_remain&=MIXER_REMAIN;
|
||||
SDL_UnlockAudio();
|
||||
}
|
||||
|
||||
static void MIXER_Mix_NoSound(void) {
|
||||
mixer.done=0;
|
||||
mixer.tick_remain+=mixer.tick_add;
|
||||
Bitu count=mixer.tick_remain>>MIXER_SHIFT;
|
||||
mixer.tick_remain&=((1<<MIXER_SHIFT)-1);
|
||||
mixer.tick_remain&=MIXER_REMAIN;
|
||||
MIXER_MixData(count);
|
||||
}
|
||||
|
||||
|
||||
static void MIXER_CallBack(void * userdata, Uint8 *stream, int len) {
|
||||
/* Copy data from out buffer to the stream */
|
||||
Bitu size=MIXER_BUFSIZE+mixer.out.write-mixer.out.read;
|
||||
if (size>=MIXER_BUFSIZE) size-=MIXER_BUFSIZE;
|
||||
if (size*MIXER_SSIZE<(Bitu)len) {
|
||||
// LOG(0,"Buffer underrun");
|
||||
/* When there's a buffer underrun, keep the data so there will be more next time */
|
||||
Bitu need=(Bitu)len/MIXER_SSIZE;
|
||||
if (need>mixer.done) {
|
||||
// LOG_MSG("Buffer underrun");
|
||||
return;
|
||||
}
|
||||
Bitu remain=MIXER_BUFSIZE-mixer.out.read;
|
||||
if (remain>=(Bitu)len/MIXER_SSIZE) {
|
||||
memcpy((void *)stream,(void *)&mixer.out.data[mixer.out.read][0],len);
|
||||
} else {
|
||||
memcpy((void *)stream,(void *)&mixer.out.data[mixer.out.read][0],remain*MIXER_SSIZE);
|
||||
stream+=remain*MIXER_SSIZE;
|
||||
memcpy((void *)stream,(void *)&mixer.out.data[0][0],(len)-remain*MIXER_SSIZE);
|
||||
/* Reduce done count in all channels */
|
||||
for (MixerChannel * chan=mixer.channels;chan;chan=chan->next) {
|
||||
if (chan->done>need) chan->done-=need;
|
||||
else chan->done=0;
|
||||
}
|
||||
mixer.done-=need;
|
||||
mixer.needed-=need;
|
||||
if (mixer.done>mixer.min_needed) {
|
||||
Bitu diff=mixer.done-mixer.min_needed;
|
||||
mixer.tick_add=((mixer.freq-(diff>>2)) << MIXER_SHIFT)/1000;
|
||||
} else {
|
||||
Bitu diff=mixer.needed-mixer.done;
|
||||
mixer.tick_add=((mixer.freq+diff*3) << MIXER_SHIFT)/1000;
|
||||
}
|
||||
Bit16s * output=(Bit16s *)stream;
|
||||
while (need--) {
|
||||
mixer.work[mixer.pos][0]>>=MIXER_VOLSHIFT;
|
||||
*output++=MIXER_CLIP(mixer.work[mixer.pos][0]);
|
||||
mixer.work[mixer.pos][0]=0;
|
||||
mixer.work[mixer.pos][1]>>=MIXER_VOLSHIFT;
|
||||
*output++=MIXER_CLIP(mixer.work[mixer.pos][1]);
|
||||
mixer.work[mixer.pos][1]=0;
|
||||
mixer.pos=(mixer.pos+1)&MIXER_BUFMASK;
|
||||
}
|
||||
mixer.out.read+=(len/MIXER_SSIZE);
|
||||
if (mixer.out.read>=MIXER_BUFSIZE) mixer.out.read-=MIXER_BUFSIZE;
|
||||
}
|
||||
|
||||
static void MIXER_WaveEvent(void) {
|
||||
|
@ -297,7 +351,7 @@ static void MIXER_Stop(Section* sec) {
|
|||
|
||||
class MIXER : public Program {
|
||||
public:
|
||||
void MakeVolume(char * scan,double & vol0,double & vol1) {
|
||||
void MakeVolume(char * scan,float & vol0,float & vol1) {
|
||||
Bitu w=0;
|
||||
bool db=(toupper(*scan)=='D');
|
||||
if (db) scan++;
|
||||
|
@ -306,7 +360,7 @@ public:
|
|||
++scan;w=1;
|
||||
}
|
||||
char * before=scan;
|
||||
double val=strtod(scan,&scan);
|
||||
float val=(float)strtod(scan,&scan);
|
||||
if (before==scan) {
|
||||
++scan;continue;
|
||||
}
|
||||
|
@ -321,7 +375,7 @@ public:
|
|||
}
|
||||
if (!w) vol1=vol0;
|
||||
}
|
||||
void ShowVolume(char * name,double vol0,double vol1) {
|
||||
void ShowVolume(char * name,float vol0,float vol1) {
|
||||
WriteOut("%-8s %3.0f:%-3.0f %+3.2f:%-+3.2f \n",name,
|
||||
vol0*100,vol1*100,
|
||||
20*log(vol0)/log(10.0f),20*log(vol1)/log(10.0f)
|
||||
|
@ -329,14 +383,14 @@ public:
|
|||
}
|
||||
void Run(void) {
|
||||
if (cmd->FindString("MASTER",temp_line,false)) {
|
||||
MakeVolume((char *)temp_line.c_str(),mixer.mastervol[0],mixer.mastervol[1]);
|
||||
MakeVolume((char *)temp_line.c_str(),mixer.mastervol[0],mixer.mastervol[1]);
|
||||
}
|
||||
MIXER_Channel * chan=mixer.channels;
|
||||
MixerChannel * chan=mixer.channels;
|
||||
while (chan) {
|
||||
if (cmd->FindString(chan->name,temp_line,false)) {
|
||||
MakeVolume((char *)temp_line.c_str(),chan->vol_main[0],chan->vol_main[1]);
|
||||
MakeVolume((char *)temp_line.c_str(),chan->volmain[0],chan->volmain[1]);
|
||||
}
|
||||
MIXER_UpdateVolume(chan);
|
||||
chan->UpdateVolume();
|
||||
chan=chan->next;
|
||||
}
|
||||
if (cmd->FindExist("/NOSHOW")) return;
|
||||
|
@ -344,7 +398,7 @@ public:
|
|||
WriteOut("Channel Main Main(dB)\n");
|
||||
ShowVolume("MASTER",mixer.mastervol[0],mixer.mastervol[1]);
|
||||
for (chan=mixer.channels;chan;chan=chan->next)
|
||||
ShowVolume(chan->name,chan->vol_main[0],chan->vol_main[1]);
|
||||
ShowVolume(chan->name,chan->volmain[0],chan->volmain[1]);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -362,9 +416,9 @@ void MIXER_Init(Section* sec) {
|
|||
|
||||
/* Initialize the internal stuff */
|
||||
mixer.channels=0;
|
||||
mixer.out.write=0;
|
||||
mixer.out.read=0;
|
||||
memset(mixer.out.data,0,sizeof(mixer.out.data));
|
||||
mixer.pos=0;
|
||||
mixer.done=0;
|
||||
memset(mixer.work,0,sizeof(mixer.work));
|
||||
mixer.wave.handle=0;
|
||||
mixer.wave.used=0;
|
||||
mixer.mastervol[0]=1.0f;
|
||||
|
@ -393,10 +447,15 @@ void MIXER_Init(Section* sec) {
|
|||
} else {
|
||||
mixer.freq=obtained.freq;
|
||||
mixer.blocksize=obtained.samples;
|
||||
mixer.tick_add=((mixer.freq+100) << MIXER_SHIFT)/1000;
|
||||
mixer.tick_add=(mixer.freq << MIXER_SHIFT)/1000;
|
||||
TIMER_AddTickHandler(MIXER_Mix);
|
||||
SDL_PauseAudio(0);
|
||||
}
|
||||
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;
|
||||
|
||||
MAPPER_AddHandler(MIXER_WaveEvent,MK_f6,MMOD1,"recwave","Rec Wave");
|
||||
PROGRAMS_MakeFile("MIXER.COM",MIXER_ProgramStart);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue