Unified · Split
| @@ -22,7 +22,7 @@ · 21 unmodified lines | |||
| 22 | #include "pt2_scopes.h" | 22 | #include "pt2_scopes.h" |
| 23 | #include "pt2_sync.h" | 23 | #include "pt2_sync.h" |
| 24 | 24 | ||
| 25 | static bool posJumpAssert, pBreakFlag, updateUIPositions, modHasBeenPlayed; | 25 | static bool posJumpAssert, pBreakFlag, modRenderDone; |
| 26 | static int8_t pBreakPosition, oldRow, modPattern; | 26 | static int8_t pBreakPosition, oldRow, modPattern; |
| 27 | static uint8_t pattDelTime, lowMask = 0xFF, pattDelTime2; | 27 | static uint8_t pattDelTime, lowMask = 0xFF, pattDelTime2; |
| 28 | static int16_t modOrder, oldPattern, oldOrder; | 28 | static int16_t modOrder, oldPattern, oldOrder; |
| @@ -909,8 +909,38 @@ static void playVoice(moduleChannel_t *ch) · 880 unmodified lines | |||
| 909 | } | 909 | } |
| 910 | } | 910 | } |
| 911 | 911 | ||
| 912 | static bool firstNextPos = true; | ||
| 913 | |||
| 914 | static void updateUIPositions(void) | ||
| 915 | { | ||
| 916 | // don't update UI under MOD2WAV/PAT2SMP rendering | ||
| 917 | if (editor.isWAVRendering || editor.isSMPRendering) | ||
| 918 | return; | ||
| 919 | |||
| 920 | song->currRow = song->row; | ||
| 921 | song->currOrder = modOrder; | ||
| 922 | song->currPattern = modPattern; | ||
| 923 | |||
| 924 | uint16_t *currPatPtr = &song->header.order[modOrder]; | ||
| 925 | editor.currPatternDisp = currPatPtr; | ||
| 926 | editor.currPosEdPattDisp = currPatPtr; | ||
| 927 | editor.currPatternDisp = currPatPtr; | ||
| 928 | editor.currPosEdPattDisp = currPatPtr; | ||
| 929 | |||
| 930 | ui.updateSongPos = true; | ||
| 931 | ui.updateSongPattern = true; | ||
| 932 | ui.updateCurrPattText = true; | ||
| 933 | ui.updatePatternData = true; | ||
| 934 | |||
| 935 | if (ui.posEdScreenShown) | ||
| 936 | ui.updatePosEd = true; | ||
| 937 | } | ||
| 938 | |||
| 912 | static void nextPosition(void) | 939 | static void nextPosition(void) |
| 913 | { | 940 | { |
| 941 | if (editor.isSMPRendering) | ||
| 942 | modRenderDone = true; | ||
| 943 | |||
| 914 | song->row = pBreakPosition; | 944 | song->row = pBreakPosition; |
| 915 | pBreakPosition = 0; | 945 | pBreakPosition = 0; |
| 916 | posJumpAssert = false; | 946 | posJumpAssert = false; |
| @@ -925,9 +955,7 @@ static void nextPosition(void) · 8 unmodified lines | |||
| 925 | editor.stepPlayEnabled = false; | 955 | editor.stepPlayEnabled = false; |
| 926 | editor.stepPlayBackwards = false; | 956 | editor.stepPlayBackwards = false; |
| 927 | 957 | ||
| 928 | if (!editor.isWAVRendering && !editor.isSMPRendering) | 958 | song->currRow = song->row; |
| 929 | song->currRow = song->row; | ||
| 930 | |||
| 931 | return; | 959 | return; |
| 932 | } | 960 | } |
| 933 | 961 | ||
| @@ -935,96 +963,101 @@ static void nextPosition(void) · 1 unmodified line | |||
| 935 | if (modOrder >= song->header.numOrders) | 963 | if (modOrder >= song->header.numOrders) |
| 936 | { | 964 | { |
| 937 | modOrder = 0; | 965 | modOrder = 0; |
| 938 | modHasBeenPlayed = true; | ||
| 939 | 966 | ||
| 940 | if (config.compoMode) // stop song for music competitions playing | 967 | if (config.compoMode) // stop song for music competitions playing |
| 941 | { | 968 | { |
| 942 | doStopIt(true); | 969 | doStopIt(true); |
| 943 | turnOffVoices(); | 970 | turnOffVoices(); |
| 944 | 971 | ||
| 945 | song->currOrder = 0; | 972 | modOrder = 0; |
| 946 | song->currRow = song->row = 0; | 973 | modPattern = (int8_t)song->header.order[modOrder]; |
| 947 | song->currPattern = modPattern = (int8_t)song->header.order[0]; | 974 | song->row = 0; |
| 948 | 975 | ||
| 949 | editor.currPatternDisp = &song->currPattern; | 976 | updateUIPositions(); |
| 950 | editor.currPosEdPattDisp = &song->currPattern; | ||
| 951 | editor.currPatternDisp = &song->currPattern; | ||
| 952 | editor.currPosEdPattDisp = &song->currPattern; | ||
| 953 | |||
| 954 | if (ui.posEdScreenShown) | ||
| 955 | ui.updatePosEd = true; | ||
| 956 | |||
| 957 | ui.updateSongPos = true; | ||
| 958 | ui.updateSongPattern = true; | ||
| 959 | ui.updateCurrPattText = true; | ||
| 960 | } | 977 | } |
| 978 | |||
| 979 | if (editor.isWAVRendering) | ||
| 980 | modRenderDone = true; | ||
| 961 | } | 981 | } |
| 962 | 982 | ||
| 963 | modPattern = (int8_t)song->header.order[modOrder]; | 983 | modPattern = (int8_t)song->header.order[modOrder]; |
| 964 | if (modPattern > MAX_PATTERNS-1) | 984 | if (modPattern > MAX_PATTERNS-1) |
| 965 | modPattern = MAX_PATTERNS-1; | 985 | modPattern = MAX_PATTERNS-1; |
| 966 | |||
| 967 | updateUIPositions = true; | ||
| 968 | } | 986 | } |
| 987 | |||
| 988 | firstNextPos = false; | ||
| 969 | } | 989 | } |
| 970 | 990 | ||
| 971 | bool intMusic(void) | 991 | static void increasePlaybackTimer(void) |
| 972 | { | 992 | { |
| 973 | uint8_t i; | 993 | // the timer is not counting in "play pattern" mode |
| 974 | uint16_t *patt; | 994 | if (editor.playMode != PLAY_MODE_PATTERN && modBPM >= 32 && modBPM <= 255) |
| 975 | moduleChannel_t *c; | 995 | editor.musicTime64 += musicTimeTab64[modBPM-32]; |
| 996 | } | ||
| 976 | 997 | ||
| 977 | // Quirk: CIA uses newly set timer values on the next interrupt, so handle BPM change now (ciaSetBPM was set on previous interrupt) | 998 | static void setCurrRowToVisited(void) // for MOD2WAV |
| 978 | if (ciaSetBPM != -1) | 999 | { |
| 979 | { | 1000 | if (editor.isWAVRendering) |
| 980 | modSetTempo(ciaSetBPM, false); | 1001 | editor.rowVisitTable[(modOrder * MOD_ROWS) + song->row] = true; |
| 981 | ciaSetBPM = -1; | 1002 | } |
| 982 | } | ||
| 983 | 1003 | ||
| 984 | if (editor.playMode != PLAY_MODE_PATTERN && modBPM >= 32 && modBPM <= 255) | 1004 | static bool renderEndCheck(void) // for MOD2WAV/PAT2SMP |
| 985 | editor.musicTime64 += musicTimeTab64[modBPM-32]; // for playback counter (don't increase in "play/rec pattern" mode) | 1005 | { |
| 1006 | if (!editor.isWAVRendering && !editor.isSMPRendering) | ||
| 1007 | return true; // we're not doing MOD2WAV/PAT2SMP | ||
| 986 | 1008 | ||
| 987 | if (updateUIPositions) | 1009 | bool noPatternDelay = pattDelTime2 == 0; |
| 1010 | if (noPatternDelay && song->tick == song->speed-1) | ||
| 988 | { | 1011 | { |
| 989 | updateUIPositions = false; | 1012 | if (editor.isSMPRendering) |
| 990 | |||
| 991 | if (!editor.isWAVRendering && !editor.isSMPRendering) | ||
| 992 | { | 1013 | { |
| 993 | if (editor.playMode != PLAY_MODE_PATTERN) | 1014 | if (modRenderDone) |
| 994 | { | 1015 | return false; // we're done rendering |
| 995 | song->currOrder = modOrder; | 1016 | } |
| 996 | song->currPattern = modPattern; | 1017 | |
| 997 | 1018 | if (editor.isWAVRendering) | |
| 998 | patt = &song->header.order[modOrder]; | 1019 | { |
| 999 | editor.currPatternDisp = patt; | 1020 | bool rowVisited = editor.rowVisitTable[(modOrder * MOD_ROWS) + song->row]; |
| 1000 | editor.currPosEdPattDisp = patt; | 1021 | if (rowVisited || modRenderDone) |
| 1001 | editor.currPatternDisp = patt; | 1022 | return false; // we're done rendering |
| 1002 | editor.currPosEdPattDisp = patt; | 1023 | } |
| 1024 | } | ||
| 1003 | 1025 | ||
| 1004 | if (ui.posEdScreenShown) | 1026 | return true; |
| 1005 | ui.updatePosEd = true; | 1027 | } |
| 1006 | 1028 | ||
| 1007 | ui.updateSongPos = true; | 1029 | bool intMusic(void) // replayer ticker |
| 1008 | ui.updateSongPattern = true; | 1030 | { |
| 1009 | ui.updateCurrPattText = true; | 1031 | // quirk: CIA BPM changes are delayed by one tick in PT, so handle previous tick's BPM change now |
| 1010 | } | 1032 | if (ciaSetBPM != -1) |
| 1011 | } | 1033 | { |
| 1034 | const int32_t newBPM = ciaSetBPM; | ||
| 1035 | modSetTempo(newBPM, false); | ||
| 1036 | ciaSetBPM = -1; | ||
| 1012 | } | 1037 | } |
| 1013 | 1038 | ||
| 1014 | if (editor.isWAVRendering && song->tick == 0) | 1039 | increasePlaybackTimer(); |
| 1015 | editor.rowVisitTable[(modOrder * MOD_ROWS) + song->row] = true; | ||
| 1016 | 1040 | ||
| 1017 | if (!editor.stepPlayEnabled) | 1041 | if (!editor.stepPlayEnabled) |
| 1018 | song->tick++; | 1042 | song->tick++; |
| 1019 | 1043 | ||
| 1020 | if ((uint32_t)song->tick >= (uint32_t)song->speed || editor.stepPlayEnabled) | 1044 | bool readNewNote = false; |
| 1045 | if ((unsigned)song->tick >= (unsigned)song->speed) | ||
| 1021 | { | 1046 | { |
| 1022 | song->tick = 0; | 1047 | song->tick = 0; |
| 1048 | readNewNote = true; | ||
| 1049 | } | ||
| 1023 | 1050 | ||
| 1024 | if (pattDelTime2 == 0) | 1051 | if (readNewNote || editor.stepPlayEnabled) // tick 0 |
| 1052 | { | ||
| 1053 | if (pattDelTime2 == 0) // no pattern delay, time to read note data | ||
| 1025 | { | 1054 | { |
| 1026 | c = song->channels; | 1055 | setCurrRowToVisited(); // for MOD2WAV/PAT2SMP |
| 1027 | for (i = 0; i < AMIGA_VOICES; i++, c++) | 1056 | updateUIPositions(); // update current song positions in UI |
| 1057 | |||
| 1058 | // read note data and trigger voices | ||
| 1059 | moduleChannel_t *c = song->channels; | ||
| 1060 | for (int32_t i = 0; i < AMIGA_VOICES; i++, c++) | ||
| 1028 | { | 1061 | { |
| 1029 | playVoice(c); | 1062 | playVoice(c); |
| 1030 | paulaSetVolume(i, c->n_volume); | 1063 | paulaSetVolume(i, c->n_volume); |
| @@ -1034,23 +1067,18 @@ bool intMusic(void) · 3 unmodified lines | |||
| 1034 | paulaSetLength(i, c->n_replen); | 1067 | paulaSetLength(i, c->n_replen); |
| 1035 | } | 1068 | } |
| 1036 | } | 1069 | } |
| 1037 | else | 1070 | else // pattern delay is on-going |
| 1038 | { | 1071 | { |
| 1039 | c = song->channels; | 1072 | moduleChannel_t *c = song->channels; |
| 1040 | for (i = 0; i < AMIGA_VOICES; i++, c++) | 1073 | for (int32_t i = 0; i < AMIGA_VOICES; i++, c++) |
| 1041 | checkEffects(c); | 1074 | checkEffects(c); |
| 1042 | } | 1075 | } |
| 1043 | 1076 | ||
| 1044 | if (!editor.isWAVRendering && !editor.isSMPRendering) | 1077 | // increase row |
| 1045 | { | ||
| 1046 | song->currRow = song->row; | ||
| 1047 | ui.updatePatternData = true; | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | if (!editor.stepPlayBackwards) | 1078 | if (!editor.stepPlayBackwards) |
| 1051 | { | 1079 | { |
| 1052 | song->row++; | 1080 | song->row++; |
| 1053 | song->rowsCounter++; | 1081 | song->rowsCounter++; // for MOD2WAV's progress bar |
| 1054 | } | 1082 | } |
| 1055 | 1083 | ||
| 1056 | if (pattDelTime > 0) | 1084 | if (pattDelTime > 0) |
| @@ -1059,10 +1087,15 @@ bool intMusic(void) · 2 unmodified lines | |||
| 1059 | pattDelTime = 0; | 1087 | pattDelTime = 0; |
| 1060 | } | 1088 | } |
| 1061 | 1089 | ||
| 1090 | // undo row increase if pattern delay is on-going | ||
| 1062 | if (pattDelTime2 > 0) | 1091 | if (pattDelTime2 > 0) |
| 1063 | { | 1092 | { |
| 1064 | if (--pattDelTime2 > 0) | 1093 | pattDelTime2--; |
| 1094 | if (pattDelTime2 > 0) | ||
| 1095 | { | ||
| 1065 | song->row--; | 1096 | song->row--; |
| 1097 | song->rowsCounter--; // for MOD2WAV's progress bar | ||
| 1098 | } | ||
| 1066 | } | 1099 | } |
| 1067 | 1100 | ||
| 1068 | if (pBreakFlag) | 1101 | if (pBreakFlag) |
| @@ -1072,51 +1105,37 @@ bool intMusic(void) · 3 unmodified lines | |||
| 1072 | pBreakFlag = false; | 1105 | pBreakFlag = false; |
| 1073 | } | 1106 | } |
| 1074 | 1107 | ||
| 1075 | if (editor.blockMarkFlag) | 1108 | // step-play handling |
| 1076 | ui.updateStatusText = true; | ||
| 1077 | |||
| 1078 | if (editor.stepPlayEnabled) | 1109 | if (editor.stepPlayEnabled) |
| 1079 | { | 1110 | { |
| 1080 | doStopIt(true); | 1111 | doStopIt(true); |
| 1081 | 1112 | ||
| 1082 | song->currRow = song->row & 0x3F; | 1113 | song->currRow = song->row & 0x3F; |
| 1083 | ui.updatePatternData = true; | ||
| 1084 | |||
| 1085 | editor.stepPlayEnabled = false; | 1114 | editor.stepPlayEnabled = false; |
| 1086 | editor.stepPlayBackwards = false; | 1115 | editor.stepPlayBackwards = false; |
| 1087 | ui.updatePatternData = true; | ||
| 1088 | 1116 | ||
| 1117 | ui.updatePatternData = true; | ||
| 1089 | return true; | 1118 | return true; |
| 1090 | } | 1119 | } |
| 1091 | 1120 | ||
| 1092 | if (song->row >= MOD_ROWS || posJumpAssert) | 1121 | if (song->row >= MOD_ROWS || posJumpAssert) |
| 1093 | { | ||
| 1094 | if (editor.isSMPRendering) | ||
| 1095 | modHasBeenPlayed = true; | ||
| 1096 | |||
| 1097 | nextPosition(); | 1122 | nextPosition(); |
| 1098 | } | ||
| 1099 | 1123 | ||
| 1100 | if (editor.isWAVRendering && !pattDelTime2 && editor.rowVisitTable[(modOrder * MOD_ROWS) + song->row]) | 1124 | // for pattern block mark feature |
| 1101 | modHasBeenPlayed = true; | 1125 | if (editor.blockMarkFlag) |
| 1126 | ui.updateStatusText = true; | ||
| 1102 | } | 1127 | } |
| 1103 | else | 1128 | else // tick > 0 (handle effects) |
| 1104 | { | 1129 | { |
| 1105 | c = song->channels; | 1130 | moduleChannel_t *c = song->channels; |
| 1106 | for (i = 0; i < AMIGA_VOICES; i++, c++) | 1131 | for (int32_t i = 0; i < AMIGA_VOICES; i++, c++) |
| 1107 | checkEffects(c); | 1132 | checkEffects(c); |
| 1108 | 1133 | ||
| 1109 | if (posJumpAssert) | 1134 | if (posJumpAssert) |
| 1110 | nextPosition(); | 1135 | nextPosition(); |
| 1111 | } | 1136 | } |
| 1112 | 1137 | ||
| 1113 | if ((editor.isSMPRendering || editor.isWAVRendering) && modHasBeenPlayed && song->tick == song->speed-1) | 1138 | return renderEndCheck(); // MOD2WAV/PAT2SMP listens to the return value (true = not done yet) |
| 1114 | { | ||
| 1115 | modHasBeenPlayed = false; | ||
| 1116 | return false; | ||
| 1117 | } | ||
| 1118 | |||
| 1119 | return true; | ||
| 1120 | } | 1139 | } |
| 1121 | 1140 | ||
| 1122 | void modSetPattern(uint8_t pattern) | 1141 | void modSetPattern(uint8_t pattern) |
| @@ -1179,7 +1198,7 @@ void modSetPos(int16_t order, int16_t row) · 56 unmodified lines | |||
| 1179 | 1198 | ||
| 1180 | void modSetTempo(int32_t bpm, bool doLockAudio) | 1199 | void modSetTempo(int32_t bpm, bool doLockAudio) |
| 1181 | { | 1200 | { |
| 1182 | if (bpm < 32) | 1201 | if (bpm < 32 || bpm > 255) |
| 1183 | return; | 1202 | return; |
| 1184 | 1203 | ||
| 1185 | const bool audioWasntLocked = !audio.locked; | 1204 | const bool audioWasntLocked = !audio.locked; |
| @@ -1195,20 +1214,20 @@ void modSetTempo(int32_t bpm, bool doLockAudio) · 9 unmodified lines | |||
| 1195 | 1214 | ||
| 1196 | bpm -= 32; // 32..255 -> 0..223 | 1215 | bpm -= 32; // 32..255 -> 0..223 |
| 1197 | 1216 | ||
| 1198 | double dSamplesPerTick; | 1217 | int64_t samplesPerTick64; |
| 1199 | if (editor.isSMPRendering) | 1218 | if (editor.isSMPRendering) |
| 1200 | dSamplesPerTick = editor.pat2SmpHQ ? audio.bpmTable28kHz[bpm] : audio.bpmTable22kHz[bpm]; | 1219 | samplesPerTick64 = editor.pat2SmpHQ ? audio.bpmTable28kHz[bpm] : audio.bpmTable22kHz[bpm]; |
| 1201 | else if (editor.isWAVRendering) | 1220 | else if (editor.isWAVRendering) |
| 1202 | dSamplesPerTick = audio.bpmTableMod2Wav[bpm]; | 1221 | samplesPerTick64 = audio.bpmTableMod2Wav[bpm]; |
| 1203 | else | 1222 | else |
| 1204 | dSamplesPerTick = audio.bpmTable[bpm]; | 1223 | samplesPerTick64 = audio.bpmTable[bpm]; |
| 1205 | 1224 | ||
| 1206 | audio.dSamplesPerTick = dSamplesPerTick; | 1225 | audio.samplesPerTick64 = samplesPerTick64; |
| 1207 | 1226 | ||
| 1208 | // calculate tick time length for audio/video sync timestamp | 1227 | // calculate tick time length for audio/video sync timestamp |
| 1209 | const uint64_t tickTimeLen64 = audio.tickLengthTable[bpm]; | 1228 | const uint64_t tickTimeLen64 = audio.tickLengthTable[bpm]; |
| 1210 | const uint32_t tickTimeLen = tickTimeLen64 >> 32; | 1229 | const uint32_t tickTimeLen = tickTimeLen64 >> 32; |
| 1211 | const uint32_t tickTimeLenFrac = tickTimeLen64 & 0xFFFFFFFF; | 1230 | const uint32_t tickTimeLenFrac = (uint32_t)tickTimeLen64; |
| 1212 | 1231 | ||
| 1213 | setSyncTickTimeLen(tickTimeLen, tickTimeLenFrac); | 1232 | setSyncTickTimeLen(tickTimeLen, tickTimeLenFrac); |
| 1214 | 1233 | ||
| @@ -1238,7 +1257,7 @@ void modStop(void) · 23 unmodified lines | |||
| 1238 | pattDelTime2 = 0; | 1257 | pattDelTime2 = 0; |
| 1239 | pBreakPosition = 0; | 1258 | pBreakPosition = 0; |
| 1240 | posJumpAssert = false; | 1259 | posJumpAssert = false; |
| 1241 | modHasBeenPlayed = true; | 1260 | modRenderDone = true; |
| 1242 | } | 1261 | } |
| 1243 | 1262 | ||
| 1244 | void playPattern(int8_t startRow) | 1263 | void playPattern(int8_t startRow) |
| @@ -1246,7 +1265,7 @@ void playPattern(int8_t startRow) · 1 unmodified line | |||
| 1246 | if (!editor.stepPlayEnabled) | 1265 | if (!editor.stepPlayEnabled) |
| 1247 | pointerSetMode(POINTER_MODE_PLAY, DO_CARRY); | 1266 | pointerSetMode(POINTER_MODE_PLAY, DO_CARRY); |
| 1248 | 1267 | ||
| 1249 | audio.dTickSampleCounter = 0.0; // zero tick sample counter so that it will instantly initiate a tick | 1268 | audio.tickSampleCounter64 = 0; // zero tick sample counter so that it will instantly initiate a tick |
| 1250 | song->currRow = song->row = startRow & 0x3F; | 1269 | song->currRow = song->row = startRow & 0x3F; |
| 1251 | song->tick = song->speed; | 1270 | song->tick = song->speed; |
| 1252 | ciaSetBPM = -1; | 1271 | ciaSetBPM = -1; |
| @@ -1291,7 +1310,7 @@ void modPlay(int16_t patt, int16_t order, int8_t row) · 38 unmodified lines | |||
| 1291 | 1310 | ||
| 1292 | doStopIt(false); | 1311 | doStopIt(false); |
| 1293 | turnOffVoices(); | 1312 | turnOffVoices(); |
| 1294 | audio.dTickSampleCounter = 0.0; // zero tick sample counter so that it will instantly initiate a tick | 1313 | audio.tickSampleCounter64 = 0; // zero tick sample counter so that it will instantly initiate a tick |
| 1295 | ciaSetBPM = -1; | 1314 | ciaSetBPM = -1; |
| 1296 | 1315 | ||
| 1297 | if (row != -1) | 1316 | if (row != -1) |
| @@ -1343,8 +1362,8 @@ void modPlay(int16_t patt, int16_t order, int8_t row) · 45 unmodified lines | |||
| 1343 | editor.playMode = oldPlayMode; | 1362 | editor.playMode = oldPlayMode; |
| 1344 | editor.currMode = oldMode; | 1363 | editor.currMode = oldMode; |
| 1345 | 1364 | ||
| 1346 | song->tick = song->speed; | 1365 | song->tick = song->speed-1; |
| 1347 | modHasBeenPlayed = false; | 1366 | modRenderDone = false; |
| 1348 | editor.songPlaying = true; | 1367 | editor.songPlaying = true; |
| 1349 | editor.didQuantize = false; | 1368 | editor.didQuantize = false; |
| 1350 | 1369 | ||
| @@ -1569,6 +1588,6 @@ void resetSong(void) // only call this after storeTempVariables() has been calle · 218 unmodified lines | |||
| 1569 | doStopIt(true); | 1588 | doStopIt(true); |
| 1570 | 1589 | ||
| 1571 | song->tick = 0; | 1590 | song->tick = 0; |
| 1572 | modHasBeenPlayed = false; | 1591 | modRenderDone = false; |
| 1573 | audio.forceMixerOff = false; | 1592 | audio.forceMixerOff = false; |
| 1574 | } | 1593 | } |