precalculating some more from CalcNote

svn-id: r42556
This commit is contained in:
Norbert Lange 2009-07-17 01:42:58 +00:00
parent 1fa1bdc9f6
commit c0c25d234e
2 changed files with 22 additions and 24 deletions

View File

@ -276,7 +276,7 @@ endOfEventLoop:
if ((uint16)(voice.portaTicks >> 8) >= channel.portamentoTime) {
voice.hasPortamento = false;
voice.baseNote = voice.endNote;
voice.preCalcNote = precalcNote(voice.baseNote, patch.tune);
voice.preCalcNote = precalcNote(voice.baseNote, patch.tune, voice.octave);
}
voice.lastPeriod = calcNote(voice);
} else if (channel.isAltered || channel.modulation)
@ -382,7 +382,7 @@ int8 MaxTrax::pickvoice(const VoiceContext voices[4], uint pick, int16 pri) {
return -1;
}
uint16 MaxTrax::calcNote(const VoiceContext &voice, int32 *offset) {
uint16 MaxTrax::calcNote(const VoiceContext &voice) {
const ChannelContext &channel = *voice.channel;
int16 bend = channel.pitchReal;
if (voice.hasPortamento)
@ -396,19 +396,12 @@ uint16 MaxTrax::calcNote(const VoiceContext &voice, int32 *offset) {
// tone = voice.baseNote << 8 + microtonal
// bend = channelPitch + porta + modulation
int32 tone = voice.preCalcNote + (bend << 6) / 3;
const int32 tone = voice.preCalcNote + (bend << 6) / 3;
// calculate which sample to use
if (offset) {
*offset = (tone <= PREF_PERIOD) ? 0 : MIN((int32)((tone + 0xFFFF - PREF_PERIOD) >> 16), (int32)(voice.patch->sampleOctaves - 1)) << 16;
tone -= *offset;
} else
tone -= voice.periodOffset;
if (tone >= PERIOD_LIMIT) {
if (tone >= PERIOD_LIMIT + (1 << 16)) {
// calculate 2^tone and round towards nearest integer
// 2*2^tone = exp((tone+1) * ln(2))
const uint16 periodX2 = (uint16)expf((float)(tone + (1 << 16)) * (float)(0.69314718055994530942 / (1 << 16)));
const uint16 periodX2 = (uint16)expf((float)tone * (float)(0.69314718055994530942 / (1 << 16)));
return (periodX2 + 1) / 2;
}
return 0;
@ -432,7 +425,7 @@ int8 MaxTrax::noteOn(ChannelContext &channel, const byte note, uint16 volume, ui
// reset previous porta
if (voice->hasPortamento)
voice->baseNote = voice->endNote;
voice->preCalcNote = precalcNote(voice->baseNote, patch.tune);
voice->preCalcNote = precalcNote(voice->baseNote, patch.tune, voice->octave);
voice->portaTicks = 0;
voice->hasPortamento = true;
voice->endNote = channel.lastNote = note;
@ -444,6 +437,7 @@ int8 MaxTrax::noteOn(ChannelContext &channel, const byte note, uint16 volume, ui
if (voiceNum >= 0) {
VoiceContext &voice = _voiceCtx[voiceNum];
voice.flags = 0;
voice.hasPortamento = false;
if (voice.channel) {
killVoice(voiceNum);
voice.flags |= VoiceContext::kFlagStolen;
@ -451,12 +445,15 @@ int8 MaxTrax::noteOn(ChannelContext &channel, const byte note, uint16 volume, ui
voice.channel = &channel;
voice.patch = &patch;
voice.baseNote = note;
voice.preCalcNote = precalcNote(voice.baseNote, patch.tune);
voice.hasPortamento = false;
const int32 plainNote = precalcNote(voice.baseNote, patch.tune, 0);
const int32 PREF_PERIOD1 = 0x8fd77 + (1 << 16);
// calculate which sample to use
const int useOctave = (plainNote <= PREF_PERIOD1) ? 0 : MIN<int32>((plainNote + 0xFFFF - PREF_PERIOD1) >> 16, patch.sampleOctaves - 1);
voice.octave = (byte)useOctave;
voice.preCalcNote = plainNote - (useOctave << 16);
voice.lastPeriod = calcNote(voice, &voice.periodOffset);
const int useOctave = voice.periodOffset >> 16;
voice.lastPeriod = calcNote(voice);
voice.priority = (byte)pri;
voice.status = VoiceContext::kStatusStart;
@ -509,7 +506,7 @@ int8 MaxTrax::noteOn(ChannelContext &channel, const byte note, uint16 volume, ui
voice.portaTicks = 0;
voice.endNote = voice.baseNote;
voice.baseNote = channel.lastNote;
voice.preCalcNote = precalcNote(voice.baseNote, patch.tune);
voice.preCalcNote = precalcNote(voice.baseNote, patch.tune, voice.octave);
voice.hasPortamento = true;
}
channel.lastNote = note;

View File

@ -152,7 +152,7 @@ public:
uint32 ticksLeft;
int32 portaTicks;
int32 incrVolume;
int32 periodOffset;
// int32 periodOffset;
/*ifne FASTSOUND
APTR voice_CurFastIOB ; current fast iob playing
APTR voice_NextFastIOB ; next fast iob to play
@ -164,8 +164,9 @@ public:
uint16 lastPeriod;
byte baseNote;
byte endNote;
byte number;
byte link;
byte octave;
// byte number;
// byte link;
byte priority;
enum {
kStatusFree,
@ -203,7 +204,7 @@ public:
static int8 pickvoice(const VoiceContext voice[4], uint pick, int16 pri);
int32 calcVolumeDelta(int32 delta, uint16 time);
static uint16 calcNote(const VoiceContext &voice, int32 *offset = 0);
static uint16 calcNote(const VoiceContext &voice);
int8 noteOn(ChannelContext &channel, byte note, uint16 volume, uint16 pri);
void noteOff(VoiceContext &voice, byte note);
void killVoice(byte num);
@ -213,8 +214,8 @@ public:
_playerCtx.tickUnit = (int32)(((uint32)(tempo & 0xFFF0) << 8) / (uint16)(5 * _playerCtx.vBlankFreq));
}
static int32 precalcNote(byte baseNote, int16 tune) {
return 0x9fd77 + 0x3C000 - ((baseNote << 14) + (tune << 11) / 3) / 3;
static int32 precalcNote(byte baseNote, int16 tune, byte octave) {
return 0x9fd77 + 0x3C000 + (1 << 16) - ((baseNote << 14) + (tune << 11) / 3) / 3 - (octave << 16);
}
static void outPutEvent(const Event &ev, int num = -1) {