324 lines · 5.9 KB · C
RawDownload
#include "it_struc.h" #define MIN(a,b) ((a)<(b)?(a):(b)) static int tempo = 125;static double pos;static s32int mixbuf[44100*2];static s16int outbuf[44100*2]; static const char *DriverDetectCard(it_engine *, const char *, uint16_t, uint16_t){	return nil;} static const char *DriverInitSound(it_engine *){	return nil;} intDriverUninitSound(it_engine *){	return 0;} static voidkill_channel(it_engine *ite, it_slave *slave){	slave->Flags = 0x0200;	slave->LpD = 0; 	if((slave->HCN & 0x80) == 0)		ite->chn[slave->HCN].Flags &= ~4;} static intupdate_offs(it_engine *ite, it_slave *slave, int32_t *offs, int32_t *oferr, int32_t *nfreq, const int32_t lpbeg, const int32_t lpend){	*oferr += *nfreq;	*offs += *oferr>>16;	*oferr &= 0xFFFF; 	if((slave->LpM & 24) == 24 && slave->LpD != 0 && (*offs < lpbeg)){		*offs = lpbeg - *offs;		if(lpend <= lpbeg){			kill_channel(ite, slave);			return 1;		} 		*offs %= (lpend-lpbeg)*2;		if(*offs < (lpend-lpbeg)){			slave->LpD = 0;			if(*nfreq < 0) *nfreq = -*nfreq;			*offs += lpbeg;		}else{			*offs = (lpend - lpbeg) - *offs;			*offs += lpend - 1;		}	} 	if(*offs < 0){		if((slave->LpM & 24) != 24){			kill_channel(ite, slave);			slave->LpD = 0;			return 1;		} 		*offs = 0;		if(*nfreq < 0) *nfreq = -*nfreq;		slave->LpD = 0;	} 	if(*offs >= lpend){		if((slave->LpM & 8) == 0){			kill_channel(ite, slave);			return 1;		} 		if((slave->LpM & 24) == 24){			if(lpend <= lpbeg){				kill_channel(ite, slave);				return 1;			} 			*offs -= lpend;			*offs %= (lpend-lpbeg)*2;			if(*offs >= (lpend-lpbeg)){				*offs -= (lpend - lpbeg);				*offs += lpbeg;			}else{				slave->LpD = 1; 				*offs = lpend - *offs - 1; 				if(*nfreq > 0)					*nfreq = -*nfreq;			}		}else{			if(lpend <= lpbeg){				kill_channel(ite, slave);				return 1;			} 			*offs -= lpend;			*offs %= (lpend-lpbeg);			*offs += lpbeg;		}	} 	if(*offs < 0 || *offs >= lpend){		kill_channel(ite, slave);		return 1;	} 	return 0;} static intDriverPoll(it_engine *ite, uint16_t PlayMode, uint16_t CurrentPattern){	it_slave *slave;	u16int ax, cx;	it_slave *si;	int i, j; 	USED(PlayMode, CurrentPattern);	Update(ite, &cx, &si, &ax); 	int tper = (44100*10)/(tempo*4); 	memset(mixbuf, 0, tper*2*4);	memset(outbuf, 0, tper*2*2); 	for(i = 0; i < ite->NumChannels; i++){		slave = &ite->slave[i];		if((slave->Flags & 1) != 0 && (slave->Flags & 0x0200) == 0){			int offs = slave->Sample_Offset;			int oferr = slave->SmpErr;			int lpbeg = slave->Loop_Beginning;			int lpend = slave->Loop_End;			int nfreq = slave->Frequency; 			int32_t vol = slave->_16bVol;			vol *= ite->hdr.MV;			vol >>= 8; 			int lvol = vol, rvol = vol; 			if(slave->FPP == 100)				rvol = -rvol;			else if(slave->FPP < 32)				rvol = (rvol * slave->FPP) >> 5;			else				lvol = (lvol * (64 - slave->FPP)) >> 5; 			nfreq = (((s64int)nfreq) << 16) / 44100ULL; 			if(slave->LpD == 1) nfreq = -nfreq; 			if(ite->SamplePointer[slave->Smp] == nil){				kill_channel(ite, slave);				break;			}else if(slave->Bit != 0){				s16int *data = (s16int*)ite->SamplePointer[slave->Smp]; 				for(j = 0; j < tper*2; j+=2){					if(update_offs(ite, slave, &offs, &oferr, &nfreq, lpbeg, lpend) != 0)						break; 					mixbuf[j+0] -= (lvol*(int32_t)data[offs])>>14;					mixbuf[j+1] -= (rvol*(int32_t)data[offs])>>14;				}			}else{				s8int *data = (s8int*)ite->SamplePointer[slave->Smp];				for(j = 0; j < tper*2; j+=2){					if(update_offs(ite, slave, &offs, &oferr, &nfreq, lpbeg, lpend) != 0)						break; 					mixbuf[j+0] -= (lvol*(int32_t)data[offs])>>(14-8);					mixbuf[j+1] -= (rvol*(int32_t)data[offs])>>(14-8);				}			}			slave->Sample_Offset = offs;			slave->SmpErr = oferr;		} 		slave->Flags &= 0x788D;	} 	for(i = 0; i < tper*2; i++){		int32_t v = mixbuf[i];		if(v >  0x7FFF)			v =  0x7FFF;		else if(v < -0x7FFF)			v = -0x7FFF;		outbuf[i] = v;	} 	int got = tper*2*2;	int skip = 0;	if(pos > 0.001){		double n = MIN(pos, (double)got / 44100.0);		int skip = (int)(n * 44100)*2*2;		pos -= n;		if(skip >= got)			return 0;	}	write(1, outbuf+skip, got-skip); 	return 0;} static intDriverSetTempo(it_engine *, uint16_t Tempo){	tempo = Tempo;	return 0;} static intDriverSetMixVolume(it_engine *ite, uint16_t MixVolume){	USED(ite, MixVolume);	return 0;} static intDriverSetStereo(it_engine *ite, uint16_t Stereo){	/* whoops */	USED(ite, Stereo);	return 0;} static intDriverReleaseSample(it_engine *, it_sample *){	return 0;} static intDriverMIDIOut(it_engine *, uint8_t){	return 0;} static intDriverGetWaveform(it_engine *){	return 0;} it_drvdata *drv_oss_init(it_engine *){	static it_drvdata d = {		.BasePort = 0xFFFF,		.IRQ = 0xFFFF,		.DMA = 0xFFFF,		.CmdLineMixSpeed = 0,		.CmdLineDMASize = 1024,		.ReverseChannels = 0,		.DriverMaxChannels = 256,		.StopEndOfPlaySection = 1,		.DefaultChannels = 256,		.DriverFlags = 0,		.DriverDetectCard = DriverDetectCard,		.DriverInitSound = DriverInitSound,		.DriverUninitSound = DriverUninitSound,		.DriverPoll = DriverPoll,		.DriverSetTempo = DriverSetTempo,		.DriverSetMixVolume = DriverSetMixVolume,		.DriverSetStereo = DriverSetStereo,		.DriverReleaseSample = DriverReleaseSample,		.DriverMIDIOut = DriverMIDIOut,		.DriverGetWaveform = DriverGetWaveform,	}; 	return &d;} it_drvdata *drv_sdl_init(it_engine *){	return nil;} static voidusage(void){	fprint(2, "usage: %s [-s SECONDS]\n", argv0);	exits("usage");} voidmain(int argc, char **argv){	it_engine *ite;	char *s; 	ARGBEGIN{	case 's':		pos = atof(EARGF(usage()));		assert(pos >= 0.0);		break;	default:		usage();	}ARGEND 	ite = ITEngineNew();	Music_InitMusic(ite);	Music_AutoDetectSoundCard(ite);	D_LoadIT(ite, 0);	Music_PlaySong(ite, 0);	s = (char*)ite->hdr.SongName;	if(*s != 0)		fprint(2, "%.*s\n", sizeof(ite->hdr.SongName), s);	if(pos > 0.0)		fprint(2, "time: %g\n", pos);	while(ite->PlayMode != 0)		Music_Poll(ite);}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t