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
		Add a link
		
	
		Reference in a new issue