VOGONS


2003-7-26 Release

Topic actions

  • This topic is locked. You cannot reply or edit posts.

Reply 20 of 23, by ih8registrations

User metadata
Rank Oldbie
Rank
Oldbie

Well, I'd prefer oprofile if I could get it working. It's a system wide profiler for Linux. It's kernel based which allows everything to be profiled without having the profile code compiled in. It uses the x86 performance counter registers. A standard linux profiler is gprof. As for windows, I suppose visual studios would suffice wouldn't it?(since you've mentioned you're using visual c).

btw, a sequencer is a midi editor/creator. You can select instruments and everything else you'd think an editor would do so if you can't find a dos midi sequencer that works, you could create the test case midi files in a windows sequencer and then play them back with whatever method you were using before.

Last edited by ih8registrations on 2003-07-31, 09:52. Edited 1 time in total.

Reply 21 of 23, by ih8registrations

User metadata
Rank Oldbie
Rank
Oldbie

old

			for(t=0;t<10;t++) {
MidiChannel *tchan = mchan[t];
int ls, rs;

ts = tchan->getSample(&lsp, &rsp);

// Spot for MMX improvement?
ts = (ts * mastervolume)>>7;
rsp = (rsp * mastervolume)>>7;
lsp = (lsp * mastervolume)>>7;
rsp = (rsp * tchan->rightvol)>>8;
lsp = (lsp * tchan->leftvol)>>8;

ls = ((ts * tchan->leftvol) >> 8) + lsp;
rs = ((ts * tchan->rightvol) >> 8) + rsp;


c[0] += ls;
c[1] += rs;

}

new

			for(t=0;t<10;t++) {
MidiChannel *tchan = mchan[t];
ts = tchan->getSample(&lsp, &rsp);
c[0] += ((((ts + lsp) * mastervolume)>>7) * tchan->leftvol)>>8;
c[1] += ((((ts + rsp) * mastervolume)>>7) * tchan->rightvol)>>8;
}

btw, as far as I could tell, lsp & rsp start out uninitialized, but I don't know what they should be.

Went through the math factoring out the common variables a couple of times and when I calculated with dummy values for the variables, old & new results matched up, but it wouldn't hurt to double check my results.

Last edited by ih8registrations on 2003-07-31, 19:07. Edited 1 time in total.

Reply 22 of 23, by ih8registrations

User metadata
Rank Oldbie
Rank
Oldbie

A cleaned up MT32_CallBack:

	INLINE static void MT32_CallBack(Bit8u * stream,Bit32u len) {
if(!isEnabled) return;

int i, t;
Bit16s ts, lsp, rsp, c[2], *snd;
snd = (Bit16s *)stream;

for(i=0;i<len;i++) {
c[0] = c[1] = 0;

for(t=0;t<10;t++) {
ts = mchan[t]->getSample(&lsp, &rsp);
c[0] += ((((ts + lsp) * mastervolume)>>7) * mchan[t]->leftvol)>>8;
c[1] += ((((ts + rsp) * mastervolume)>>7) * mchan[t]->rightvol)>>8;
}

// Reverb code
/*
float tls, trs;
tls = ((float)c[0]);
trs = ((float)c[1]);
myReverb->run(&tls, &trs, .33);
c[0] = (int)(tls);
c[1] = (int)(trs);*/

*snd++ = c[0];
*snd++ = c[1];
}
}

I dropped the assignment 'MidiChannel *tchan = mchan[t];' and referenced mchan[t] directly. If I didn't goof reading the pointer usage again, here's a link describing what that does:
http://pardus-larus.student.utwente.nl/DOC/La … ialization.html

So one, it's pointing to anywhere, and two, it's copying the contents of mchan[t] to the address pointed to by tchan. MidiChannel class holds two 65k arrays along with a bunch of other stuff.

Last edited by ih8registrations on 2003-08-01, 15:50. Edited 1 time in total.

Reply 23 of 23, by canadacow

User metadata
Rank Member
Rank
Member

My pointer assignment of tchan to mchan[t] is ok as mchan is an array of pointers to the 9 MidiChannel objects.

In the meantime, I've used GoldCode to profile my code. As I suspected, getSample does consume most of the time spent processing the sound (about 99%) of MT32_Callback. Interestingly though, most of that time is spent in getSample itself, not in the envelope subroutines. getAmpEnvelope is about 14% of getSample, getPitchEnvelope and getFiltEnvelope are both about 11% each. Finally, the iir_filter code consumes about 8% of the time spent in getSample. This means the other 56% of the time is spent on code within the getSample routine. The profiler claimed this is due to some of the loops within the code as they have multiple compares. This of course, is not how the real MT-32 does channel processing. Rather, it simply has 32 partials of which it assigns to channels as they are needed. I may revise my code in that direction to speed it up. (Rather than iterating though 9 channels * 6 possible poly configs * 4 partials per channel). 32 compares would have to be better than 216.