Skip to content

Commit a67641f

Browse files
committed
3.9.2 alpha
1 parent b3552d9 commit a67641f

File tree

5 files changed

+315
-305
lines changed

5 files changed

+315
-305
lines changed

source/de/quippy/javamod/multimedia/mod/loader/tracker/XMMod.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,14 @@ private void readXMPattern(final ModfileInputStream inputStream) throws IOExcept
204204
final int packedPatternDataSize = inputStream.readIntelUnsignedWord();
205205
if (packedPatternDataSize==0)
206206
{
207-
patternContainer.createPattern(pattNum, rows);
207+
patternContainer.createPattern(pattNum, rows, getNChannels());
208+
for (int row=0; row<rows; row++)
209+
{
210+
for (int channel=0; channel<getNChannels(); channel++)
211+
{
212+
patternContainer.createPatternElement(pattNum, row, channel);
213+
}
214+
}
208215
continue;
209216
}
210217

source/de/quippy/javamod/multimedia/mod/mixer/BasicModMixer.java

+38-74
Original file line numberDiff line numberDiff line change
@@ -774,37 +774,12 @@ protected void calculateGlobalTuning()
774774
* @param aktMemo
775775
* @param period or noteIndex
776776
* @return
777+
* @since 28.06.2024 moved to the respective Mixers (ProTrackerMixher and ScreamTrackerMixer)
777778
*/
778779
protected int getFineTunePeriod(final ChannelMemory aktMemo, final int period)
779780
{
780-
final int noteIndex = period - 1; // Period is only a note index now. No period - easier lookup
781-
switch (frequencyTableType)
782-
{
783-
case ModConstants.STM_S3M_TABLE:
784-
case ModConstants.IT_AMIGA_TABLE:
785-
final int s3mNote=ModConstants.FreqS3MTable[noteIndex%12];
786-
final int s3mOctave=noteIndex/12;
787-
return (int)((long)ModConstants.BASEFREQUENCY * ((long)s3mNote<<7) / ((long)aktMemo.currentFinetuneFrequency<<s3mOctave));
788-
789-
case ModConstants.IT_LINEAR_TABLE:
790-
return (ModConstants.FreqS3MTable[noteIndex%12]<<7)>>(noteIndex/12);
791-
792-
case ModConstants.AMIGA_TABLE:
793-
final int lookUpFineTune = (aktMemo.currentFineTune<0)?aktMemo.currentFineTune+16:aktMemo.currentFineTune;
794-
final int proTrackerIndex = noteIndex - 36; // our lookup table has three more octaves
795-
return ModConstants.periodTable[(lookUpFineTune*37) + proTrackerIndex]<<ModConstants.PERIOD_SHIFT;
796-
797-
case ModConstants.XM_AMIGA_TABLE:
798-
final int amigaIndex = (noteIndex<<4) + ((aktMemo.currentFineTune>>3) + 16); // 0..1920
799-
return ModConstants.FT2_amigaPeriods[amigaIndex]<<(ModConstants.PERIOD_SHIFT-2); // table values are already shifted by 2
800-
801-
case ModConstants.XM_LINEAR_TABLE:
802-
final int linearIndex = (noteIndex<<4) + ((aktMemo.currentFineTune>>3) + 16); // 0..1920
803-
return ModConstants.FT2_linearPeriods[linearIndex]<<(ModConstants.PERIOD_SHIFT-2); // table values are already shifted by 2
804-
805-
default: // Period is not a noteindex - this will never happen, but I once used it with protracker mods
806-
return (int)((long)ModConstants.BASEFREQUENCY * (long)period / (long)aktMemo.currentFinetuneFrequency);
807-
}
781+
// Period is not a noteindex - this will never happen, but I once used it with protracker mods
782+
return (int)((long)ModConstants.BASEFREQUENCY * (long)period / (long)aktMemo.currentFinetuneFrequency);
808783
}
809784
/**
810785
* Calls getFineTunePeriod(ChannelMemory, int Period) with the actual Period assigned.
@@ -830,6 +805,7 @@ protected int getFineTunePeriod(final ChannelMemory aktMemo)
830805
* MAKE SHURE that newPeriod is already the "getFineTunePeriod" value.
831806
* @param aktMemo
832807
* @param newPeriod
808+
* @since 28.06.2024 moved to the respective Mixers (ProTrackerMixher and ScreamTrackerMixer)
833809
*/
834810
protected void setNewPlayerTuningFor(final ChannelMemory aktMemo, final int newPeriod)
835811
{
@@ -842,35 +818,7 @@ protected void setNewPlayerTuningFor(final ChannelMemory aktMemo, final int newP
842818
}
843819

844820
final int clampedPeriod = (newPeriod>aktMemo.portaStepDownEnd)?aktMemo.portaStepDownEnd:(newPeriod<aktMemo.portaStepUpEnd)?aktMemo.portaStepUpEnd:newPeriod;
845-
846-
switch (frequencyTableType)
847-
{
848-
case ModConstants.AMIGA_TABLE:
849-
aktMemo.currentTuning = globalTuning / (aktMemo.currentNotePeriodSet = clampedPeriod);
850-
return;
851-
case ModConstants.XM_LINEAR_TABLE:
852-
// We have a different LUT table as original FT2 - to avoid the doubles used there
853-
// So we need some adoption to the algorithm used in FT2 but stay as close as possible to the coding there:
854-
final int period = (newPeriod>>(ModConstants.PERIOD_SHIFT-2)) & 0xFFFF;
855-
final int invPeriod = ((12 * 192 * 4) + 767 - period) & 0xFFFF; // 12 octaves * (12 * 16 * 4) LUT entries = 9216, add 767 for rounding
856-
final int quotient = invPeriod / (12 * 16 * 4);
857-
final int remainder = period % (12 * 16 * 4);
858-
final int newFrequency = ModConstants.lintab[remainder] >> (((14 - quotient) & 0x1F)-2); // values are 4 times bigger in FT2
859-
aktMemo.currentTuning = (int)(((long)newFrequency<<ModConstants.SHIFT) / (long)sampleRate);
860-
return;
861-
case ModConstants.IT_LINEAR_TABLE:
862-
final long itTuning = (((((long)ModConstants.BASEPERIOD)<<ModConstants.PERIOD_SHIFT) * (long)aktMemo.currentFinetuneFrequency)<<ModConstants.SHIFT) / (long)sampleRate;
863-
aktMemo.currentTuning = (int)(itTuning / (long)newPeriod);
864-
return;
865-
case ModConstants.STM_S3M_TABLE:
866-
aktMemo.currentTuning = globalTuning / clampedPeriod; // in globalTuning, all constant values are already calculated. (see above)
867-
return;
868-
case ModConstants.XM_AMIGA_TABLE:
869-
case ModConstants.IT_AMIGA_TABLE:
870-
default:
871-
aktMemo.currentTuning = globalTuning / clampedPeriod; // in globalTuning, all constant values are already calculated. (see above)
872-
return;
873-
}
821+
aktMemo.currentTuning = globalTuning / clampedPeriod;
874822
}
875823
/**
876824
* Set the current tuning for the player
@@ -1901,9 +1849,12 @@ protected void resetInstrumentPointers(final ChannelMemory aktMemo)
19011849
*/
19021850
protected void resetFineTune(final ChannelMemory aktMemo, final Sample currentSample)
19031851
{
1904-
aktMemo.currentFinetuneFrequency = currentSample.baseFrequency;
1905-
aktMemo.currentFineTune = currentSample.fineTune;
1906-
aktMemo.currentTranspose = currentSample.transpose;
1852+
if (currentSample!=null)
1853+
{
1854+
aktMemo.currentFinetuneFrequency = currentSample.baseFrequency;
1855+
aktMemo.currentFineTune = currentSample.fineTune;
1856+
aktMemo.currentTranspose = currentSample.transpose;
1857+
}
19071858
aktMemo.prevSampleOffset=0;
19081859
}
19091860
/**
@@ -1964,7 +1915,7 @@ protected void resetTablePositions(final ChannelMemory aktMemo)
19641915
*/
19651916
protected void resetAutoVibrato(final ChannelMemory aktMemo, final Sample sample)
19661917
{
1967-
if (isXM)
1918+
if (isXM && sample!=null)
19681919
{
19691920
if (sample.vibratoDepth>0)
19701921
{
@@ -2161,6 +2112,22 @@ protected void setNewInstrumentAndPeriod(final ChannelMemory aktMemo)
21612112
:mod.getInstrumentContainer().getSample(aktMemo.currentAssignedInstrumentIndex-1);
21622113

21632114
boolean hasInstrument = element.getInstrument()>0 && aktMemo.assignedSample!=null;
2115+
// do certain range checks with XMs.
2116+
// With XMs the playback will skip some things when the noteIndex is out of range
2117+
// i.e. do not reset volume and panning, do not set finetune of instrument, do not set tuning
2118+
// we also do not set a sample offset (not implemented!) or retrigger the sample pointer
2119+
// but if the note is zero, we only do not set the tuning
2120+
// We simulate that here now - except for the sample offset...
2121+
boolean isXMIllegalNote = false;
2122+
boolean isXMZeroNote = false;
2123+
if (isXM)
2124+
{
2125+
int note = aktMemo.assignedNoteIndex;
2126+
if (note>96) note = aktMemo.assignedNoteIndex = 96;
2127+
if (aktMemo.assignedSample!=null) note += aktMemo.assignedSample.transpose;
2128+
if (note<0 || note>=10*12) isXMIllegalNote = true; // this is an uint8 compare
2129+
if (note==0) isXMZeroNote = true;
2130+
}
21642131

21652132
if (hasInstrument) // At this point we reset volume and panning for XMs and Fastracker family (IT, STM, S3M)
21662133
{
@@ -2173,7 +2140,7 @@ protected void setNewInstrumentAndPeriod(final ChannelMemory aktMemo)
21732140
if (aktMemo.currentSample!=null) aktMemo.assignedSample = aktMemo.currentSample;
21742141
}
21752142
// reset for new Instrument
2176-
resetVolumeAndPanning(aktMemo, aktMemo.currentAssignedInstrument, aktMemo.assignedSample);
2143+
if (!isXMIllegalNote) resetVolumeAndPanning(aktMemo, aktMemo.currentAssignedInstrument, aktMemo.assignedSample);
21772144
resetEnvelopes(aktMemo, aktMemo.currentAssignedInstrument);
21782145
resetAutoVibrato(aktMemo, aktMemo.assignedSample);
21792146
resetTablePositions(aktMemo);
@@ -2326,18 +2293,15 @@ protected void setNewInstrumentAndPeriod(final ChannelMemory aktMemo)
23262293
}
23272294
else // isFastTrackerFamily: reset to last known note period if instrument is set without note (or current, which is set anyways)
23282295
{
2329-
resetAllEffects(aktMemo, element); // Reset Tremolo and such things... Forced! because of a new note
2330-
aktMemo.noteCut = aktMemo.keyOff = aktMemo.noteFade = false;
2331-
if (!(isXM && isNewNote && !hasInstrument)) // with XMs a single note without instrument set does not retrigger anything
2332-
{
2333-
resetInstrumentPointers(aktMemo);
2334-
resetEnvelopes(aktMemo);
2335-
resetAutoVibrato(aktMemo, aktMemo.currentSample);
2336-
if (isMOD) resetTablePositions(aktMemo); // with MODs we reset vibrato/tremolo here
2337-
}
2296+
resetAllEffects(aktMemo, element); // Reset Tremolo and such things...
2297+
//aktMemo.noteCut = aktMemo.keyOff = aktMemo.noteFade = false;
2298+
if (!isXMIllegalNote) resetInstrumentPointers(aktMemo);
2299+
resetEnvelopes(aktMemo);
2300+
resetAutoVibrato(aktMemo, aktMemo.currentSample);
2301+
if (isMOD) resetTablePositions(aktMemo); // with MODs we reset vibrato/tremolo here
23382302
// With XMs reset the finetune with a new note. A finetune effect might change that later
2339-
if (isXM) resetFineTune(aktMemo, aktMemo.currentSample);
2340-
setNewPlayerTuningFor(aktMemo, aktMemo.currentNotePeriod = getFineTunePeriod(aktMemo));
2303+
if (isXM && !isXMIllegalNote) resetFineTune(aktMemo, aktMemo.currentSample);
2304+
if (!isXMIllegalNote && !isXMZeroNote) setNewPlayerTuningFor(aktMemo, aktMemo.currentNotePeriod = getFineTunePeriod(aktMemo));
23412305
// With XMs we are also here in a note delay, even if it is a porta2Note effect - so do not reset portaTarget in that case
23422306
if (!isMOD && !isNoteDelay) aktMemo.portaTargetNotePeriod = aktMemo.currentNotePeriod; // do not reset with MODs
23432307
}
@@ -3019,7 +2983,7 @@ public int mixIntoBuffer(final long[] leftBuffer, final long[] rightBuffer, fina
30192983
for (int c=0; c<maxChannels; c++)
30202984
{
30212985
final ChannelMemory aktMemo = channelMemory[c];
3022-
if (!aktMemo.instrumentFinished) fillRampDataIntoBuffers(interweaveBufferLeft, interweaveBufferRight, aktMemo);
2986+
if (!aktMemo.instrumentFinished && aktMemo.currentSample!=null) fillRampDataIntoBuffers(interweaveBufferLeft, interweaveBufferRight, aktMemo);
30232987
}
30242988
interweaveStartIndex=0; interweave = true;
30252989
// now do the events

0 commit comments

Comments
 (0)