From 6f95303feaf1801e9a814dfc143e2cb8f6bbff3e Mon Sep 17 00:00:00 2001
From: Jeremy Clarke
Date: Sun, 14 Jun 2020 03:20:42 +0100
Subject: [PATCH 01/30] fill_dword(): Replace memset() with simple loop
memset() sets bytes, we need to set dwords!
The compiler will optimise this nicely, so no need for optimisations
or assembly in the code.
---
src/ppui/fastfill.h | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/ppui/fastfill.h b/src/ppui/fastfill.h
index 1517c5a6..7aec92dd 100644
--- a/src/ppui/fastfill.h
+++ b/src/ppui/fastfill.h
@@ -28,11 +28,10 @@
*
*/
-#include
-
static inline void fill_dword(pp_uint32* buff, pp_uint32 dw, pp_uint32 len)
{
- memset(buff, dw, len);
+ while (len--)
+ *(buff++) = dw;
}
static inline void fill_dword_vertical(pp_uint32* buff, pp_uint32 dw, pp_uint32 len, pp_uint32 pitch)
From e0652ecca58ff2d4fc89b9eaec5ec3cd015bea91 Mon Sep 17 00:00:00 2001
From: Christopher O'Neill
Date: Fri, 9 Oct 2020 23:44:21 +0100
Subject: [PATCH 02/30] Fix #218: Inverted samples during signed-unsigned
conversion
---
src/milkyplay/SampleLoaderWAV.cpp | 2 +-
src/milkyplay/XModule.cpp | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/milkyplay/SampleLoaderWAV.cpp b/src/milkyplay/SampleLoaderWAV.cpp
index abcab22c..2a06c1f0 100644
--- a/src/milkyplay/SampleLoaderWAV.cpp
+++ b/src/milkyplay/SampleLoaderWAV.cpp
@@ -689,7 +689,7 @@ mp_sint32 SampleLoaderWAV::saveSample(const SYSCHAR* fileName, mp_sint32 index)
mp_ubyte* dstPtr = new mp_ubyte[smp->samplen];
mp_ubyte* dst = dstPtr;
for (mp_uint32 i = 0; i < smp->samplen; i++)
- *dstPtr++ = ((mp_sbyte)smp->getSampleValue(i))^127;
+ *dstPtr++ = ((mp_sbyte)smp->getSampleValue(i))^128;
f.write(dst, 1, smp->samplen);
delete[] dst;
}
diff --git a/src/milkyplay/XModule.cpp b/src/milkyplay/XModule.cpp
index 0315f0fb..e3fd719c 100644
--- a/src/milkyplay/XModule.cpp
+++ b/src/milkyplay/XModule.cpp
@@ -1519,7 +1519,7 @@ bool XModule::loadSample(XMFileBase& f,void* buffer,mp_uint32 size,mp_uint32 len
if (flags & ST_UNSIGNED)
{
for (i = 0; i < length; i++)
- dstPtr[i] = (dstPtr[i]^32767);
+ dstPtr[i] = (dstPtr[i]^32768);
}
}
// 8 bit sample
@@ -1539,7 +1539,7 @@ bool XModule::loadSample(XMFileBase& f,void* buffer,mp_uint32 size,mp_uint32 len
if (flags & ST_UNSIGNED)
{
for (mp_uint32 i = 0; i < length; i++)
- smpPtr[i] ^= 127;
+ smpPtr[i] ^= 128;
}
}
From bb785e2d732219fce02a79f70e7b3460ff35df02 Mon Sep 17 00:00:00 2001
From: Christopher O'Neill
Date: Sat, 10 Oct 2020 00:06:21 +0100
Subject: [PATCH 03/30] Fix #217: Difficult to resize sample selection
Don't require ctrl/cmd modifier.
Increase resizing zone to minimum 4 pixels.
---
src/tracker/SampleEditorControl.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/tracker/SampleEditorControl.cpp b/src/tracker/SampleEditorControl.cpp
index 16f7c1d7..42c123bd 100644
--- a/src/tracker/SampleEditorControl.cpp
+++ b/src/tracker/SampleEditorControl.cpp
@@ -1097,16 +1097,16 @@ pp_int32 SampleEditorControl::dispatchEvent(PPEvent* event)
pp_int32 x2 = (pp_int32)((sEnd)/xScale)-startPos + location.x + 2;
pp_int32 minDist = (scrollDist>>4);
- if (minDist < 1) minDist = 1;
+ if (minDist < 4) minDist = 4;
pp_int32 sDist1 = abs(x1 - p->x);
pp_int32 sDist2 = abs(p->x - x2);
- if (sDist1 >= 0 && sDist1 <= minDist && (::getKeyModifier() == KeyModifierCTRL))
+ if (sDist1 >= 0 && sDist1 <= minDist)
{
type = MouseCursorTypeResizeLeft;
}
- else if (sDist2 >= 0 && sDist2 <= minDist && (::getKeyModifier() == KeyModifierCTRL))
+ else if (sDist2 >= 0 && sDist2 <= minDist)
{
type = MouseCursorTypeResizeRight;
}
From 216f802e493345f48ff4d3efd4fa6e1acbffc363 Mon Sep 17 00:00:00 2001
From: Cong
Date: Wed, 28 Oct 2020 23:24:16 +1100
Subject: [PATCH 04/30] Fix windows build for non-MFC
---
src/tracker/win32/Win32_resources.rc | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/tracker/win32/Win32_resources.rc b/src/tracker/win32/Win32_resources.rc
index bfc5ef79..57d0ec37 100644
--- a/src/tracker/win32/Win32_resources.rc
+++ b/src/tracker/win32/Win32_resources.rc
@@ -7,7 +7,11 @@
//
// Generated from the TEXTINCLUDE 2 resource.
//
-#include "afxres.h"
+#include "windows.h"
+
+#ifndef IDC_STATIC
+#define IDC_STATIC -1
+#endif
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
From 52e6a42d1f03c5fcb29b81f8cbdef8a9de9c4f55 Mon Sep 17 00:00:00 2001
From: Christopher O'Neill
Date: Tue, 1 Dec 2020 21:50:48 +0000
Subject: [PATCH 05/30] Update zziplib submodule
---
src/submodules/zziplib | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/submodules/zziplib b/src/submodules/zziplib
index 9d82e19c..3921fc43 160000
--- a/src/submodules/zziplib
+++ b/src/submodules/zziplib
@@ -1 +1 @@
-Subproject commit 9d82e19c7f654722f9e37deaa9eb91c25ad544ec
+Subproject commit 3921fc43bca7283f126bfb2e47ec7e7e24b5a5ea
From ac29d03c21db299b83010a208a4f36d8d9b531a1 Mon Sep 17 00:00:00 2001
From: Christopher O'Neill
Date: Wed, 9 Dec 2020 22:31:34 +0000
Subject: [PATCH 06/30] Update CI app keys
---
.travis.yml | 2 +-
appveyor.yml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 0092802e..acf05103 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -37,7 +37,7 @@ matrix:
deploy:
provider: releases
api_key:
- secure: C2RWNFq25CsR1OdJkguSBU2iYvi40UUTlSe2AZUWKB1qE4a0tERlvOj80ez2j72EuO0UdEzschQ+6jnAQG/Osz3TGYCjCOMGRP/09Am5TdVals3gcMC+hqrWuTMycmjh4qElh2Gu2cUXzrWM7K8kSvRhX7x5jE122K0geeiJeONRj9vfSnBeuwBFFJXQacXJ/vCBKzRn/S67FKBIn9WIvzh/ldlbAgdiIqQBV/8uQInNGwSYGlgq+fm6Pm18D0H2DILj0OT4atyxu+dGhSXLLqCHl/U0MfZXeNTfUKCvtKxen/vK9FlEJpiBG/+mZ7GwwQkoPPcr5ywsXuF8BtcncLFy8DS05BACVDQ8UYiqB3WUlsEEgJus8Uk64Gt0zvF9j6rH9NhWEBWicVvC5NhsNXzQYJjEkP3gjdGPebLqTAtKVMQtgm5Cz3gtKpVL+U/9E/xsijZ8M/X6ln/l1+oJyat9v6OGLyMLRRnf7a92j4SxBE7iqTrK07FF6stWyCAvSaWuRfwxOjhau3aA7KEWFpdizFsDzygXrGs0vvzcUOz6MMnS2lfWb3kI7DQiSwXQe8q2ZMnpQBA5C5oHXesaoAm6nP6JT2SS0GB7zimIQCDn61T6ZLFfHfDs245LmEr9Hp41AefF8bIYFBGub+xJDn8o4Q2TRJyOM2CXylUZ9SY=
+ secure: "tuoM4T5yYeqtmqjK5m9+zsVkLYqfwD/Lf5nyXPaONDRvgo7lh46OvNXPcHCu4QK6j80PmmzvhK/B0L836puEQpcaKsksdO8WTp3Lw4wPiidOC30rw+OR9jDnJzbPmv+PXxmqENIDUccLhDKpB9IGfosgcaxERvlvJZ44XlHnmgIPhXrKlESDnrV44snFJ/JkjlcNJr55nOdbCHTEUrW3J+kkYqjA3kyMW9/rS+iWx2PRLYKUBQDh+7U6frEjI8E4Ygpr5L6Cm7T2SuOWJhp+8tu9fEDZtfCngrU8ZTYclgAIqCyh1o6BU9ljcpU26CBcDYnNcqeFV8a7GcK/D32ix26rMvff9Ngei2uWs9ZYTGSSSC8CGnVpfPxi2ZSN15/pvqxhwr6I5Z/V/RX5+ZjdAyU6IIHo7GGt2y/e/zkoxfOBeiv1EV+gPZPbKafKkDX1Xghxp8t64qXynMctKiM3KCbcLRi+Z0Srym+lrIHYY2jo/cWk88VK6xGjCk5SDtQlkJgxN72Jbyy4kWMPIa7aOzrSA9WbUXG26osw38sNIGe5Rs1pErvSKMV3slLWBBDtzvh1Z/zUO34W6FyKilBwoE3zTvE/lnAZtBWyk0QCNxJvLReqNGZE53Zk8VuGmBQ9S9aIXqm21CSuEYVpvhogXAj82ePNH9Dy3B4A0KIqUBY="
skip_cleanup: true
file_glob: true
file: build/milkytracker-*
diff --git a/appveyor.yml b/appveyor.yml
index bc2d2359..69a5837e 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -32,7 +32,7 @@ deploy:
description: Release $(appveyor_repo_tag_name)
provider: GitHub
auth_token:
- secure: XtZUHo/SWVXr89Z4YQYylRE8lDQue+JwuaQdqEG/P57GePwPJipKzlPSxp8qOFiG
+ secure: k4eMw7MSycoyZwL8VfdAS8ejNXnwhFQ0KOVpif3IqyQDUrOGeGRyCHXm7FsD4kjb
artifact: /milkytracker.*\.zip/
prerelease: false
overwrite: true
From 5ffac52ee67560924ecf046d03c7736a8fe21e3e Mon Sep 17 00:00:00 2001
From: Christopher O'Neill
Date: Wed, 9 Dec 2020 19:59:15 +0000
Subject: [PATCH 07/30] Release v1.03
---
CMakeLists.txt | 2 +-
ChangeLog.md | 23 +++
docs/ChangeLog.html | 349 ++++++++++++++++++++++++++++++-----------
docs/MilkyTracker.html | 2 +-
docs/TiTAN.nfo | 4 +-
5 files changed, 287 insertions(+), 93 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9318dbce..4bdecf1b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -52,7 +52,7 @@ list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
# Version number in format X.YY.ZZ
set(VER_X 1)
-set(VER_YY 02)
+set(VER_YY 03)
set(VER_ZZ 00)
set(VER_FULL "${VER_X}.${VER_YY}.${VER_ZZ}")
diff --git a/ChangeLog.md b/ChangeLog.md
index 622e7b31..ab802bef 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,28 @@
# MilkyTracker ChangeLog
+## 12/12/2020 (v1.03):
+
+### What's new:
+* Improved FT2 accuracy
+* Alt-Backspace alternative for insert keybindings
+* Improved mousewheel / touchpad scrolling for Windows/OSX/SDL2
+* Option to invert mousewheel for pattern editor
+* New flanger effect
+* Allow quarter periods in sample generator
+* Click and drag to move selection in pattern editor
+* More intuitive cutting/pasting of partial FX commands
+* Allow selections by clicking outside the pattern bounds
+* Easier and more intuitive sample selection resizing
+
+### Bugs fixed:
+* Various compatibility fixes
+* Jam channels stop working after applying settings
+* Improper WAV chunk parsing for odd sizes
+* Multiple heap & buffer overflow vulnerabilities
+* MacOS compatibility
+* Inverted samoples during signed to unsigned conversion
+* ...and more, see git commit history for details
+
## 24/02/2018 (v1.02):
### What's new:
diff --git a/docs/ChangeLog.html b/docs/ChangeLog.html
index db4385c5..118f6fa1 100644
--- a/docs/ChangeLog.html
+++ b/docs/ChangeLog.html
@@ -1,21 +1,186 @@
-
-
+
+
-
-
+
-
-
+
+ ChangeLog
+
+
MilkyTracker ChangeLog
-24/02/2018 (v1.02)
-What's new:
+12/12/2020 (v1.03):
+What’s new:
+
+- Improved FT2 accuracy
+- Alt-Backspace alternative for insert keybindings
+- Improved mousewheel / touchpad scrolling for Windows/OSX/SDL2
+- Option to invert mousewheel for pattern editor
+- New flanger effect
+- Allow quarter periods in sample generator
+- Click and drag to move selection in pattern editor
+- More intuitive cutting/pasting of partial FX commands
+- Allow selections by clicking outside the pattern bounds
+- Easier and more intuitive sample selection resizing
+
+Bugs fixed:
+
+- Various compatibility fixes
+- Jam channels stop working after applying settings
+- Improper WAV chunk parsing for odd sizes
+- Multiple heap & buffer overflow vulnerabilities
+- MacOS compatibility
+- Inverted samoples during signed to unsigned conversion
+- …and more, see git commit history for details
+
+24/02/2018 (v1.02):
+What’s new:
- 99 channel MOD support
- Alternative keybindings for inc/dec Row Insert
-Bugs fixed:
+Bugs fixed:
- Fix Lxx command to also set panning envelope if volume sustain point is enabled.
- Infinite loop when processing 8 digit hexadecimal numbers
@@ -25,39 +190,45 @@ Bugs fixed:
- Various loader memory corruption bugs
29/07/2017 (v1.01):
-What's new:
+What’s new:
- Channel limit increased to 128 channels
-- New sample editor filters:
+- New sample editor filters:
+
- Phase modulation
- AM & FM modulation
- Selective equaliser
+
- OSX: Insert key mapped to F13
- GUI: Clickable checkbox labels
- GNU: Use GNUInstallDirs
-Bugs fixed:
+Bugs fixed:
- Errant characters inserts when selecting patterns using ALT + cursor keys
- Windows: Window size now takes scale factor into consideration
- Build: Default value used for PATH_MAX if not set (for GNU/Hurd)
-- Instrument editor:
+- Instrument editor:
+
- Prevent point inserts overlapping existing points
- Reset cursor when changing presets or pasting envelopes
+
- PT3 octave limit not reset when switching playback mode back to FT2
-- Sample editor:
+- Sample editor:
+
- Invert function now works correctly
- Equaliser constants tweaked
- No longer crashes when generating silence with no selection active
- Noise generator on 64-bit systems
+
- OSX: Core audio sample-rate switching
- GUS frequencies lower than lowest note
- Off-by-semitone issue in GUS patch loader
-- Corrupt display with window sizes that aren't multiples of 4
+- Corrupt display with window sizes that aren’t multiples of 4
- Windows: Window position gradually moving off-screen on restarts
11/03/2017 (v1.00.00):
-What's new:
+What’s new:
- 5 new customisable colours
- X-Y mouse scrolling support
@@ -84,12 +255,12 @@ What's new:
- Mouse middle-click to solo channel
- ..and more, see (commit log) for details
-Bugs Fixed:
+Bugs Fixed:
- Segfault when loading <4 byte samples
- Samples incorrectly offset when exporting .mod files
- libalsa linker errors on some systems
-- .mod export: Don't zero first word of looping samples
+- .mod export: Don’t zero first word of looping samples
- Decompress files despite possible mis-identification
- Windows: Determine window dimensions based on client area
- Update view if paste changes pattern length
@@ -106,26 +277,26 @@ Bugs Fixed:
- Sample/Ins editor listboxes scrolled right in certain circumstances
07/11/13 (v0.90.86):
-Whats New:
+Whats New:
-- Unsafe notes now shown in red when "PT 3 octave limit" option enabled
+- Unsafe notes now shown in red when “PT 3 octave limit” option enabled
- Haiku port (thanks jua)
- Additional FT2 shortcuts (forum post)
- Android port (thanks guillaum1)
- Jack driver now connects to first available physical device
- MilkyTracker source code now hosted on GitHub
-Bugs Fixed:
+Bugs Fixed:
-- Loss of data when using 'backward' sample filter (forum post)
+- Loss of data when using ‘backward’ sample filter (forum post)
- Warning displayed when exporting .mod files with samples over 64k (forum post)
- Default panning settings applied when adding channels (forum post)
- One-shot looping now works correctly (forum post)
- First 2 bytes of samples cleared to zero when exporting to MOD (Amiga compatibility)
- FT2 weirdness emulated when using the arpreggio command (thanks Saga_Musix)
-- In live mode, don't switch from pattern to song play when selecting a new pattern from the order list
+- In live mode, don’t switch from pattern to song play when selecting a new pattern from the order list
- Check config file is open for writing before attempting to save to it.
-- Don't assume BACKUPxx.XM has been saved
+- Don’t assume BACKUPxx.XM has been saved
- Crash when storing colour presets (forum post)
- Segfault when loading XMs with zero-length loop (forum post)
- Emulate FT2 behaviour for arpregios when speed>18
@@ -134,7 +305,7 @@ Bugs Fixed:
- Various build warnings and errors
01/01/10 (v0.90.85):
-Whats New:
+Whats New:
- Ability to move dialogs.
- Keyboard shortcut Shift-U (unmute all).
@@ -147,7 +318,7 @@ Whats New:
- New font: IDC-Harmonica (12x12)
- New font: IDC-MicroKnight (12x12)
- Ability to detect desktop display resolution.
-- Added '1' as note-off key in MilkyTracker mode.
+- Added ‘1’ as note-off key in MilkyTracker mode.
- Ability to adjust screen magnification factor.
- Milkyplay license changed from GPL to BSD (MilkyTracker remains GPL).
- Working close button in OSX.
@@ -155,10 +326,10 @@ Whats New:
- Improved constants for 10 band EQ.
- New font: Topaz 1.3 & Topaz 2.0 (8x8)
-Bugs Fixed:
+Bugs Fixed:
- (Unix) JACK client thread gets zombified causing playback to block.
-- Crash when using the '-orientation ROTATE90CW' switch on SDL versions.
+- Crash when using the ‘-orientation ROTATE90CW’ switch on SDL versions.
- Screen input lock after showing a system message.
- Bug in xm loader for old xm variant causing 8 bit samples to not load correctly.
- Added FT2 note range clipping to live playback.
@@ -173,22 +344,22 @@ Bugs Fixed:
- Mouse repeat bug on SDL version.
- Small bug in SDL Midi code.
- Little bug in the advanced edit panel (limit of subsequent channels).
-- Undefined .XM sample type 0x3 causes sample loop to appear "one shot".
+- Undefined .XM sample type 0x3 causes sample loop to appear “one shot”.
- Instrument vibrato depth value gets doubled when copying instruments.
- PSM loader can now store sub-song information correctly.
- XM loading problems with 16-bit odd sample sizes.
-- Support for callbacks on systems that don't use C style function calls (ie, OS/2)
-- Instrument fadeout value initially doesn't match the slider position when adding new instruments to a loaded module.
-- Selecting an instrument with the numpad doesn't update the instrument or sample editors with the selected instrument, but with the previous one.
+- Support for callbacks on systems that don’t use C style function calls (ie, OS/2)
+- Instrument fadeout value initially doesn’t match the slider position when adding new instruments to a loaded module.
+- Selecting an instrument with the numpad doesn’t update the instrument or sample editors with the selected instrument, but with the previous one.
- Bug in auto-detection of playmode for XM modules (panning was not set).
- Set envelope position after sustain points.
- Ignored lower 3 bits of finetune for more accurate FT2 playback
- Crash while loading sample during playback
- Screen refresh issues
- Problem with French keyboard layout.
-- The current pattern length under the song title isn't updated when the mod is zapped.
-- Shrinking a 2-row pattern isn't possible.
-- Undoing an action doesn't register as a change.
+- The current pattern length under the song title isn’t updated when the mod is zapped.
+- Shrinking a 2-row pattern isn’t possible.
+- Undoing an action doesn’t register as a change.
- A slight graphical bug occurs when using the seq and cln buttons on the FEth pattern of a mod.
- Crash when converting sample resolution.
- Freeze on exit when using DirectSound on Windows 7.
@@ -196,8 +367,8 @@ Bugs Fixed:
04/13/08 (v0.90.80):
Important note:
-This version of MilkyTracker will update your current configuration file in a way that it's no longer usable with older versions. It is recommended that you keep a backup of your configuration file. On Windows the configuration is stored in the application folder. When using MilkyTracker on OS X or Unix systems the configuration is stored in your home directory in a file called .milkytracker_config.
-What's New:
+This version of MilkyTracker will update your current configuration file in a way that it’s no longer usable with older versions. It is recommended that you keep a backup of your configuration file. On Windows the configuration is stored in the application folder. When using MilkyTracker on OS X or Unix systems the configuration is stored in your home directory in a file called .milkytracker_config.
+What’s New:
05/27/05:
@@ -504,9 +675,9 @@ 05/22/05:
05/14/05:
-- Fixed some "focus" issues
-- Divided "save" option into "save" and "save as…"
-- Added value interpolation (available in the "Advanced Editor")
+- Fixed some “focus” issues
+- Divided “save” option into “save” and “save as…”
+- Added value interpolation (available in the “Advanced Editor”)
- Fixed an instrument load/save issue
- PocketPC: Fixed bug, which prevented the progress bar from disappearing when saving instruments/samples.
@@ -529,7 +700,7 @@ 04/29/05:
04/25/05:
-- First "official" PocketPC pre-release.
+- First “official” PocketPC pre-release.
diff --git a/docs/MilkyTracker.html b/docs/MilkyTracker.html
index a4511838..0ae3941a 100644
--- a/docs/MilkyTracker.html
+++ b/docs/MilkyTracker.html
@@ -1,7 +1,7 @@
- MilkyTracker Manual v1.02
+ MilkyTracker Manual v1.03
- MilkyTracker Manual v1.0.1
+ MilkyTracker Manual v1.03
Hello and welcome to MilkyTracker, an open source multi-platform Fasttracker II compatible music tracker program. This document holds a lot of valuable information about the tracker but it's not a tracking manual. If you want to learn more about tracking and how it's done, the Internet is your friend. We host some resources on MilkyTracker.titandemo.org as well.
@@ -980,7 +980,7 @@ Pattern editor:
Caps-Lock | Enter key-off (Windows only) |
- 1 | Enter key-off (OS X only) |
+ 1 | Enter key-off |
Del | Delete note or volume column at cursor |
diff --git a/src/tracker/PatternEditorControlKeyboard.cpp b/src/tracker/PatternEditorControlKeyboard.cpp
index 81f55846..db7b55c4 100644
--- a/src/tracker/PatternEditorControlKeyboard.cpp
+++ b/src/tracker/PatternEditorControlKeyboard.cpp
@@ -540,9 +540,7 @@ pp_int32 PatternEditorControl::ScanCodeToNote(pp_int16 scanCode)
// CAPS-lock
case SC_CAPSLOCK:
-#ifndef WIN32
case SC_1:
-#endif
return PatternTools::getNoteOffNote();
case SC_SMALLERGREATER:
From be016986168a4d03b8d160303fa61296070a6e2c Mon Sep 17 00:00:00 2001
From: Christopher O'Neill
Date: Thu, 31 Dec 2020 18:34:11 +0000
Subject: [PATCH 11/30] Fix #96: Alternative keybinding for Insert in FT2 mode
Alt-Backspace -> insert row on current track only
Shift-Alt-Backspace -> Insert row on all tracks
---
docs/MilkyTracker.html | 10 ++++++++--
src/tracker/PatternEditorControlKeyboard.cpp | 2 ++
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/docs/MilkyTracker.html b/docs/MilkyTracker.html
index be013076..38a0ca9f 100644
--- a/docs/MilkyTracker.html
+++ b/docs/MilkyTracker.html
@@ -703,10 +703,10 @@ Pattern Editor:
Shift-Insert | Insert row at cursor position |
- Alt-Backspace | Insert space on current track at cursor position |
+ Alt-Backspace | Insert space on current track at cursor position (alternative for keyboards with no Insert key) |
- Shift-Alt-Backspace | Insert row at cursor position |
+ Shift-Alt-Backspace | Insert row at cursor position (alternative for keyboards with no Insert key) |
Backspace | Delete previous note |
@@ -1000,6 +1000,12 @@ Pattern editor:
Shift-Ins | Insert row at cursor position (shift-F13 on mac) |
+
+ Alt-Backspace | Insert space on current track at cursor position (alternative for keyboards with no Insert key) |
+
+
+ Shift-Alt-Backspace | Insert row at cursor position (alternative for keyboards with no Insert key) |
+
Backspace | Delete previous note |
diff --git a/src/tracker/PatternEditorControlKeyboard.cpp b/src/tracker/PatternEditorControlKeyboard.cpp
index db7b55c4..3e8d60fe 100644
--- a/src/tracker/PatternEditorControlKeyboard.cpp
+++ b/src/tracker/PatternEditorControlKeyboard.cpp
@@ -108,6 +108,8 @@ void PatternEditorControl::initKeyBindings()
eventKeyDownBindingsFastTracker->addBinding(VK_INSERT, 0, &PatternEditorControl::eventKeyDownBinding_InsertNote);
eventKeyDownBindingsFastTracker->addBinding(VK_INSERT, KeyModifierSHIFT, &PatternEditorControl::eventKeyDownBinding_InsertLine);
+ eventKeyDownBindingsFastTracker->addBinding(VK_BACK, KeyModifierALT, &PatternEditorControl::eventKeyDownBinding_InsertNote);
+ eventKeyDownBindingsFastTracker->addBinding(VK_BACK, KeyModifierALT | KeyModifierSHIFT, &PatternEditorControl::eventKeyDownBinding_InsertLine);
eventKeyDownBindingsFastTracker->addBinding(VK_BACK, 0, &PatternEditorControl::eventKeyDownBinding_DeleteNoteSlot);
eventKeyDownBindingsFastTracker->addBinding(VK_BACK, KeyModifierSHIFT, &PatternEditorControl::eventKeyDownBinding_DeleteLine);
From 9f19025cb7922f177419bbec64d446d03ac4fda8 Mon Sep 17 00:00:00 2001
From: Johannes Schultz
Date: Sat, 29 May 2021 23:30:56 +0200
Subject: [PATCH 12/30] Fix various inaccuracies in (commented-out) AMF DSMI
loader
---
src/milkyplay/LoaderAMF.cpp | 52 +++++++++++++++++++++++++------------
1 file changed, 36 insertions(+), 16 deletions(-)
diff --git a/src/milkyplay/LoaderAMF.cpp b/src/milkyplay/LoaderAMF.cpp
index eabe830a..763ae5f5 100644
--- a/src/milkyplay/LoaderAMF.cpp
+++ b/src/milkyplay/LoaderAMF.cpp
@@ -225,8 +225,10 @@ const char* LoaderAMF_2::identifyModule(const mp_ubyte* buffer)
if (!memcmp(buffer,"AMF", 3))
{
// check for version
- if (buffer[3] < 0xA ||
- buffer[3] > 0xE)
+ if (buffer[3] < 0x8 &&
+ buffer[3] != 0x1)
+ return NULL;
+ if (buffer[3] > 0xE)
return NULL;
return "AMF_2";
@@ -278,7 +280,14 @@ mp_sint32 LoaderAMF_2::load(XMFileBase& f, XModule* module)
mp_uword numTracks = f.readWord();
- header->channum = f.readByte();
+ if (ver >= 9)
+ {
+ header->channum = f.readByte();
+ }
+ else
+ {
+ header->channum = 4;
+ }
mp_sint32 channelRemap[16];
@@ -287,7 +296,7 @@ mp_sint32 LoaderAMF_2::load(XMFileBase& f, XModule* module)
mp_ubyte panpos[32];
f.read(panpos, 1, (ver >= 13) ? 32 : 16);
}
- else
+ else if (ver >= 9)
{
for (mp_sint32 i = 0; i < 16; i++)
channelRemap[i] = f.readByte();
@@ -353,7 +362,7 @@ mp_sint32 LoaderAMF_2::load(XMFileBase& f, XModule* module)
else
{
loopstart = f.readWord();
- loopend = length;
+ loopend = f.readWord();
}
if (type)
@@ -407,7 +416,12 @@ mp_sint32 LoaderAMF_2::load(XMFileBase& f, XModule* module)
mp_sbyte arg;
tracksize = f.readWord();
- tracksize+=((mp_sint32)f.readByte()) << 16;
+ f.readByte(); // track type
+
+ if (tracksize && ver == 1)
+ {
+ tracksize++;
+ }
if (tracksize)
while(tracksize--)
@@ -535,9 +549,9 @@ mp_sint32 LoaderAMF_2::load(XMFileBase& f, XModule* module)
nEff = 0x1C;
nOp = op;
break;
-
+
// Volume slide
- case 2:
+ case 2:
nEff = 0x0A;
if (op)
{
@@ -547,7 +561,7 @@ mp_sint32 LoaderAMF_2::load(XMFileBase& f, XModule* module)
nOp = (-op)&0xf;
}
break;
-
+
// set volume
case 0x03:
nEff = 0x0C;
@@ -593,7 +607,7 @@ mp_sint32 LoaderAMF_2::load(XMFileBase& f, XModule* module)
break;
// Porta + Volume slide
- case 0xA:
+ case 0xA:
nEff = 0x05;
if (op)
{
@@ -605,7 +619,7 @@ mp_sint32 LoaderAMF_2::load(XMFileBase& f, XModule* module)
break;
// Vibrato + Volume slide
- case 0xB:
+ case 0xB:
nEff = 0x06;
if (op)
{
@@ -641,8 +655,8 @@ mp_sint32 LoaderAMF_2::load(XMFileBase& f, XModule* module)
break;
// Fine Volume slide
- case 0x11:
- if (op)
+ case 0x11:
+ if (op)
{
if (op>=0)
{
@@ -658,7 +672,7 @@ mp_sint32 LoaderAMF_2::load(XMFileBase& f, XModule* module)
break;
// Fine Porta
- case 0x12:
+ case 0x12:
if (op)
{
if (op>=0)
@@ -1264,10 +1278,16 @@ mp_sint32 LoaderAMF_2::load(XMFileBase& f, XModule* module)
// Set panning
case 0x17:
- if (op > 64)
+ if (op == 100)
{
+ // surround
nEff = 0x08;
- nOp = XModule::vol64to255(op);
+ nOp = 0x80;
+ }
+ else
+ {
+ nEff = 0x08;
+ nOp = XModule::vol128to255(op + 64);
}
break;
}
From 450a9986ccb953f4255af65e5cf63b0ecde90e1a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olav=20S=C3=B8rensen?=
Date: Tue, 1 Jun 2021 12:34:14 +0200
Subject: [PATCH 13/30] Fix for 16-bit samples in S3M importer
---
src/milkyplay/LoaderS3M.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/milkyplay/LoaderS3M.cpp b/src/milkyplay/LoaderS3M.cpp
index edf0fd54..afbf208d 100644
--- a/src/milkyplay/LoaderS3M.cpp
+++ b/src/milkyplay/LoaderS3M.cpp
@@ -488,9 +488,13 @@ mp_sint32 LoaderS3M::load(XMFileBase& f, XModule* module)
if (flags & 4)
{
smp[s].type |= 16;
+
+ // 8bitbubsy: fix for 16-bit S3M samples (Units are in samples, not bytes. Don't divide by two!)
+ /*
smp[s].samplen >>= 1;
smp[s].loopstart >>= 1;
smp[s].looplen >>= 1;
+ */
}
mp_uint32 c4spd = f.readDword();
From d3b2c78b66b9aae22f73d7034af58b9ae7466e4d Mon Sep 17 00:00:00 2001
From: Casey Joy <67843601+caseyjoy@users.noreply.github.com>
Date: Mon, 15 Mar 2021 05:29:21 -0600
Subject: [PATCH 14/30] Add #107 Feature Request "set loop to selection"
---
src/ppui/Menu.h | 1 +
src/tracker/SampleEditor.cpp | 20 ++++++++++++++++++++
src/tracker/SampleEditor.h | 3 ++-
src/tracker/SampleEditorControl.cpp | 15 +++++++++++++++
src/tracker/SampleEditorControl.h | 1 +
5 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/src/ppui/Menu.h b/src/ppui/Menu.h
index 4aab71c5..e6bf390b 100644
--- a/src/ppui/Menu.h
+++ b/src/ppui/Menu.h
@@ -46,6 +46,7 @@ enum MenuCommandIDs
MenuCommandIDPaste = 3,
MenuCommandIDSelectAll = 4,
MenuCommandIDSelectNothing = 5,
+ MenuCommandIDLoopRange = 6,
MenuCommandIDUndo = 7,
MenuCommandIDRedo = 8,
MenuCommandIDHide = 0x10000
diff --git a/src/tracker/SampleEditor.cpp b/src/tracker/SampleEditor.cpp
index 09fb46b2..55605733 100644
--- a/src/tracker/SampleEditor.cpp
+++ b/src/tracker/SampleEditor.cpp
@@ -444,6 +444,26 @@ void SampleEditor::selectAll()
selectionEnd = sample->samplen;
}
+void SampleEditor::loopRange()
+{
+ if (!hasValidSelection())
+ return;
+
+ // If a loop type is not enabled, set loop to Forward.
+ // - Changes loop type to Forward when loop type is set to One shot
+ // and the start of the selection is not at the start of the sample,
+ // but so does dragging the start of the loop.
+ if (!getLoopType())
+ setLoopType(1);
+
+ // Once loop is enabled, set the loop start/end points to selection start/end points.
+ setRepeatStart(getSelectionStart());
+ setRepeatEnd(getSelectionEnd());
+
+ // Doesn't currently have undo or have the sample do the new loop
+ // until it retriggers, but neither does dragging the loop points.
+}
+
bool SampleEditor::validate()
{
if (isEmptySample())
diff --git a/src/tracker/SampleEditor.h b/src/tracker/SampleEditor.h
index 872fdcfb..8d30b1b1 100644
--- a/src/tracker/SampleEditor.h
+++ b/src/tracker/SampleEditor.h
@@ -184,7 +184,8 @@ class SampleEditor : public EditorBase
bool hasValidSelection() const { return ((selectionStart >= 0 && selectionEnd >= 0) && (selectionStart != selectionEnd)); }
void selectAll();
-
+ void loopRange();
+
bool validate();
// --- Multilevel UNDO / REDO --------------------------------------------
diff --git a/src/tracker/SampleEditorControl.cpp b/src/tracker/SampleEditorControl.cpp
index 42c123bd..78e92cb8 100644
--- a/src/tracker/SampleEditorControl.cpp
+++ b/src/tracker/SampleEditorControl.cpp
@@ -168,6 +168,7 @@ SampleEditorControl::SampleEditorControl(pp_int32 id,
editMenuControl->addEntry("Paste", MenuCommandIDPaste);
editMenuControl->addEntry("Crop", MenuCommandIDCrop);
editMenuControl->addEntry("Range all", MenuCommandIDSelectAll);
+ editMenuControl->addEntry("Loop range", MenuCommandIDLoopRange);
editMenuControl->addEntry(seperatorStringMed, -1);
editMenuControl->addEntry("Advanced \x10", 0xFFFF, subMenuAdvanced);
editMenuControl->addEntry("Ext. Paste \x10", 0xFFFF, subMenuXPaste);
@@ -1437,6 +1438,14 @@ void SampleEditorControl::rangeAll(bool updateNotify/* = false*/)
notifyUpdate();
}
+void SampleEditorControl::loopRange(bool updateNotify/* = false*/)
+{
+ sampleEditor->loopRange();
+
+ if (updateNotify)
+ notifyUpdate();
+}
+
void SampleEditorControl::rangeClear(bool updateNotify/* = false*/)
{
sampleEditor->resetSelection();
@@ -1664,6 +1673,7 @@ void SampleEditorControl::invokeContextMenu(const PPPoint& p, bool translatePoin
editMenuControl->setState(MenuCommandIDCut, !hasValidSelection());
editMenuControl->setState(MenuCommandIDCrop, !hasValidSelection());
editMenuControl->setState(MenuCommandIDSelectAll, isEmptySample);
+ editMenuControl->setState(MenuCommandIDLoopRange, !hasValidSelection());
// update submenu states
subMenuAdvanced->setState(MenuCommandIDNormalize, isEmptySample);
@@ -1770,6 +1780,11 @@ void SampleEditorControl::executeMenuCommand(pp_int32 commandId)
rangeAll(true);
break;
+ // set loop to current selection
+ case MenuCommandIDLoopRange:
+ loopRange(true);
+ break;
+
// Invoke tools
case MenuCommandIDNew:
invokeToolParameterDialog(ToolHandlerResponder::SampleToolTypeNew);
diff --git a/src/tracker/SampleEditorControl.h b/src/tracker/SampleEditorControl.h
index c0df4e16..c40d866b 100644
--- a/src/tracker/SampleEditorControl.h
+++ b/src/tracker/SampleEditorControl.h
@@ -161,6 +161,7 @@ class SampleEditorControl : public PPControl, public EventListenerInterface, pub
void showRange();
void rangeAll(bool updateNotify = false);
void rangeClear(bool updateNotify = false);
+ void loopRange(bool updateNotify = false); // set loop points to current range
void increaseRangeStart();
void decreaseRangeStart();
From 075d32ec2662cbbf52caf45e1ec97a2df3254248 Mon Sep 17 00:00:00 2001
From: Leon
Date: Tue, 6 Jul 2021 15:59:46 +0200
Subject: [PATCH 15/30] easily 'sample' current pattern into current sample
---
src/tracker/ModuleEditor.h | 2 ++
src/tracker/SampleEditorControl.cpp | 11 +++++++++++
src/tracker/SampleEditorControl.h | 8 +++++++-
src/tracker/SectionSamples.cpp | 2 +-
src/tracker/Tracker.h | 3 +++
src/tracker/TrackerKeyboard.cpp | 15 +++++++++++++++
6 files changed, 39 insertions(+), 2 deletions(-)
mode change 100644 => 100755 src/tracker/ModuleEditor.h
mode change 100644 => 100755 src/tracker/SampleEditorControl.cpp
mode change 100644 => 100755 src/tracker/SampleEditorControl.h
mode change 100644 => 100755 src/tracker/SectionSamples.cpp
mode change 100644 => 100755 src/tracker/Tracker.h
mode change 100644 => 100755 src/tracker/TrackerKeyboard.cpp
diff --git a/src/tracker/ModuleEditor.h b/src/tracker/ModuleEditor.h
old mode 100644
new mode 100755
index 823f63f1..3519362c
--- a/src/tracker/ModuleEditor.h
+++ b/src/tracker/ModuleEditor.h
@@ -34,6 +34,7 @@ class SampleEditor;
class EnvelopeEditor;
class ModuleServices;
class PlayerCriticalSection;
+class Tracker;
class ModuleEditor
{
@@ -385,6 +386,7 @@ class ModuleEditor
static PPSystemString getTempFilename();
friend class ChangesListener;
+ friend class Tracker;
};
#endif
diff --git a/src/tracker/SampleEditorControl.cpp b/src/tracker/SampleEditorControl.cpp
old mode 100644
new mode 100755
index 78e92cb8..4af98615
--- a/src/tracker/SampleEditorControl.cpp
+++ b/src/tracker/SampleEditorControl.cpp
@@ -28,6 +28,8 @@
#include "ContextMenu.h"
#include "Piano.h"
#include "Tools.h"
+#include "Tracker.h"
+#include "SampleEditor.h"
#include "TrackerConfig.h"
#include "PlayerController.h"
#include "DialogBase.h"
@@ -64,6 +66,7 @@ SampleEditorControl::SampleEditorControl(pp_int32 id,
EventListenerInterface* eventListener,
const PPPoint& location,
const PPSize& size,
+ Tracker& tracker,
bool border/*= true*/) :
PPControl(id, parentScreen, eventListener, location, size),
border(border),
@@ -144,6 +147,8 @@ SampleEditorControl::SampleEditorControl(pp_int32 id,
subMenuXPaste->addEntry("Phase Modulate", MenuCommandIDPHPaste);
subMenuXPaste->addEntry("Flanger", MenuCommandIDFLPaste);
subMenuXPaste->addEntry("Selective EQ" PPSTR_PERIODS, MenuCommandIDSelectiveEQ10Band);
+ subMenuXPaste->addEntry("Capture pattern" PPSTR_PERIODS, MenuCommandIDCapturePattern);
+
subMenuPT = new PPContextMenu(6, parentScreen, this, PPPoint(0,0), TrackerConfig::colorThemeMain);
subMenuPT->addEntry("Boost", MenuCommandIDPTBoost);
@@ -178,6 +183,7 @@ SampleEditorControl::SampleEditorControl(pp_int32 id,
// Create tool handler responder
toolHandlerResponder = new ToolHandlerResponder(*this);
dialog = NULL;
+ this->tracker = (Tracker *)&tracker;
resetLastValues();
}
@@ -1718,6 +1724,7 @@ void SampleEditorControl::hideContextMenu()
void SampleEditorControl::executeMenuCommand(pp_int32 commandId)
{
+
switch (commandId)
{
// cut
@@ -1790,6 +1797,10 @@ void SampleEditorControl::executeMenuCommand(pp_int32 commandId)
invokeToolParameterDialog(ToolHandlerResponder::SampleToolTypeNew);
break;
+ case MenuCommandIDCapturePattern:
+ tracker->eventKeyDownBinding_InvokePatternCapture();
+ break;
+
case MenuCommandIDVolumeBoost:
invokeToolParameterDialog(ToolHandlerResponder::SampleToolTypeVolume);
break;
diff --git a/src/tracker/SampleEditorControl.h b/src/tracker/SampleEditorControl.h
old mode 100644
new mode 100755
index c40d866b..7f6f06f6
--- a/src/tracker/SampleEditorControl.h
+++ b/src/tracker/SampleEditorControl.h
@@ -26,7 +26,9 @@
#include "BasicTypes.h"
#include "Control.h"
#include "Event.h"
+#include "Tracker.h"
#include "SampleEditor.h"
+#include "EditorBase.h"
#include "SampleEditorControlLastValues.h"
// Forwards
@@ -63,6 +65,7 @@ class SampleEditorControl : public PPControl, public EventListenerInterface, pub
PPControl* caughtControl;
bool controlCaughtByLMouseButton, controlCaughtByRMouseButton;
+ Tracker* tracker;
PPContextMenu* editMenuControl;
PPContextMenu* subMenuAdvanced;
PPContextMenu* subMenuXPaste;
@@ -126,6 +129,7 @@ class SampleEditorControl : public PPControl, public EventListenerInterface, pub
EventListenerInterface* eventListener,
const PPPoint& location,
const PPSize& size,
+ Tracker& tracker,
bool border = true);
virtual ~SampleEditorControl();
@@ -296,6 +300,7 @@ class SampleEditorControl : public PPControl, public EventListenerInterface, pub
MenuCommandIDEQ3Band,
MenuCommandIDEQ10Band,
MenuCommandIDSelectiveEQ10Band,
+ MenuCommandIDCapturePattern,
MenuCommandIDGenerateSilence,
MenuCommandIDGenerateNoise,
MenuCommandIDGenerateSine,
@@ -363,7 +368,8 @@ class SampleEditorControl : public PPControl, public EventListenerInterface, pub
};
friend class ToolHandlerResponder;
-
+ friend class Tracker;
+
PPDialogBase* dialog;
ToolHandlerResponder* toolHandlerResponder;
diff --git a/src/tracker/SectionSamples.cpp b/src/tracker/SectionSamples.cpp
old mode 100644
new mode 100755
index 6fcc5f61..8a78f1bb
--- a/src/tracker/SectionSamples.cpp
+++ b/src/tracker/SectionSamples.cpp
@@ -500,7 +500,7 @@ void SectionSamples::init(pp_int32 x, pp_int32 y)
PPContainer* sampleEditorContainer = new PPContainer(CONTAINER_SAMPLEEDITOR, screen, this, PPPoint(x, y), PPSize(screen->getWidth(), cHeight), false);
sampleEditorContainer->setColor(TrackerConfig::colorThemeMain);
- sampleEditorControl = new SampleEditorControl(SAMPLE_EDITOR, screen, this, PPPoint(x+2, y+2), PPSize(sampleEditorContainer->getSize().width-4, sampleEditorContainer->getSize().height-4));
+ sampleEditorControl = new SampleEditorControl(SAMPLE_EDITOR, screen, this, PPPoint(x+2, y+2), PPSize(sampleEditorContainer->getSize().width-4, sampleEditorContainer->getSize().height-4), tracker );
sampleEditorControl->attachSampleEditor(tracker.moduleEditor->getSampleEditor());
sampleEditorControl->setBorderColor(TrackerConfig::colorThemeMain);
diff --git a/src/tracker/Tracker.h b/src/tracker/Tracker.h
old mode 100644
new mode 100755
index 067add69..a396887e
--- a/src/tracker/Tracker.h
+++ b/src/tracker/Tracker.h
@@ -580,6 +580,8 @@ class Tracker : public EventListenerInterface
void eventKeyDownBinding_DecCurOrderPattern();
void eventKeyDownBinding_IncCurOrderPattern();
+ void eventKeyDownBinding_InvokePatternCapture();
+
private:
// - friend classes --------------------------------------------------------
@@ -609,6 +611,7 @@ class Tracker : public EventListenerInterface
friend class RecorderLogic;
friend class Zapper;
friend class SectionSwitcher;
+ friend class SampleEditorControl;
};
#endif
diff --git a/src/tracker/TrackerKeyboard.cpp b/src/tracker/TrackerKeyboard.cpp
old mode 100644
new mode 100755
index 2ab0d31c..f68efb46
--- a/src/tracker/TrackerKeyboard.cpp
+++ b/src/tracker/TrackerKeyboard.cpp
@@ -171,6 +171,9 @@ void Tracker::initKeyBindings()
eventKeyDownBindingsMilkyTracker->addBinding(VK_DECIMAL, 0, &Tracker::eventKeyDownBinding_InvokeQuickChooseInstrument);
eventKeyDownBindingsMilkyTracker->addBinding(VK_DIVIDE, 0, &Tracker::eventKeyDownBinding_InvokeQuickChooseInstrument);
+ eventKeyDownBindingsMilkyTracker->addBinding('V', KeyModifierCTRL | KeyModifierSHIFT, &Tracker::eventKeyDownBinding_InvokePatternCapture);
+
+
// Key-down bindings for Fasttracker
// tab stuff
eventKeyDownBindingsFastTracker->addBinding('T', KeyModifierCTRL|KeyModifierSHIFT, &Tracker::eventKeyDownBinding_OpenTab);
@@ -261,6 +264,8 @@ void Tracker::initKeyBindings()
eventKeyDownBindingsFastTracker->addBinding(VK_F11, KeyModifierCTRL, &Tracker::eventKeyDownBinding_DecCurOrderPattern);
eventKeyDownBindingsFastTracker->addBinding(VK_F12, KeyModifierCTRL, &Tracker::eventKeyDownBinding_IncCurOrderPattern);
+ eventKeyDownBindingsFastTracker->addBinding('V', KeyModifierCTRL|KeyModifierSHIFT, &Tracker::eventKeyDownBinding_InvokePatternCapture);
+
eventKeyDownBindings = eventKeyDownBindingsMilkyTracker;
}
@@ -1006,3 +1011,13 @@ void Tracker::eventKeyDownBinding_IncCurOrderPattern()
moduleEditor->increaseOrderPosition(getOrderListBoxIndex());
updateOrderlist();
}
+
+void Tracker::eventKeyDownBinding_InvokePatternCapture()
+{
+ sectionHDRecorder->selectSampleOutput();
+ sectionHDRecorder->smpIndex = moduleEditor->currentSampleIndex;
+ sectionHDRecorder->insIndex = moduleEditor->currentInstrumentIndex;
+ sectionHDRecorder->fromOrder = getOrderListBoxIndex();
+ sectionHDRecorder->toOrder = getOrderListBoxIndex();
+ sectionHDRecorder->exportWAVAsSample();
+}
From ac29eaddea14c764dfb2581e9a886c5c9cd1bee9 Mon Sep 17 00:00:00 2001
From: Leon
Date: Tue, 13 Jul 2021 21:08:13 +0200
Subject: [PATCH 16/30] capture should respect mutes
---
src/tracker/TrackerKeyboard.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/tracker/TrackerKeyboard.cpp b/src/tracker/TrackerKeyboard.cpp
index f68efb46..8239f80e 100755
--- a/src/tracker/TrackerKeyboard.cpp
+++ b/src/tracker/TrackerKeyboard.cpp
@@ -1019,5 +1019,6 @@ void Tracker::eventKeyDownBinding_InvokePatternCapture()
sectionHDRecorder->insIndex = moduleEditor->currentInstrumentIndex;
sectionHDRecorder->fromOrder = getOrderListBoxIndex();
sectionHDRecorder->toOrder = getOrderListBoxIndex();
+ sectionHDRecorder->setSettingsAllowMuting(true);
sectionHDRecorder->exportWAVAsSample();
}
From c8e5ad4c880901069398b3d6a43cfbba7dd0f188 Mon Sep 17 00:00:00 2001
From: Cong
Date: Wed, 9 Jun 2021 20:15:16 +1000
Subject: [PATCH 17/30] Add half sine generator #239
---
src/tracker/SampleEditor.cpp | 51 +++++++++++++++++++
src/tracker/SampleEditor.h | 1 +
src/tracker/SampleEditorControl.cpp | 6 +++
src/tracker/SampleEditorControl.h | 6 ++-
.../SampleEditorControlToolHandler.cpp | 13 +++++
5 files changed, 75 insertions(+), 2 deletions(-)
diff --git a/src/tracker/SampleEditor.cpp b/src/tracker/SampleEditor.cpp
index 55605733..e0934b78 100644
--- a/src/tracker/SampleEditor.cpp
+++ b/src/tracker/SampleEditor.cpp
@@ -2914,6 +2914,57 @@ void SampleEditor::tool_generateSawtooth(const FilterParameters* par)
postFilter();
}
+void SampleEditor::tool_generateHalfSine(const FilterParameters* par)
+{
+ if (isEmptySample())
+ return;
+
+ pp_int32 sStart = selectionStart;
+ pp_int32 sEnd = selectionEnd;
+
+ if (hasValidSelection())
+ {
+ if (sStart >= 0 && sEnd >= 0)
+ {
+ if (sEnd < sStart)
+ {
+ pp_int32 s = sEnd; sEnd = sStart; sStart = s;
+ }
+ }
+ }
+ else
+ {
+ sStart = 0;
+ sEnd = sample->samplen;
+ }
+
+ preFilter(&SampleEditor::tool_generateHalfSine, par);
+
+ mp_sint32 sLen = sEnd - sStart;
+
+ prepareUndo();
+
+ pp_int32 i;
+
+ const float numPeriods = (float)(6.283185307179586476925286766559 * par->getParameter(1).floatPart);
+ const float amplify = par->getParameter(0).floatPart;
+
+ // generate half sine wave here
+ for (i = sStart; i < sEnd / 2; i++)
+ {
+ float per = (i - sStart) / (float)sLen * numPeriods;
+ setFloatSampleInWaveform(i, (float)sin(per) * amplify);
+ }
+ for (i = sEnd / 2; i < sEnd; i++)
+ {
+ setFloatSampleInWaveform(i, 0);
+ }
+
+ finishUndo();
+
+ postFilter();
+}
+
bool SampleEditor::tool_canApplyLastFilter() const
{
return lastFilterFunc != NULL && isValidSample();
diff --git a/src/tracker/SampleEditor.h b/src/tracker/SampleEditor.h
index 8d30b1b1..b96f6f2e 100644
--- a/src/tracker/SampleEditor.h
+++ b/src/tracker/SampleEditor.h
@@ -350,6 +350,7 @@ class SampleEditor : public EditorBase
void tool_generateSquare(const FilterParameters* par);
void tool_generateTriangle(const FilterParameters* par);
void tool_generateSawtooth(const FilterParameters* par);
+ void tool_generateHalfSine(const FilterParameters* par);
void tool_applyLastFilter();
bool tool_canApplyLastFilter() const;
diff --git a/src/tracker/SampleEditorControl.cpp b/src/tracker/SampleEditorControl.cpp
index 78e92cb8..4598a81b 100644
--- a/src/tracker/SampleEditorControl.cpp
+++ b/src/tracker/SampleEditorControl.cpp
@@ -154,6 +154,7 @@ SampleEditorControl::SampleEditorControl(pp_int32 id,
subMenuGenerators->addEntry("Square" PPSTR_PERIODS, MenuCommandIDGenerateSquare);
subMenuGenerators->addEntry("Triangle" PPSTR_PERIODS, MenuCommandIDGenerateTriangle);
subMenuGenerators->addEntry("Sawtooth" PPSTR_PERIODS, MenuCommandIDGenerateSawtooth);
+ subMenuGenerators->addEntry("Half Sine" PPSTR_PERIODS, MenuCommandIDGenerateHalfSine);
subMenuGenerators->addEntry("Silence" PPSTR_PERIODS, MenuCommandIDGenerateSilence);
// build context menu
@@ -1705,6 +1706,7 @@ void SampleEditorControl::invokeContextMenu(const PPPoint& p, bool translatePoin
subMenuGenerators->setState(MenuCommandIDGenerateSquare, isEmptySample);
subMenuGenerators->setState(MenuCommandIDGenerateTriangle, isEmptySample);
subMenuGenerators->setState(MenuCommandIDGenerateSawtooth, isEmptySample);
+ subMenuGenerators->setState(MenuCommandIDGenerateHalfSine, isEmptySample);
subMenuGenerators->setState(MenuCommandIDGenerateSilence, isEmptySample);
parentScreen->setContextMenuControl(editMenuControl);
@@ -1878,6 +1880,10 @@ void SampleEditorControl::executeMenuCommand(pp_int32 commandId)
invokeToolParameterDialog(ToolHandlerResponder::SampleToolTypeGenerateSawtooth);
break;
+ case MenuCommandIDGenerateHalfSine:
+ invokeToolParameterDialog(ToolHandlerResponder::SampleToolTypeGenerateHalfSine);
+ break;
+
}
}
diff --git a/src/tracker/SampleEditorControl.h b/src/tracker/SampleEditorControl.h
index c40d866b..19ce50fc 100644
--- a/src/tracker/SampleEditorControl.h
+++ b/src/tracker/SampleEditorControl.h
@@ -301,7 +301,8 @@ class SampleEditorControl : public PPControl, public EventListenerInterface, pub
MenuCommandIDGenerateSine,
MenuCommandIDGenerateSquare,
MenuCommandIDGenerateTriangle,
- MenuCommandIDGenerateSawtooth
+ MenuCommandIDGenerateSawtooth,
+ MenuCommandIDGenerateHalfSine
};
void executeMenuCommand(pp_int32 commandId);
@@ -345,7 +346,8 @@ class SampleEditorControl : public PPControl, public EventListenerInterface, pub
SampleToolTypeGenerateSine,
SampleToolTypeGenerateSquare,
SampleToolTypeGenerateTriangle,
- SampleToolTypeGenerateSawtooth
+ SampleToolTypeGenerateSawtooth,
+ SampleToolTypeGenerateHalfSine
};
private:
diff --git a/src/tracker/SampleEditorControlToolHandler.cpp b/src/tracker/SampleEditorControlToolHandler.cpp
index 3348e574..703052f3 100644
--- a/src/tracker/SampleEditorControlToolHandler.cpp
+++ b/src/tracker/SampleEditorControlToolHandler.cpp
@@ -153,6 +153,7 @@ bool SampleEditorControl::invokeToolParameterDialog(SampleEditorControl::ToolHan
case ToolHandlerResponder::SampleToolTypeGenerateSquare:
case ToolHandlerResponder::SampleToolTypeGenerateTriangle:
case ToolHandlerResponder::SampleToolTypeGenerateSawtooth:
+ case ToolHandlerResponder::SampleToolTypeGenerateHalfSine:
{
dialog = new DialogWithValues(parentScreen, toolHandlerResponder, PP_DEFAULT_ID, "Generate waveform" PPSTR_PERIODS, DialogWithValues::ValueStyleEnterTwoValues);
static_cast(dialog)->setValueOneCaption("Volume in percent:");
@@ -331,6 +332,18 @@ bool SampleEditorControl::invokeTool(ToolHandlerResponder::SampleToolTypes type)
sampleEditor->tool_generateSawtooth(&par);
break;
}
+
+ case ToolHandlerResponder::SampleToolTypeGenerateHalfSine:
+ {
+ lastValues.waveFormVolume = static_cast(dialog)->getValueOne();
+ lastValues.waveFormNumPeriods = static_cast(dialog)->getValueTwo();
+ FilterParameters par(2);
+ par.setParameter(0, FilterParameters::Parameter(lastValues.waveFormVolume / 100.0f));
+ par.setParameter(1, FilterParameters::Parameter(lastValues.waveFormNumPeriods));
+ sampleEditor->tool_generateHalfSine(&par);
+ break;
+ }
+
default:
break;
}
From 7f005f9cb6d7d1cf9fc372c02191a2907c49aa58 Mon Sep 17 00:00:00 2001
From: Leon
Date: Tue, 6 Jul 2021 18:38:52 +0200
Subject: [PATCH 18/30] added quick and dirty dynamic compression
---
src/tracker/SampleEditor.cpp | 71 +++++++++++++++++++++++++++++
src/tracker/SampleEditor.h | 1 +
src/tracker/SampleEditorControl.cpp | 6 +++
src/tracker/SampleEditorControl.h | 1 +
4 files changed, 79 insertions(+)
mode change 100644 => 100755 src/tracker/SampleEditor.cpp
mode change 100644 => 100755 src/tracker/SampleEditor.h
mode change 100644 => 100755 src/tracker/SampleEditorControl.cpp
mode change 100644 => 100755 src/tracker/SampleEditorControl.h
diff --git a/src/tracker/SampleEditor.cpp b/src/tracker/SampleEditor.cpp
old mode 100644
new mode 100755
index e0934b78..216238b0
--- a/src/tracker/SampleEditor.cpp
+++ b/src/tracker/SampleEditor.cpp
@@ -1840,6 +1840,77 @@ void SampleEditor::tool_normalizeSample(const FilterParameters* par)
postFilter();
}
+void SampleEditor::tool_compressSample(const FilterParameters* par)
+{
+ if (isEmptySample())
+ return;
+
+ pp_int32 sStart = selectionStart;
+ pp_int32 sEnd = selectionEnd;
+
+ if (hasValidSelection())
+ {
+ if (sStart >= 0 && sEnd >= 0)
+ {
+ if (sEnd < sStart)
+ {
+ pp_int32 s = sEnd; sEnd = sStart; sStart = s;
+ }
+ }
+ }
+ else
+ {
+ sStart = 0;
+ sEnd = sample->samplen;
+ }
+
+ preFilter(&SampleEditor::tool_compressSample, par);
+
+ prepareUndo();
+
+ float maxLevel = ((par == NULL) ? 1.0f : par->getParameter(0).floatPart);
+ float peak_pre = 0.0f;
+ float peak_post = 0.0f;
+ float compress = 0.8;
+
+ pp_int32 i;
+
+ // find peak value (pre)
+ for (i = sStart; i < sEnd; i++)
+ {
+ float f = getFloatSampleFromWaveform(i);
+ if (ppfabs(f) > peak_pre) peak_pre = ppfabs(f);
+ }
+
+ // compress
+ for (i = sStart; i < sEnd; i++)
+ {
+ float f = getFloatSampleFromWaveform(i);
+ f = compress * tanh(f / compress); // upward compression
+ setFloatSampleInWaveform(i, f);
+ }
+
+ // find peak value (post)
+ for (i = sStart; i < sEnd; i++)
+ {
+ float f = getFloatSampleFromWaveform(i);
+ if (ppfabs(f) > peak_post) peak_post = ppfabs(f);
+ }
+
+ float scale = 1.0f + (peak_pre - peak_post);
+
+ for (i = sStart; i < sEnd; i++)
+ {
+ float f = getFloatSampleFromWaveform(i);
+ setFloatSampleInWaveform(i, f * scale);
+ }
+
+ finishUndo();
+
+ postFilter();
+}
+
+
void SampleEditor::tool_reverseSample(const FilterParameters* par)
{
if (isEmptySample())
diff --git a/src/tracker/SampleEditor.h b/src/tracker/SampleEditor.h
old mode 100644
new mode 100755
index b96f6f2e..949f98aa
--- a/src/tracker/SampleEditor.h
+++ b/src/tracker/SampleEditor.h
@@ -329,6 +329,7 @@ class SampleEditor : public EditorBase
// filters
void tool_scaleSample(const FilterParameters* par);
void tool_normalizeSample(const FilterParameters* par);
+ void tool_compressSample(const FilterParameters* par);
void tool_reverseSample(const FilterParameters* par);
void tool_PTboostSample(const FilterParameters* par);
bool isValidxFadeSelection();
diff --git a/src/tracker/SampleEditorControl.cpp b/src/tracker/SampleEditorControl.cpp
old mode 100644
new mode 100755
index 4598a81b..0ccf5608
--- a/src/tracker/SampleEditorControl.cpp
+++ b/src/tracker/SampleEditorControl.cpp
@@ -119,6 +119,7 @@ SampleEditorControl::SampleEditorControl(pp_int32 id,
subMenuAdvanced->addEntry("Volume boost" PPSTR_PERIODS, MenuCommandIDVolumeBoost);
subMenuAdvanced->addEntry("Volume fade" PPSTR_PERIODS, MenuCommandIDVolumeFade);
subMenuAdvanced->addEntry("Normalize", MenuCommandIDNormalize);
+ subMenuAdvanced->addEntry("Compress", MenuCommandIDCompress);
subMenuAdvanced->addEntry(seperatorStringLarge, -1);
subMenuAdvanced->addEntry("Backwards", MenuCommandIDReverse);
subMenuAdvanced->addEntry("Cross-fade", MenuCommandIDXFade);
@@ -1678,6 +1679,7 @@ void SampleEditorControl::invokeContextMenu(const PPPoint& p, bool translatePoin
// update submenu states
subMenuAdvanced->setState(MenuCommandIDNormalize, isEmptySample);
+ subMenuAdvanced->setState(MenuCommandIDCompress, isEmptySample);
subMenuAdvanced->setState(MenuCommandIDVolumeFade, isEmptySample);
subMenuAdvanced->setState(MenuCommandIDVolumeBoost, isEmptySample);
subMenuAdvanced->setState(MenuCommandIDReverse, isEmptySample);
@@ -1812,6 +1814,10 @@ void SampleEditorControl::executeMenuCommand(pp_int32 commandId)
sampleEditor->tool_normalizeSample(NULL);
break;
+ case MenuCommandIDCompress:
+ sampleEditor->tool_compressSample(NULL);
+ break;
+
case MenuCommandIDReverse:
sampleEditor->tool_reverseSample(NULL);
break;
diff --git a/src/tracker/SampleEditorControl.h b/src/tracker/SampleEditorControl.h
old mode 100644
new mode 100755
index 19ce50fc..4cf6090c
--- a/src/tracker/SampleEditorControl.h
+++ b/src/tracker/SampleEditorControl.h
@@ -281,6 +281,7 @@ class SampleEditorControl : public PPControl, public EventListenerInterface, pub
MenuCommandIDPHPaste,
MenuCommandIDFLPaste,
MenuCommandIDNormalize,
+ MenuCommandIDCompress,
MenuCommandIDVolumeBoost,
MenuCommandIDVolumeFade,
MenuCommandIDReverse,
From d2cd52c9bc53d239fa65c0a8212b6638d267b917 Mon Sep 17 00:00:00 2001
From: Coder of Salvation / Leon van Kammen
Date: Thu, 29 Jul 2021 23:03:32 +0200
Subject: [PATCH 19/30] docs updated with ctrl-shift-v shortcut
---
docs/MilkyTracker.html | 3 +++
1 file changed, 3 insertions(+)
diff --git a/docs/MilkyTracker.html b/docs/MilkyTracker.html
index 38a0ca9f..7cd8bb65 100644
--- a/docs/MilkyTracker.html
+++ b/docs/MilkyTracker.html
@@ -681,6 +681,9 @@ Pattern Editor:
Ctrl-V | Paste |
+
+ Ctrl-Shift-V | Convert current pattern to sample |
+
Ctrl-I | Interpolate values |
From 3d306a02d847a42ce582ea574008ef4aa8c16020 Mon Sep 17 00:00:00 2001
From: Coder of Salvation / Leon van Kammen
Date: Thu, 29 Jul 2021 23:18:52 +0200
Subject: [PATCH 20/30] prevented future 'oddevenoddevenoddeven'-chore by
introducing css feature
---
docs/MilkyTracker.html | 873 ++++++++++++++++++++++-------------------
1 file changed, 469 insertions(+), 404 deletions(-)
diff --git a/docs/MilkyTracker.html b/docs/MilkyTracker.html
index 7cd8bb65..46672bcb 100644
--- a/docs/MilkyTracker.html
+++ b/docs/MilkyTracker.html
@@ -68,7 +68,7 @@
vertical-align: top;
}
- tr.odd {
+ tr:nth-child(odd) {
background-color: #eee;
}
@@ -299,97 +299,97 @@
Import:
-
+
.669 | 669 Composer/Unis669 (PC) |
-
+
.AMF | Asylum Music Format ("Crusader" in-game music) (PC) |
-
+
Digital Sound and Music Interface (DSMI) library (PC) |
-
+
.AMS | Extreme Tracker (PC) |
-
+
Velvet Studio (PC) |
-
+
.CBA | Chuck Biscuits+Black Artist module format (PC) |
-
+
.DBM | DigiBooster Pro (Amiga) |
-
+
.DIGI | Digibooster 1.0-1.7 (Amiga) |
-
+
.DSM | Digisound Interface Kit (DSIK) library (PC) |
-
+
Dynamic Studio (PC) |
-
+
.DTM | Digital Tracker (Atari) |
-
+
DigiTrekker 3.0 (PC) |
-
+
.FAR | Farandole Composer (PC) |
-
+
.GDM | General Digimusic (PC) |
-
+
.GMC | Game Music Creator (Amiga) |
-
+
.IMF | Imago Orpheus (PC) |
-
+
.IT | Impulse Tracker (PC) |
-
+
.MDL | DigiTrakker 1.0-3.0 (PC) |
-
+
.MOD | Sound-/ProTracker and variants (Amiga & PC) |
-
+
.MTM | MultiTracker (PC) |
-
+
.MXM | Cubic Tiny XM (PC) |
-
+
.OKT | Oktalyzer (Amiga) |
-
+
.PLM | DisorderTracker II (PC) |
-
+
.PSM | Epic MegaGames MASI (PC) |
-
+
.PTM | PolyTracker (PC) |
-
+
.S3M | Scream Tracker 3.0 (PC) |
-
+
.SFX | SoundFX (Amiga) |
-
+
.STM | Scream Tracker 2.0 (PC) |
-
+
.ULT | UltraTracker (PC) |
-
+
.UNI | MikMod (PC) |
-
+
.XM | Fasttracker II (PC) |
@@ -398,13 +398,13 @@ Import:
Export:
-
+
.MOD | ProTracker boundaries (including 64kb max sample length), although can save 2–32 channels |
-
+
.WAV | Microsoft/IBM PCM Waveform audio rendering |
-
+
.XM | Fasttracker II compatible, not as common as one might think |
@@ -417,25 +417,25 @@
Import:
-
+
.8SVX / .IFF | Compressed/uncompressed Interchange File Format |
-
+
.AIF / .AIFF | Apple Audio Interchange File Format |
-
+
.WAV | Microsoft/IBM uncompressed PCM Waveform audio |
-
+
.* | RAW PCM audio |
Export:
-
+
.IFF | Uncompressed Interchange File Format |
-
+
.WAV | Microsoft/IBM uncompressed PCM Waveform audio |
@@ -467,43 +467,43 @@
Please note that under Mac OS X the Command key is used instead of the Ctrl key.
-
+
Alt-Enter | Switch between full screen and windowed display (Windows & SDL) |
-
+
Shift-Command-F | Switch between full screen and windowed display (OS X) |
-
+
Shift-M | Mute current channel |
-
+
Ctrl-Shift-M | Invert muting |
-
+
Shift-U | Un-mute all |
-
+
Ctrl-Shift-T | Open a new tab |
-
+
Ctrl-Shift-W | Close current tab |
-
+
Ctrl-Shift-Left | Select previous tab |
-
+
Ctrl-Shift-Right | Select next tab |
-
+
Ctrl-= | Increment instrument number of all notes in the current selection |
-
+
Ctrl-- | Decrement instrument number of all notes in the current selection |
-
+
Ctrl-Shift-= | Increment instrument number of all notes in the current track under the cursor |
-
+
Ctrl-Shift-- | Decrement instrument number of all notes in the current track under the cursor |
@@ -513,274 +513,309 @@
Section switching:
-
+
Ctrl-Alt- |
-
+
A | Advanced edit |
-
+
C | Configuration |
-
+
D | Disk operations |
-
+
I | Instrument editor |
-
+
R | Disk recorder |
-
+
S | Sample editor |
-
+
T | Transpose |
-
+
X | Main screen |
-
+
Z | Toggle scopes |
Global:
-
+
2, 3, 5, 6… | Play / insert notes (depending on whether edit mode is on) |
-
+
Q, W, E, R… |
-
+
S, D, F, G… |
-
+
Z, X, C, V… |
-
+
F1…F8 | Select octave |
-
+
Ctrl-Shift-1…8 |
-
+
Space | Toggle pattern editor focus (edit mode on/off) |
-
+
Enter | Play song from current order |
-
+
Ctrl-Enter | Play current pattern from beginning |
-
+
Shift-Enter | Play current pattern from cursor position |
-
+
Shift-F9 | Play current pattern from beginning (same as Ctrl-Enter) |
-
+
Shift-F10 | Play current pattern from position after the first quarter of the pattern length |
-
+
Shift-F11 | Play current pattern from position after the second quarter of the pattern length |
-
+
Shift-F12 | Play current pattern from position after the third quarter of the pattern length |
-
+
Alt-Space | Play song from current row (stop and return when keys are released) |
-
+
Shift-Space | Play row by row |
-
+
Esc | Stop |
-
+
Ctrl-F | Toggle song follow |
-
+
Ctrl-P | Toggle prospective pattern view |
-
+
Ctrl-W | Toggle pattern wrapping |
-
+
Ctrl-L | Toggle pattern change behavior (live mode) |
-
+
Ctrl-O | Load song |
-
+
Ctrl-S | Save song |
-
+
Ctrl-Shift-S | Save song as… |
-
+
Ctrl-Q | Exit program |
-
+
Alt-F4 |
Pattern Editor:
-
- Cursor keys | Move around |
+
+ Cursor keys |
+ Move around |
-
- Tab | Jump to next channel |
+
+ Tab |
+ Jump to next channel |
-
- PageUp | Jump 16 rows up |
+
+ PageUp |
+ Jump 16 rows up |
-
- PageDown | Jump 16 rows down |
+
+ PageDown |
+ Jump 16 rows down |
-
- Home | Jump to first row |
+
+ Home |
+ Jump to first row |
-
- End | Jump to last row |
+
+ End |
+ Jump to last row |
-
- F9 | Jump to beginning of the pattern |
+
+ F9 |
+ Jump to beginning of the pattern |
-
- F10 | Jump to position ¼ through the pattern |
+
+ F10 |
+ Jump to position ¼ through the pattern |
-
- F11 | Jump to position halfway through the pattern |
+
+ F11 |
+ Jump to position halfway through the pattern |
-
- F12 | Jump to position ¾ through the pattern |
+
+ F12 |
+ Jump to position ¾ through the pattern |
-
- Ctrl-Z | Undo |
+
+ Ctrl-Z |
+ Undo |
-
- Ctrl-Y | Redo |
+
+ Ctrl-Y |
+ Redo |
-
- Shift-Cursor keys | Select block |
+
+ Shift-Cursor keys |
+ Select block |
-
- Shift-Alt-Cursor keys | Extend block |
+
+ Shift-Alt-Cursor keys |
+ Extend block |
+
+
+ Ctrl-A |
+ Select entire pattern |
-
- Ctrl-A | Select entire pattern |
+
+ Ctrl-X |
+ Cut |
-
- Ctrl-X | Cut |
+
+ Ctrl-C |
+ Copy |
-
- Ctrl-C | Copy |
+
+ Ctrl-V |
+ Paste |
-
- Ctrl-V | Paste |
+
+ Ctrl-Shift-V |
+ Convert current pattern to sample |
-
- Ctrl-Shift-V | Convert current pattern to sample |
-
-
- Ctrl-I | Interpolate values |
+
+ Ctrl-I |
+ Interpolate values |
-
- Delete | Delete note/instrument/volume/effect/parameter |
+
+ Delete |
+ Delete note/instrument/volume/effect/parameter |
-
- Shift-Del | Delete note, volume and effect at cursor |
+
+ Shift-Del |
+ Delete note, volume and effect at cursor |
-
- Ctrl-Del | Delete volume and effect at cursor |
+
+ Ctrl-Del |
+ Delete volume and effect at cursor |
-
- Alt-Delete | Delete effect at cursor |
+
+ Alt-Delete |
+ Delete effect at cursor |
-
- Insert | Insert space on current track at cursor position |
+
+ Insert |
+ Insert space on current track at cursor position |
-
- Shift-Insert | Insert row at cursor position |
+
+ Shift-Insert |
+ Insert row at cursor position |
-
- Alt-Backspace | Insert space on current track at cursor position (alternative for keyboards with no Insert key) |
+
+ Alt-Backspace |
+ Insert space on current track at cursor position (alternative for keyboards with no Insert key) |
-
- Shift-Alt-Backspace | Insert row at cursor position (alternative for keyboards with no Insert key) |
+
+ Shift-Alt-Backspace |
+ Insert row at cursor position (alternative for keyboards with no Insert key) |
-
- Backspace | Delete previous note |
+
+ Backspace |
+ Delete previous note |
-
- Shift-Backspace | Delete previous row |
+
+ Shift-Backspace |
+ Delete previous row |
-
- The key right of LShift | Enter key-off |
+
+ The key right of LShift |
+ Enter key-off |
-
- The key below Esc | Enter key-off (Windows only) |
+
+ The key below Esc |
+ Enter key-off (Windows only) |
-
- 1 | Enter key-off (OS X only) |
+
+ 1 |
+ Enter key-off (OS X only) |
-
- Alt-Minus | Increase Add value |
+
+ Alt-Minus |
+ Increase Add value |
-
- or Alt-Plus | Decrease Add value |
+
+ or Alt-Plus |
+ Decrease Add value |
Transpose:
-
+
Alt-F7 | Transpose current instrument in block down |
-
+
Alt-F8 | Transpose current instrument in block up |
-
+
Shift-F7 | Transpose current instrument in track down |
-
+
Shift-F8 | Transpose current instrument in track up |
-
+
Ctrl-F7 | Transpose current instrument in pattern down |
-
+
Ctrl-F8 | Transpose current instrument in pattern up |
-
+
Alt-F1 | Transpose all instruments in block down |
-
+
Alt-F2 | Transpose all instruments in block up |
-
+
Shift-F1 | Transpose all instruments in track down |
-
+
Shift-F2 | Transpose all instruments in track up |
-
+
Ctrl-F1 | Transpose all instruments in pattern down |
-
+
Ctrl-F2 | Transpose all instruments in pattern up |
Sample Editor:
-
+
Shift & drag | Quick draw |
-
+
Ctrl & drag | Resize selection |
-
+
Alt & drag | Move selection or loop range |
@@ -793,142 +828,142 @@
Section switching:
-
+
Ctrl- |
-
+
A | Advanced edit |
-
+
C | Configuration |
-
+
D | Disk operations |
-
+
I | Instrument editor |
-
+
R | Disk recorder |
-
+
S | Sample editor |
-
+
T | Transpose |
-
+
X | Main screen |
-
+
Z | Toggle scopes |
Global:
-
+
2, 3, 5, 6… | Play / insert notes (depending on whether edit mode is on) |
-
+
Q, W, E, R… |
-
+
S, D, F, G… |
-
+
Z, X, C, V… |
-
+
F1…F8 | Select octave |
-
+
Right Ctrl | Play song from current order |
-
+
Enter | Play song from current order |
-
+
Right Alt | Play current pattern from beginning (Windows &SDL) |
-
+
Ctrl-Enter | Play current pattern from beginning |
-
+
Shift-Enter | Play current pattern from current row |
-
+
Shift-F9 | Play current pattern from beginning (same as Ctrl-Enter/Right Alt) |
-
+
Shift-F10 | Play current pattern from position after the first quarter of the pattern length |
-
+
Shift-F11 | Play current pattern from position after the second quarter of the pattern length |
-
+
Shift-F12 | Play current pattern from position after the third quarter of the pattern length |
-
+
Alt-Space | Play song from current row (stop and return when keys are released) |
-
+
Shift-Space | Play row by row |
-
+
Space | Stop / Edit |
-
+
Shift-Left | Increase song position |
-
+
Shift-Right | Decrease song position |
-
+
Ctrl-Left | Increase current pattern number |
-
+
Ctrl-Right | Decrease current pattern number |
-
+
Ctrl-F9 | Delete current order position |
-
+
Ctrl-F10 | Insert new order position |
-
+
Ctrl-F11 | Decrease
current order pattern number |
-
+
Ctrl-F12 | Increase current order pattern number |
-
+
Key below ESC (ANSI: Alt-Minus)* | Increase Add value |
-
+
Shift-key below ESC (ANSI: Alt-Plus)* | Decrease Add value |
-
+
Ctrl-F | Toggle song follow |
-
+
Ctrl-P | Toggle prospective pattern view |
-
+
Ctrl-W | Toggle pattern wrapping |
-
+
Ctrl-L | Toggle pattern change behavior (live mode) |
-
+
Shift-Ctrl-L | Load song |
-
+
Shift-R | Toggle record mode |
-
+
Shift-Ctrl-S | Save song |
-
+
Esc | Exit program |
@@ -937,217 +972,247 @@ Global:
Pattern editor:
-
- Cursor keys | Move around |
+
+ Cursor keys |
+ Move around |
-
- PageUp | Jump 16 rows up |
+
+ PageUp |
+ Jump 16 rows up |
-
- PageDown | Jump 16 rows down |
+
+ PageDown |
+ Jump 16 rows down |
-
- Home | Jump to first row |
+
+ Home |
+ Jump to first row |
-
- End | Jump to last row |
+
+ End |
+ Jump to last row |
-
- Tab | Jump to next track |
+
+ Tab |
+ Jump to next track |
-
- Shift-Tab | Jump to previous track |
+
+ Shift-Tab |
+ Jump to previous track |
-
- Alt-Q…I | Jump to track (0…7) MOD N-Channels |
+
+ Alt-Q…I |
+ Jump to track (0…7) MOD N-Channels |
-
- Alt-A…K | Jump to track (8…15) MOD N-Channels |
+
+ Alt-A…K |
+ Jump to track (8…15) MOD N-Channels |
-
- F9 | Jump to beginning of the pattern |
+
+ F9 |
+ Jump to beginning of the pattern |
-
- F10 | Jump to position ¼ through the pattern |
+
+ F10 |
+ Jump to position ¼ through the pattern |
+
+
+ F11 |
+ Jump to position halfway through the pattern |
-
- F11 | Jump to position halfway through the pattern |
+
+ F12 |
+ Jump to position ¾ through the pattern |
-
- F12 | Jump to position ¾ through the pattern |
+
+ The key right of LShift |
+ Enter key-off |
-
- The key right of LShift | Enter key-off |
+
+ Caps-Lock |
+ Enter key-off (Windows only) |
-
- Caps-Lock | Enter key-off (Windows only) |
+
+ 1 |
+ Enter key-off |
-
- 1 | Enter key-off |
+
+ Del |
+ Delete note or volume column at cursor |
-
- Del | Delete note or volume column at cursor |
+
+ Shift-Del |
+ Delete note, volume and effect at cursor |
-
- Shift-Del | Delete note, volume and effect at cursor |
+
+ Ctrl-Del |
+ Delete volume and effect at cursor |
-
- Ctrl-Del | Delete volume and effect at cursor |
+
+ Alt-Delete |
+ Delete effect at cursor |
-
- Alt-Delete | Delete effect at cursor |
+
+ Ins |
+ Insert space on current track at cursor position (F13 on mac) |
-
- Ins | Insert space on current track at cursor position (F13 on mac) |
+
+ Shift-Ins |
+ Insert row at cursor position (shift-F13 on mac) |
-
- Shift-Ins | Insert row at cursor position (shift-F13 on mac) |
+
+ Alt-Backspace |
+ Insert space on current track at cursor position (alternative for keyboards with no Insert key) |
-
- Alt-Backspace | Insert space on current track at cursor position (alternative for keyboards with no Insert key) |
+
+ Shift-Alt-Backspace |
+ Insert row at cursor position (alternative for keyboards with no Insert key) |
-
- Shift-Alt-Backspace | Insert row at cursor position (alternative for keyboards with no Insert key) |
+
+ Backspace |
+ Delete previous note |
-
- Backspace | Delete previous note |
+
+ Shift-Backspace |
+ Delete previous row |
-
- Shift-Backspace | Delete previous row |
+
+ Ctrl-Shift-V |
+ Convert current pattern to sample |
Clipboard operations:
-
+
Alt-Cursor keys | Select block |
-
+
Shift-Alt-Cursor keys | Extend block |
-
+
Alt-F3 | Cut block |
-
+
Alt-F4 | Copy block (yes, even under Windows =) |
-
+
Alt-F5 | Paste block |
-
+
Alt-F6 | Porous paste block |
-
+
Shift-F3 | Cut track |
-
+
Shift-F4 | Copy track |
-
+
Shift-F5 | Paste track |
-
+
Shift-F6 | Porous paste track |
-
+
Ctrl-F3 | Cut pattern |
-
+
Ctrl-F4 | Copy pattern |
-
+
Ctrl-F5 | Paste pattern |
-
+
Ctrl-F6 | Porous paste pattern |
Additional shortcuts (not found in FT2):
-
+
Ctrl-Alt-Z | Undo |
-
+
Ctrl-Alt-Y | Redo |
-
+
Ctrl-Alt-A | Select entire pattern |
-
+
Shift-I | Interpolate values |
Volume scaling:
-
+
Alt-V | Volume scale block |
-
+
Shift-V | Volume scale track |
-
+
Ctrl-V | Volume scale pattern |
Command/Volume macro:
-
+
Shift-Alt-1…0 | Read command/volume at cursor |
-
+
Alt-1…0 | Write command/volume at cursor |
Transpose:
-
+
Alt-F7 | Transpose current instrument in block down |
-
+
Alt-F8 | Transpose current instrument in block up |
-
+
Shift-F7 | Transpose current instrument in track down |
-
+
Shift-F8 | Transpose current instrument in track up |
-
+
Ctrl-F7 | Transpose current instrument in pattern down |
-
+
Ctrl-F8 | Transpose current instrument in pattern up |
-
+
Alt-F1 | Transpose all instruments in block down |
-
+
Alt-F2 | Transpose all instruments in block up |
-
+
Shift-F1 | Transpose all instruments in track down |
-
+
Shift-F2 | Transpose all instruments in track up |
-
+
Ctrl-F1 | Transpose all instruments in pattern down |
-
+
Ctrl-F2 | Transpose all instruments in pattern up |
Instrument selection:
-
+
Shift-Up | Select previous instrument |
-
+
Shift-Down | Select next instrument |
-
+
Ctrl-Shift-Up | Select previous sample |
-
+
Ctrl-Shift-Down | Select next sample |
@@ -1156,40 +1221,40 @@ Instrument selection:
keypad, the layout is like this:
-
+
PC | Mac |
-
+
Num 0…9 | Num 0…9 | Digit 0…9 |
-
+
Num / | Num = | Digit A |
-
+
Num * | Num / | Digit B |
-
+
Num - | Num * | Digit C |
-
+
Num + | Num - | Digit D |
-
+
Num Enter | Num + | Digit E |
-
+
Num , | Num Enter | Digit F |
Sample editor:
-
+
Shift & drag | Quick draw |
-
+
Ctrl & drag | Resize selection |
-
+
Alt & drag | Move selection or loop range |
@@ -1199,25 +1264,25 @@ Sample editor:
-
+
BPM | Traditionally Beats Per Minute, but in tracker terminology it defines the speed of ticks. |
-
+
Effect memory | When an effect command is called with 0 parameters, previous parameters are used. |
-
+
Row/line | Refers to one line of "text" on a pattern. In playback its duration depends on how many ticks there are per row (Speed) and fast they are (BPM). |
-
+
Sample fine-tune/volume/panning | Per sample default settings available through the instrument editor (thus also called instrument volume etc). Overrideable with effect commands. .MODs support these as well but with lower precision. (Save module and load back to enforce .MOD precision.) |
-
+
Tick | The base time unit in traditional trackers like MilkyTracker, originating from Amiga. Notes are triggered on the first tick of a row (unless delayed) and effects are applied on the following ticks. |
-
+
Semitone | The smallest musical interval in Western music and in MilkyTracker. A C# note is one semitone away from the note C. |
-
+
Speed (Spd.) | Number of ticks per row. |
@@ -1308,7 +1373,7 @@
y = semitone offset |
-
+
Example: |
@@ -1335,7 +1400,7 @@ Fasttracker II
|
-
+
Notes: |
In MilkyTracker you don't have to and indeed you CAN'T enter the effect digit 0. Just start with the parameter digits and the effect digit will be filled in.
@@ -1362,7 +1427,7 @@
|
xx = portamento speed |
-
+
Example: |
@@ -1385,7 +1450,7 @@ Amiga frequencies
|
-
+
Notes: |
ProTracker 2/3
@@ -1404,7 +1469,7 @@
|
xx = portamento speed |
-
+
Example: |
@@ -1421,7 +1486,7 @@
Works similarly to 1xx portamento up, only bending note pitch down instead of up.
|
-
+
Notes: |
ProTracker 2/3
@@ -1440,7 +1505,7 @@
|
xx = portamento speed |
-
+
Example: |
@@ -1472,7 +1537,7 @@
y = depth |
-
+
Example: |
@@ -1504,7 +1569,7 @@
y = volume slide down speed |
-
+
Example: |
@@ -1523,7 +1588,7 @@
|
-
+
Notes: |
ProTracker 2/3
@@ -1545,7 +1610,7 @@
|
y = volume slide down speed |
-
+
Example: |
@@ -1564,7 +1629,7 @@
|
-
+
Notes: |
ProTracker 2/3
@@ -1586,7 +1651,7 @@
|
y = depth |
-
+
Example: |
@@ -1615,7 +1680,7 @@
xx = panning position |
-
+
Example: |
@@ -1634,7 +1699,7 @@
|
-
+
Notes: |
ProTracker 2/3
@@ -1657,7 +1722,7 @@
|
xx = sample offset |
-
+
Example: |
@@ -1676,7 +1741,7 @@
|
-
+
Tips: |
Resampling a loop to exactly (0x10000=) 65536 bytes gives you the highest possible level of control over the sample.
@@ -1695,7 +1760,7 @@
|
y = volume slide down speed |
-
+
Example: |
@@ -1714,7 +1779,7 @@
|
-
+
Notes: |
@@ -1736,7 +1801,7 @@
xx = song position |
-
+
Example: |
@@ -1755,7 +1820,7 @@
|
-
+
Tips: |
@@ -1773,7 +1838,7 @@
|
xx = volume |
-
+
Example: |
@@ -1792,7 +1857,7 @@
|
-
+
Notes: |
Fasttracker II
@@ -1811,7 +1876,7 @@
|
xx = row number on next pattern |
-
+
Example: |
@@ -1830,7 +1895,7 @@
|
-
+
Notes: |
@@ -1851,7 +1916,7 @@
|
x = portamento speed |
-
+
Example: |
@@ -1880,7 +1945,7 @@
x = portamento speed |
-
+
Example: |
@@ -1909,7 +1974,7 @@
x = glissando control toggle on/off |
-
+
Example: |
@@ -1928,7 +1993,7 @@
|
-
+
Notes: |
@@ -1946,7 +2011,7 @@
|
x = vibrato waveform selection |
-
+
Example: |
@@ -1973,7 +2038,7 @@
|
-
+
Notes: |
@@ -1991,7 +2056,7 @@
|
x = fine-tune |
-
+
Example: |
@@ -2073,7 +2138,7 @@
x = set loop point / number of iterations |
-
+
Example: |
@@ -2092,7 +2157,7 @@
|
-
+
Notes: |
@@ -2117,7 +2182,7 @@
|
x = tremolo waveform selection |
-
+
Example: |
@@ -2144,7 +2209,7 @@
|
-
+
Notes: |
@@ -2162,7 +2227,7 @@
|
x = panning position |
-
+
Explanation: |
@@ -2188,7 +2253,7 @@
|
x = triggering interval |
-
+
Example: |
@@ -2217,7 +2282,7 @@
x = speed |
-
+
Example: |
@@ -2246,7 +2311,7 @@
x = speed |
-
+
Example: |
@@ -2275,7 +2340,7 @@
x = tick number |
-
+
Example: |
@@ -2304,7 +2369,7 @@
x = tick number |
-
+
Example: |
@@ -2333,7 +2398,7 @@
x = amount of rows |
-
+
Example: |
@@ -2362,7 +2427,7 @@
xx = speed/BPM value |
-
+
Example: |
@@ -2391,7 +2456,7 @@
xx = volume |
-
+
Example: |
@@ -2423,7 +2488,7 @@
y = volume slide down speed |
-
+
Example: |
@@ -2442,7 +2507,7 @@
|
-
+
Notes: |
@@ -2460,7 +2525,7 @@
|
xx = tick number |
-
+
Example: |
@@ -2489,7 +2554,7 @@
xx = envelope position |
-
+
Example: |
@@ -2522,7 +2587,7 @@
y = panning slide left speed |
-
+
Example: |
@@ -2541,7 +2606,7 @@
|
-
+
Notes: |
@@ -2562,7 +2627,7 @@
|
y = triggering interval |
-
+
Example: |
@@ -2599,7 +2664,7 @@
|
-
+
Notes: |
This command is very buggy from the start, straight from the source, Fasttracker II. While FT2's own documentation is inaccurate in many places, this is different. Extensive testing has revealed almost bizarre qualities of this effect and it's up to MilkyTracker to emulate it all. Without doubt the quirk the team has spent the most time and iterations working on getting it right. And still we advise to be careful with it. When using Rxy , check your song with FT2 (render to .WAV if you don't have the hardware (to emulate)), or at least BASS/XMPlay. And if you do find something odd, please report the bug as accurately and detailed as possible.
@@ -2630,7 +2695,7 @@
|
y + 1 = ticks off |
-
+
Example: |
@@ -2649,7 +2714,7 @@
|
-
+
Notes: |
@@ -2667,7 +2732,7 @@
|
x = speed |
-
+
Example: |
@@ -2696,7 +2761,7 @@
x = speed |
-
+
Example: |
@@ -2723,7 +2788,7 @@
Syntax: | xx = volume |
-
+
Example: |
@@ -2752,7 +2817,7 @@
x = speed |
-
+
Example: |
@@ -2781,7 +2846,7 @@
x = speed |
-
+
Example: |
@@ -2810,7 +2875,7 @@ Dx Fine volume slide down (displayed as ▼x)<
x = speed |
-
+
Example: |
@@ -2839,7 +2904,7 @@
x = speed |
-
+
Example: |
@@ -2868,7 +2933,7 @@
x = speed |
-
+
Example: |
@@ -2887,7 +2952,7 @@
|
-
+
Tips: |
@@ -2905,7 +2970,7 @@
|
x = speed |
-
+
Example: |
@@ -2924,7 +2989,7 @@
|
-
+
Tips: |
@@ -2942,7 +3007,7 @@
| x = speed |
-
+
Example: |
@@ -2971,7 +3036,7 @@
x = speed |
-
+
Example: |
@@ -3000,7 +3065,7 @@ |
-
+
Example: |
@@ -3029,7 +3094,7 @@
x = depth |
-
+
Example: |
@@ -3048,7 +3113,7 @@
|
-
+
Notes: |
@@ -3065,15 +3130,15 @@
MilkyTracker supports basic MIDI input, which means you can use your MIDI device to feed notes into MilkyTracker. Enabling MIDI input varies a little from platform to platform - here's how to do it on…
-
+
Windows: |
Select Preferences from the system menu (top left corner of the window) |
-
+
OSX: |
Select Preferences from the MilkyTracker menu or press Command-, |
-
+
Linux: |
Enabled by default if available on the system. See the Linux readme for details. |
From 50267642dffe12b6c4c2aa2144c0f110baea0d02 Mon Sep 17 00:00:00 2001
From: Christopher O'Neill
Date: Sun, 1 Aug 2021 11:04:04 +0100
Subject: [PATCH 21/30] Remove executable bit on source files
---
src/tracker/ModuleEditor.h | 0
src/tracker/SampleEditor.cpp | 0
src/tracker/SampleEditor.h | 0
src/tracker/SampleEditorControl.cpp | 0
src/tracker/SampleEditorControl.h | 0
src/tracker/SectionSamples.cpp | 0
src/tracker/Tracker.h | 0
src/tracker/TrackerKeyboard.cpp | 0
8 files changed, 0 insertions(+), 0 deletions(-)
mode change 100755 => 100644 src/tracker/ModuleEditor.h
mode change 100755 => 100644 src/tracker/SampleEditor.cpp
mode change 100755 => 100644 src/tracker/SampleEditor.h
mode change 100755 => 100644 src/tracker/SampleEditorControl.cpp
mode change 100755 => 100644 src/tracker/SampleEditorControl.h
mode change 100755 => 100644 src/tracker/SectionSamples.cpp
mode change 100755 => 100644 src/tracker/Tracker.h
mode change 100755 => 100644 src/tracker/TrackerKeyboard.cpp
diff --git a/src/tracker/ModuleEditor.h b/src/tracker/ModuleEditor.h
old mode 100755
new mode 100644
diff --git a/src/tracker/SampleEditor.cpp b/src/tracker/SampleEditor.cpp
old mode 100755
new mode 100644
diff --git a/src/tracker/SampleEditor.h b/src/tracker/SampleEditor.h
old mode 100755
new mode 100644
diff --git a/src/tracker/SampleEditorControl.cpp b/src/tracker/SampleEditorControl.cpp
old mode 100755
new mode 100644
diff --git a/src/tracker/SampleEditorControl.h b/src/tracker/SampleEditorControl.h
old mode 100755
new mode 100644
diff --git a/src/tracker/SectionSamples.cpp b/src/tracker/SectionSamples.cpp
old mode 100755
new mode 100644
diff --git a/src/tracker/Tracker.h b/src/tracker/Tracker.h
old mode 100755
new mode 100644
diff --git a/src/tracker/TrackerKeyboard.cpp b/src/tracker/TrackerKeyboard.cpp
old mode 100755
new mode 100644
From 6cac112683e92b57686536fe76e4af5909687df5 Mon Sep 17 00:00:00 2001
From: Cong
Date: Sun, 1 Aug 2021 22:57:53 +1000
Subject: [PATCH 22/30] Add absolute sine generator #239
---
src/tracker/SampleEditor.cpp | 52 +++++++++++++++++++
src/tracker/SampleEditor.h | 1 +
src/tracker/SampleEditorControl.cpp | 6 +++
src/tracker/SampleEditorControl.h | 6 ++-
.../SampleEditorControlToolHandler.cpp | 12 +++++
5 files changed, 75 insertions(+), 2 deletions(-)
diff --git a/src/tracker/SampleEditor.cpp b/src/tracker/SampleEditor.cpp
index 216238b0..35550136 100644
--- a/src/tracker/SampleEditor.cpp
+++ b/src/tracker/SampleEditor.cpp
@@ -3036,6 +3036,58 @@ void SampleEditor::tool_generateHalfSine(const FilterParameters* par)
postFilter();
}
+void SampleEditor::tool_generateAbsoluteSine(const FilterParameters* par)
+{
+ if (isEmptySample())
+ return;
+
+ pp_int32 sStart = selectionStart;
+ pp_int32 sEnd = selectionEnd;
+
+ if (hasValidSelection())
+ {
+ if (sStart >= 0 && sEnd >= 0)
+ {
+ if (sEnd < sStart)
+ {
+ pp_int32 s = sEnd; sEnd = sStart; sStart = s;
+ }
+ }
+ }
+ else
+ {
+ sStart = 0;
+ sEnd = sample->samplen;
+ }
+
+ preFilter(&SampleEditor::tool_generateAbsoluteSine, par);
+
+ mp_sint32 sLen = sEnd - sStart;
+
+ prepareUndo();
+
+ pp_int32 i;
+
+ const float numPeriods = (float)(6.283185307179586476925286766559 * par->getParameter(1).floatPart);
+ const float amplify = par->getParameter(0).floatPart;
+
+ // generate half sine wave in first and second halves
+ for (i = sStart; i < sEnd / 2; i++)
+ {
+ float per = (i - sStart) / (float)sLen * numPeriods;
+ setFloatSampleInWaveform(i, (float)sin(per) * amplify);
+ }
+ for (i = sEnd / 2; i < sEnd; i++)
+ {
+ float per = (i - sEnd / 2) / (float)sLen * numPeriods;
+ setFloatSampleInWaveform(i, (float)sin(per) * amplify);
+ }
+
+ finishUndo();
+
+ postFilter();
+}
+
bool SampleEditor::tool_canApplyLastFilter() const
{
return lastFilterFunc != NULL && isValidSample();
diff --git a/src/tracker/SampleEditor.h b/src/tracker/SampleEditor.h
index 949f98aa..62c87b6e 100644
--- a/src/tracker/SampleEditor.h
+++ b/src/tracker/SampleEditor.h
@@ -352,6 +352,7 @@ class SampleEditor : public EditorBase
void tool_generateTriangle(const FilterParameters* par);
void tool_generateSawtooth(const FilterParameters* par);
void tool_generateHalfSine(const FilterParameters* par);
+ void tool_generateAbsoluteSine(const FilterParameters* par);
void tool_applyLastFilter();
bool tool_canApplyLastFilter() const;
diff --git a/src/tracker/SampleEditorControl.cpp b/src/tracker/SampleEditorControl.cpp
index 30afb393..de6d8bae 100644
--- a/src/tracker/SampleEditorControl.cpp
+++ b/src/tracker/SampleEditorControl.cpp
@@ -161,6 +161,7 @@ SampleEditorControl::SampleEditorControl(pp_int32 id,
subMenuGenerators->addEntry("Triangle" PPSTR_PERIODS, MenuCommandIDGenerateTriangle);
subMenuGenerators->addEntry("Sawtooth" PPSTR_PERIODS, MenuCommandIDGenerateSawtooth);
subMenuGenerators->addEntry("Half Sine" PPSTR_PERIODS, MenuCommandIDGenerateHalfSine);
+ subMenuGenerators->addEntry("Absolute Sine" PPSTR_PERIODS, MenuCommandIDGenerateAbsoluteSine);
subMenuGenerators->addEntry("Silence" PPSTR_PERIODS, MenuCommandIDGenerateSilence);
// build context menu
@@ -1715,6 +1716,7 @@ void SampleEditorControl::invokeContextMenu(const PPPoint& p, bool translatePoin
subMenuGenerators->setState(MenuCommandIDGenerateTriangle, isEmptySample);
subMenuGenerators->setState(MenuCommandIDGenerateSawtooth, isEmptySample);
subMenuGenerators->setState(MenuCommandIDGenerateHalfSine, isEmptySample);
+ subMenuGenerators->setState(MenuCommandIDGenerateAbsoluteSine, isEmptySample);
subMenuGenerators->setState(MenuCommandIDGenerateSilence, isEmptySample);
parentScreen->setContextMenuControl(editMenuControl);
@@ -1901,6 +1903,10 @@ void SampleEditorControl::executeMenuCommand(pp_int32 commandId)
invokeToolParameterDialog(ToolHandlerResponder::SampleToolTypeGenerateHalfSine);
break;
+ case MenuCommandIDGenerateAbsoluteSine:
+ invokeToolParameterDialog(ToolHandlerResponder::SampleToolTypeGenerateAbsoluteSine);
+ break;
+
}
}
diff --git a/src/tracker/SampleEditorControl.h b/src/tracker/SampleEditorControl.h
index 26b12404..570aabcc 100644
--- a/src/tracker/SampleEditorControl.h
+++ b/src/tracker/SampleEditorControl.h
@@ -308,7 +308,8 @@ class SampleEditorControl : public PPControl, public EventListenerInterface, pub
MenuCommandIDGenerateSquare,
MenuCommandIDGenerateTriangle,
MenuCommandIDGenerateSawtooth,
- MenuCommandIDGenerateHalfSine
+ MenuCommandIDGenerateHalfSine,
+ MenuCommandIDGenerateAbsoluteSine
};
void executeMenuCommand(pp_int32 commandId);
@@ -353,7 +354,8 @@ class SampleEditorControl : public PPControl, public EventListenerInterface, pub
SampleToolTypeGenerateSquare,
SampleToolTypeGenerateTriangle,
SampleToolTypeGenerateSawtooth,
- SampleToolTypeGenerateHalfSine
+ SampleToolTypeGenerateHalfSine,
+ SampleToolTypeGenerateAbsoluteSine
};
private:
diff --git a/src/tracker/SampleEditorControlToolHandler.cpp b/src/tracker/SampleEditorControlToolHandler.cpp
index 703052f3..366c6c04 100644
--- a/src/tracker/SampleEditorControlToolHandler.cpp
+++ b/src/tracker/SampleEditorControlToolHandler.cpp
@@ -154,6 +154,7 @@ bool SampleEditorControl::invokeToolParameterDialog(SampleEditorControl::ToolHan
case ToolHandlerResponder::SampleToolTypeGenerateTriangle:
case ToolHandlerResponder::SampleToolTypeGenerateSawtooth:
case ToolHandlerResponder::SampleToolTypeGenerateHalfSine:
+ case ToolHandlerResponder::SampleToolTypeGenerateAbsoluteSine:
{
dialog = new DialogWithValues(parentScreen, toolHandlerResponder, PP_DEFAULT_ID, "Generate waveform" PPSTR_PERIODS, DialogWithValues::ValueStyleEnterTwoValues);
static_cast(dialog)->setValueOneCaption("Volume in percent:");
@@ -344,6 +345,17 @@ bool SampleEditorControl::invokeTool(ToolHandlerResponder::SampleToolTypes type)
break;
}
+ case ToolHandlerResponder::SampleToolTypeGenerateAbsoluteSine:
+ {
+ lastValues.waveFormVolume = static_cast(dialog)->getValueOne();
+ lastValues.waveFormNumPeriods = static_cast(dialog)->getValueTwo();
+ FilterParameters par(2);
+ par.setParameter(0, FilterParameters::Parameter(lastValues.waveFormVolume / 100.0f));
+ par.setParameter(1, FilterParameters::Parameter(lastValues.waveFormNumPeriods));
+ sampleEditor->tool_generateAbsoluteSine(&par);
+ break;
+ }
+
default:
break;
}
From d9fe42ca254fbe66eb11d3dd8ee4e4e8bd17047c Mon Sep 17 00:00:00 2001
From: Peter Barth <69579956+peterbart-lmi@users.noreply.github.com>
Date: Sun, 29 Aug 2021 21:55:56 +0200
Subject: [PATCH 23/30] Feature: Add 9xx adjustment option to sample resampler
(#247)
* feat: Add an option to the sample resampler so it's possible to automatically adjust sample offset (9xx) commands
---
src/tracker/DialogResample.cpp | 38 +++++++---
src/tracker/DialogResample.h | 9 ++-
src/tracker/ModuleEditor.cpp | 75 +++++++++++++++++++
src/tracker/ModuleEditor.h | 2 +
src/tracker/SampleEditor.cpp | 12 +++
src/tracker/SampleEditor.h | 4 +
src/tracker/SampleEditorControlLastValues.h | 10 ++-
.../SampleEditorControlToolHandler.cpp | 4 +-
8 files changed, 141 insertions(+), 13 deletions(-)
diff --git a/src/tracker/DialogResample.cpp b/src/tracker/DialogResample.cpp
index d2d4ac3b..06e4e07b 100644
--- a/src/tracker/DialogResample.cpp
+++ b/src/tracker/DialogResample.cpp
@@ -94,12 +94,13 @@ DialogResample::DialogResample(PPScreen* screen,
count(0),
resamplerHelper(new ResamplerHelper()),
interpolationType(1),
- adjustFtAndRelnote(true)
+ adjustFtAndRelnote(true),
+ adjustSampleOffsetCommand(false)
{
#ifdef __LOWRES__
- initDialog(screen, responder, id, "Resample" PPSTR_PERIODS, 290, 142+15+20+16, 26+15, "Ok", "Cancel");
+ initDialog(screen, responder, id, "Resample" PPSTR_PERIODS, 290, 158+15+20+16, 26+15, "Ok", "Cancel");
#else
- initDialog(screen, responder, id, "Resample" PPSTR_PERIODS, 290, 142+20+16, 26, "Ok", "Cancel");
+ initDialog(screen, responder, id, "Resample" PPSTR_PERIODS, 290, 158+20+16, 26, "Ok", "Cancel");
#endif
pp_int32 x = getMessageBoxContainer()->getLocation().x;
@@ -200,13 +201,23 @@ DialogResample::DialogResample(PPScreen* screen,
y2+=16;
x2 = x + width / 2 - (10 * 8 + 35 + 14 * 8) / 2 + 21 * 8;
- checkBox = new PPCheckBox(MESSAGEBOX_CONTROL_USER2, screen, this, PPPoint(x2, y2 + 1));
- checkBox->checkIt(adjustFtAndRelnote);
- messageBoxContainerGeneric->addControl(checkBox);
+ checkBoxAdjustFtAndRelnote = new PPCheckBox(MESSAGEBOX_CONTROL_USER2, screen, this, PPPoint(x2, y2 + 1));
+ checkBoxAdjustFtAndRelnote->checkIt(adjustFtAndRelnote);
+ messageBoxContainerGeneric->addControl(checkBoxAdjustFtAndRelnote);
x2 -= 21 * 8;
- messageBoxContainerGeneric->addControl(new PPCheckBoxLabel(0, screen, this, PPPoint(x2, y2 + 2), "Adjust Ft/Rel.Note:", checkBox, true));
-
+ messageBoxContainerGeneric->addControl(new PPCheckBoxLabel(0, screen, this, PPPoint(x2, y2 + 2), "Adjust Ft/Rel.Note:", checkBoxAdjustFtAndRelnote, true));
+
+ y2+=16;
+
+ x2 = x + width / 2 - (10 * 8 + 35 + 14 * 8) / 2 + 21 * 8;
+ checkBoxAdjustSampleOffsetCommand = new PPCheckBox(MESSAGEBOX_CONTROL_USER3, screen, this, PPPoint(x2, y2 + 1));
+ checkBoxAdjustSampleOffsetCommand->checkIt(adjustSampleOffsetCommand);
+ messageBoxContainerGeneric->addControl(checkBoxAdjustSampleOffsetCommand);
+
+ x2 -= 21 * 8;
+ messageBoxContainerGeneric->addControl(new PPCheckBoxLabel(0, screen, this, PPPoint(x2, y2 + 2), "Adjust 9xx commands:", checkBoxAdjustSampleOffsetCommand, true));
+
y2+=16;
#ifdef __LOWRES__
@@ -372,6 +383,14 @@ pp_int32 DialogResample::handleEvent(PPObject* sender, PPEvent* event)
break;
}
+ case MESSAGEBOX_CONTROL_USER3:
+ {
+ if (event->getID() != eCommand)
+ break;
+
+ this->adjustSampleOffsetCommand = reinterpret_cast(sender)->isChecked();
+ break;
+ }
}
}
else if (event->getID() == eValueChanged)
@@ -422,7 +441,8 @@ void DialogResample::updateListBoxes()
PPStaticText* staticText = static_cast(messageBoxContainerGeneric->getControlByID(MESSAGEBOX_STATICTEXT_USER1));
staticText->setHexValue(finalSize, 8);
- checkBox->checkIt(adjustFtAndRelnote);
+ checkBoxAdjustFtAndRelnote->checkIt(adjustFtAndRelnote);
+ checkBoxAdjustSampleOffsetCommand->checkIt(adjustSampleOffsetCommand);
}
void DialogResample::updateListBox(pp_int32 id, float val, pp_int32 numDecimals)
diff --git a/src/tracker/DialogResample.h b/src/tracker/DialogResample.h
index 785b26fa..d63d6dac 100644
--- a/src/tracker/DialogResample.h
+++ b/src/tracker/DialogResample.h
@@ -37,7 +37,8 @@ class DialogResample : public PPDialogBase
{
private:
class PPListBox* listBoxes[3];
- class PPCheckBox* checkBox;
+ class PPCheckBox* checkBoxAdjustFtAndRelnote;
+ class PPCheckBox* checkBoxAdjustSampleOffsetCommand;
pp_int32 currentSelectedListBox;
pp_int32 relnote, finetune;
pp_uint32 size, finalSize;
@@ -48,6 +49,7 @@ class DialogResample : public PPDialogBase
class ResamplerHelper* resamplerHelper;
pp_int32 interpolationType;
bool adjustFtAndRelnote;
+ bool adjustSampleOffsetCommand;
public:
DialogResample(PPScreen* screen,
@@ -74,7 +76,10 @@ class DialogResample : public PPDialogBase
void setAdjustFtAndRelnote(bool adjustFtAndRelnote) { this->adjustFtAndRelnote = adjustFtAndRelnote; }
bool getAdjustFtAndRelnote() const { return adjustFtAndRelnote; }
-
+
+ void setAdjustSampleOffsetCommand(bool adjustSampleOffsetCommand) { this->adjustSampleOffsetCommand = adjustSampleOffsetCommand; }
+ bool getAdjustSampleOffsetCommand() const { return adjustSampleOffsetCommand; }
+
private:
void listBoxEnterEditState(pp_int32 id);
diff --git a/src/tracker/ModuleEditor.cpp b/src/tracker/ModuleEditor.cpp
index fa930997..eb5df129 100644
--- a/src/tracker/ModuleEditor.cpp
+++ b/src/tracker/ModuleEditor.cpp
@@ -21,9 +21,11 @@
*/
#include
+#include
#include "ModuleEditor.h"
#include "PatternEditor.h"
#include "SampleEditor.h"
+#include "FilterParameters.h"
#include "EnvelopeEditor.h"
#include "ModuleServices.h"
#include "PlayerCriticalSection.h"
@@ -75,7 +77,17 @@ class ChangesListener : public EditorBase::EditorNotificationListener
case EditorBase::NotificationChanges:
{
if (sender == moduleEditor.sampleEditor)
+ {
moduleEditor.finishSamples();
+ if (moduleEditor.sampleEditor->isLastOperationResampling())
+ {
+ const bool adjustSampleOffsetCommand = moduleEditor.sampleEditor->getLastParameters()->getParameter(3).intPart;
+ if (adjustSampleOffsetCommand)
+ {
+ moduleEditor.adjustSampleOffsetCommandAfterSampleSizeChange(moduleEditor.sampleEditor->getSample(), moduleEditor.sampleEditor->getUndoSample()->getSampLen());
+ }
+ }
+ }
moduleEditor.setChanged();
break;
}
@@ -2463,6 +2475,69 @@ void ModuleEditor::optimizeSamples(bool convertTo8Bit, bool minimize,
changed = true;
}
+void ModuleEditor::adjustSampleOffsetCommandAfterSampleSizeChange(TXMSample *sample, pp_int32 oldSize)
+{
+ mp_sint32 i,j;
+
+ mp_ubyte* lastIns = new mp_ubyte[module->header.channum];
+ memset(lastIns, 0, module->header.channum);
+
+ for (mp_sint32 l = 0; l < module->header.ordnum; l++)
+ {
+ TXMPattern* pattern = &module->phead[module->header.ord[l]];
+
+ if (pattern->patternData == NULL)
+ continue;
+
+ mp_sint32 slotSize = pattern->effnum * 2 + 2;
+ mp_sint32 rowSizeSrc = slotSize*pattern->channum;
+
+ for (i = 0; i < pattern->rows; i++)
+ {
+ for (j = 0; j < pattern->channum; j++)
+ {
+ mp_ubyte* src = pattern->patternData + i*rowSizeSrc+j*slotSize;
+
+ if (src[1])
+ {
+ lastIns[j] = src[1];
+ }
+
+
+ if (src[0] && src[0] < 120)
+ {
+ for (mp_sint32 k = 0; k < pattern->effnum; k++) {
+ if (src[k * 2 + 2] == 0x9) {
+
+ mp_sint32 op = src[k * 2 + 3];
+ if (lastIns[j])
+ {
+ mp_sint32 insIndex = lastIns[j] - 1;
+
+ mp_sint32 smpIndex = module->instr[insIndex].snum[src[0]-1];
+
+ if (smpIndex >= 0 && smpIndex < MP_MAXSAMPLES)
+ {
+ if (&module->smp[smpIndex] == sample)
+ {
+ const float factor = (float)sample->samplen / (float)oldSize;
+ op = (mp_sint32)roundf(op * factor);
+ if (op > 255) {
+ op = 255;
+ }
+ src[k * 2 + 3] = (mp_ubyte)op;
+ }
+ }
+ }
+
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
void ModuleEditor::insertText(char* dst, const char* src, mp_sint32 max)
{
char name[MP_MAXTEXT+1];
diff --git a/src/tracker/ModuleEditor.h b/src/tracker/ModuleEditor.h
index 3519362c..773ba164 100644
--- a/src/tracker/ModuleEditor.h
+++ b/src/tracker/ModuleEditor.h
@@ -379,6 +379,8 @@ class ModuleEditor
void optimizeSamples(bool convertTo8Bit, bool minimize,
mp_sint32& numConvertedSamples, mp_sint32& numMinimizedSamples,
bool evaluate);
+
+ void adjustSampleOffsetCommandAfterSampleSizeChange(TXMSample *sample, pp_int32 oldSize);
public:
static void insertText(char* dst, const char* src, mp_sint32 max);
diff --git a/src/tracker/SampleEditor.cpp b/src/tracker/SampleEditor.cpp
index 35550136..4624184b 100644
--- a/src/tracker/SampleEditor.cpp
+++ b/src/tracker/SampleEditor.cpp
@@ -804,6 +804,18 @@ pp_int32 SampleEditor::getPanning() const
return sample ? sample->pan : 0;
}
+bool SampleEditor::isLastOperationResampling() const {
+ return lastFilterFunc == &SampleEditor::tool_resampleSample;
+}
+
+const FilterParameters* SampleEditor::getLastParameters() const {
+ return lastParameters;
+}
+
+const SampleUndoStackEntry* SampleEditor::getUndoSample() const {
+ return before;
+}
+
void SampleEditor::startDrawing()
{
if (sample)
diff --git a/src/tracker/SampleEditor.h b/src/tracker/SampleEditor.h
index 62c87b6e..a516c967 100644
--- a/src/tracker/SampleEditor.h
+++ b/src/tracker/SampleEditor.h
@@ -239,6 +239,10 @@ class SampleEditor : public EditorBase
bool isEmpty() const { if (sample && !sample->sample) return true; else return false; }
+ bool isLastOperationResampling() const;
+ const FilterParameters* getLastParameters() const;
+ const SampleUndoStackEntry* getUndoSample() const;
+
void startDrawing();
bool isDrawing() const { return drawing; }
void drawSample(pp_int32 sampleIndex, float s);
diff --git a/src/tracker/SampleEditorControlLastValues.h b/src/tracker/SampleEditorControlLastValues.h
index 7b58516d..118e7e49 100644
--- a/src/tracker/SampleEditorControlLastValues.h
+++ b/src/tracker/SampleEditorControlLastValues.h
@@ -47,6 +47,7 @@ struct SampleEditorControlLastValues
pp_int32 resampleInterpolationType;
bool adjustFtAndRelnote;
+ bool adjustSampleOffsetCommand;
static float invalidFloatValue()
{
@@ -72,6 +73,7 @@ struct SampleEditorControlLastValues
hasEQ3BandValues = hasEQ10BandValues = false;
resampleInterpolationType = invalidIntValue();
adjustFtAndRelnote = true;
+ adjustSampleOffsetCommand = false;
}
PPDictionary convertToDictionary()
@@ -97,6 +99,8 @@ struct SampleEditorControlLastValues
result.store("resampleInterpolationType", resampleInterpolationType);
result.store("adjustFtAndRelnote", adjustFtAndRelnote);
+
+ result.store("adjustSampleOffsetCommands", adjustSampleOffsetCommand);
return result;
}
@@ -149,7 +153,11 @@ struct SampleEditorControlLastValues
{
adjustFtAndRelnote = key->getBoolValue();
}
-
+ else if (key->getKey().compareToNoCase("adjustSampleOffsetCommands") == 0)
+ {
+ adjustSampleOffsetCommand = key->getBoolValue();
+ }
+
key = dictionary.getNextKey();
}
}
diff --git a/src/tracker/SampleEditorControlToolHandler.cpp b/src/tracker/SampleEditorControlToolHandler.cpp
index 366c6c04..675d0b55 100644
--- a/src/tracker/SampleEditorControlToolHandler.cpp
+++ b/src/tracker/SampleEditorControlToolHandler.cpp
@@ -234,11 +234,13 @@ bool SampleEditorControl::invokeTool(ToolHandlerResponder::SampleToolTypes type)
{
lastValues.resampleInterpolationType = static_cast(dialog)->getInterpolationType();
lastValues.adjustFtAndRelnote = static_cast(dialog)->getAdjustFtAndRelnote();
+ lastValues.adjustSampleOffsetCommand = static_cast(dialog)->getAdjustSampleOffsetCommand();
- FilterParameters par(3);
+ FilterParameters par(4);
par.setParameter(0, FilterParameters::Parameter(static_cast(dialog)->getC4Speed()));
par.setParameter(1, FilterParameters::Parameter(static_cast(lastValues.resampleInterpolationType)));
par.setParameter(2, FilterParameters::Parameter(lastValues.adjustFtAndRelnote ? 1 : 0));
+ par.setParameter(3, FilterParameters::Parameter(lastValues.adjustSampleOffsetCommand ? 1 : 0));
sampleEditor->tool_resampleSample(&par);
break;
}
From 3533e5d836e3ac642b277b0a96ba044a9af5d8d4 Mon Sep 17 00:00:00 2001
From: Peter Barth
Date: Sun, 29 Aug 2021 22:26:56 +0200
Subject: [PATCH 24/30] feat: Add tracker string parameter to
saveExtendedModule function
---
src/milkyplay/ExporterXM.cpp | 21 ++++++++++++++-------
src/milkyplay/XModule.h | 2 +-
src/tracker/ModuleEditor.cpp | 6 +++---
3 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/src/milkyplay/ExporterXM.cpp b/src/milkyplay/ExporterXM.cpp
index 865f0cee..a59b0141 100644
--- a/src/milkyplay/ExporterXM.cpp
+++ b/src/milkyplay/ExporterXM.cpp
@@ -1341,7 +1341,7 @@ static void sort(mp_sword* array,mp_sint32 l, mp_sint32 r)
if (i 20 ? 20 : len);
+ f.write(trackerStringBuffer, 1, 20);
+ }
+ else
+ {
+ f.write(header.tracker, 1, 20);
+ }
+
header.ver = 0x104;
f.writeWord(header.ver);
header.hdrsize = 276;
diff --git a/src/milkyplay/XModule.h b/src/milkyplay/XModule.h
index 4f04a2d2..67457faa 100644
--- a/src/milkyplay/XModule.h
+++ b/src/milkyplay/XModule.h
@@ -640,7 +640,7 @@ class XModule
///////////////////////////////////////////////////
// Module exporters //
///////////////////////////////////////////////////
- mp_sint32 saveExtendedModule(const SYSCHAR* fileName); // FT2 (.XM)
+ mp_sint32 saveExtendedModule(const SYSCHAR* fileName, const char* trackerString = NULL); // FT2 (.XM)
mp_sint32 saveProtrackerModule(const SYSCHAR* fileName); // Protracker compatible (.MOD)
///////////////////////////////////////////////////
diff --git a/src/tracker/ModuleEditor.cpp b/src/tracker/ModuleEditor.cpp
index eb5df129..f5dda8e9 100644
--- a/src/tracker/ModuleEditor.cpp
+++ b/src/tracker/ModuleEditor.cpp
@@ -31,6 +31,7 @@
#include "PlayerCriticalSection.h"
#include "TrackerConfig.h"
#include "PPSystem.h"
+#include "version.h"
static const char validCharacters[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_!.";
@@ -787,7 +788,7 @@ bool ModuleEditor::saveSong(const SYSCHAR* fileName, ModSaveTypes saveType/* = e
{
case ModSaveTypeDefault:
case ModSaveTypeXM:
- res = module->saveExtendedModule(fileName) == 0;
+ res = module->saveExtendedModule(fileName, MILKYTRACKER_VERSION_STRING) == 0;
break;
case ModSaveTypeMOD:
@@ -809,10 +810,9 @@ bool ModuleEditor::saveSong(const SYSCHAR* fileName, ModSaveTypes saveType/* = e
mp_sint32 ModuleEditor::saveBackup(const SYSCHAR* fileName)
{
- return module->saveExtendedModule(fileName);
+ return module->saveExtendedModule(fileName, MILKYTRACKER_VERSION_STRING);
}
-
void ModuleEditor::increaseSongLength()
{
if (module->header.ordnum < 255)
From 4f97b7011b20519890e30368e2c2cf17c81020b6 Mon Sep 17 00:00:00 2001
From: Johannes Schultz
Date: Sat, 15 Jan 2022 00:38:13 +0100
Subject: [PATCH 25/30] Fix various heap corruptions and crashes in PSM loader
---
src/milkyplay/LoaderPSM.cpp | 41 +++++++++++++++++++++----------------
1 file changed, 23 insertions(+), 18 deletions(-)
diff --git a/src/milkyplay/LoaderPSM.cpp b/src/milkyplay/LoaderPSM.cpp
index 81aa1923..ea27593c 100644
--- a/src/milkyplay/LoaderPSM.cpp
+++ b/src/milkyplay/LoaderPSM.cpp
@@ -70,6 +70,7 @@ static bool PATTTest(mp_ubyte* p, mp_sint32& size)
patterns[i] = NULL; \
} \
delete[] patterns; \
+ delete[] patternSizes; \
}
const char* LoaderPSMv2::identifyModule(const mp_ubyte* buffer)
@@ -487,29 +488,32 @@ mp_sint32 LoaderPSMv2::load(XMFileBase& f, XModule* module)
mp_sint32 offset = 6+patIDSize;
mp_ubyte* packed = patterns[i]+offset;
-
mp_uint32 index = 0;
mp_uint32 row = 0;
-
+ mp_uint32 numRows = LittleEndian::GET_WORD(patterns[i] + offset - 2);
+ if (numRows > 256)
+ {
+ RELEASE_PATTERNS;
+ return MP_OUT_OF_MEMORY;
+ }
+
mp_uint32 maxChannels = 0;
- while (index<(patternSizes[i]-offset))
+ while (index<(patternSizes[i]-offset) && row < numRows)
{
- mp_uint32 size = ((mp_uword)LittleEndian::GET_WORD(packed+index))-2;
- index+=2; // advance pointer
-
+ mp_uint32 size = ((mp_uword)LittleEndian::GET_WORD(packed+index));
mp_uint32 dstIndex = index+size;
-
- if (size)
+ index += 2; // advance pointer
+
+ if (size > 2)
{
-
do {
mp_ubyte pi = packed[index++];
- mp_uint32 chn = packed[index++];
+ mp_uint32 chn = packed[index++] & 0x1F;
if (chn>maxChannels)
maxChannels = chn;
@@ -553,7 +557,11 @@ mp_sint32 LoaderPSMv2::load(XMFileBase& f, XModule* module)
}
else if (slot[3] == 0x2D)
{
- slot[4] = packed[index+=3];
+ slot[4] = packed[index+=3]; // ???
+ }
+ else if (slot[3] == 0x33)
+ {
+ index++;
}
}
@@ -564,12 +572,12 @@ mp_sint32 LoaderPSMv2::load(XMFileBase& f, XModule* module)
if (index!=dstIndex)
printf("nagnag ");
#endif
-
+ index = dstIndex;
+
}
- row++;
+ row++;
}
- delete[] patternSizes;
maxChannels++;
@@ -577,7 +585,7 @@ mp_sint32 LoaderPSMv2::load(XMFileBase& f, XModule* module)
maxChannels = header->channum;
// convert pattern here:
- phead[i].rows = (mp_uword)LittleEndian::GET_WORD(patterns[i]+offset-2);
+ phead[i].rows = (mp_uword)numRows;
phead[i].effnum = 3;
phead[i].channum = maxChannels;
@@ -585,7 +593,6 @@ mp_sint32 LoaderPSMv2::load(XMFileBase& f, XModule* module)
if (phead[i].patternData == NULL)
{
- delete[] pattern;
RELEASE_PATTERNS;
return MP_OUT_OF_MEMORY;
}
@@ -839,8 +846,6 @@ mp_sint32 LoaderPSMv2::load(XMFileBase& f, XModule* module)
}
- delete[] pattern;
-
RELEASE_PATTERNS;
header->smpnum = smpIndex;
From 9647e01292e254dfeb868a28659dbc7dd0e7b7cb Mon Sep 17 00:00:00 2001
From: j v
Date: Mon, 11 Apr 2022 11:36:43 -0700
Subject: [PATCH 26/30] Fix missing argument to SampleEditorControl
---
src/tracker/SectionSamples.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/tracker/SectionSamples.cpp b/src/tracker/SectionSamples.cpp
index 8a78f1bb..c3753bb5 100644
--- a/src/tracker/SectionSamples.cpp
+++ b/src/tracker/SectionSamples.cpp
@@ -759,7 +759,7 @@ void SectionSamples::init(pp_int32 x, pp_int32 y)
PPContainer* sampleEditorContainer = new PPContainer(CONTAINER_SAMPLEEDITOR, screen, this, PPPoint(x, y), PPSize(320, 92), false);
sampleEditorContainer->setColor(TrackerConfig::colorThemeMain);
- sampleEditorControl = new SampleEditorControl(SAMPLE_EDITOR, screen, this, PPPoint(x+2, y+2), PPSize(316, 92-4));
+ sampleEditorControl = new SampleEditorControl(SAMPLE_EDITOR, screen, this, PPPoint(x+2, y+2), PPSize(316, 92-4), tracker);
sampleEditorControl->attachSampleEditor(tracker.moduleEditor->getSampleEditor());
sampleEditorControl->setBorderColor(TrackerConfig::colorThemeMain);
From 3a5474f9102cbdc10fbd9e7b1b2c8d3f3f45d91b Mon Sep 17 00:00:00 2001
From: Johannes Schultz
Date: Sun, 26 Jun 2022 17:53:59 +0200
Subject: [PATCH 27/30] Fix possible stack corruption with XM instrument
headers claiming a size of less than 4
Closes #275
---
src/milkyplay/LoaderXM.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/milkyplay/LoaderXM.cpp b/src/milkyplay/LoaderXM.cpp
index f87f5c11..303e3493 100644
--- a/src/milkyplay/LoaderXM.cpp
+++ b/src/milkyplay/LoaderXM.cpp
@@ -478,7 +478,7 @@ mp_sint32 LoaderXM::load(XMFileBase& f, XModule* module)
f.readDwords(&instr[y].size,1);
- if (instr[y].size < 29)
+ if (instr[y].size >= 4 && instr[y].size < 29)
{
mp_ubyte buffer[29];
memset(buffer, 0, sizeof(buffer));
From 3c60de3b4376df1d105a9efaf581b9adf8d3ab36 Mon Sep 17 00:00:00 2001
From: nyanpasu64
Date: Wed, 13 Jul 2022 05:11:41 -0700
Subject: [PATCH 28/30] Fix About screen crash caused by missing null
terminator (#255)
---
src/tracker/AnimatedFXControl.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/tracker/AnimatedFXControl.cpp b/src/tracker/AnimatedFXControl.cpp
index 010ba7b1..8693085c 100644
--- a/src/tracker/AnimatedFXControl.cpp
+++ b/src/tracker/AnimatedFXControl.cpp
@@ -141,6 +141,7 @@ AnimatedFXControl::AnimatedFXControl(pp_int32 id,
textBufferMaxChars = visibleWidth*2 / font->getCharWidth();
textBuffer = new char[textBufferMaxChars + 1];
+ textBuffer[textBufferMaxChars] = '\0';
currentCharIndex = 0;
pp_int32 j = currentCharIndex % strlen(text);
From 59f01750f1492fe4f558f73813b056303a9fafe0 Mon Sep 17 00:00:00 2001
From: Cong
Date: Wed, 13 Jul 2022 22:14:30 +1000
Subject: [PATCH 29/30] Add quarter sine generator #239 (#250)
Also fix half sine and absolute sine generator ranges
---
src/tracker/SampleEditor.cpp | 67 +++++++++++++++++--
src/tracker/SampleEditor.h | 1 +
src/tracker/SampleEditorControl.cpp | 6 ++
src/tracker/SampleEditorControl.h | 6 +-
.../SampleEditorControlToolHandler.cpp | 12 ++++
5 files changed, 84 insertions(+), 8 deletions(-)
diff --git a/src/tracker/SampleEditor.cpp b/src/tracker/SampleEditor.cpp
index 4624184b..792f36c9 100644
--- a/src/tracker/SampleEditor.cpp
+++ b/src/tracker/SampleEditor.cpp
@@ -3033,12 +3033,12 @@ void SampleEditor::tool_generateHalfSine(const FilterParameters* par)
const float amplify = par->getParameter(0).floatPart;
// generate half sine wave here
- for (i = sStart; i < sEnd / 2; i++)
+ for (i = sStart; i < sStart + sLen / 2; i++)
{
float per = (i - sStart) / (float)sLen * numPeriods;
setFloatSampleInWaveform(i, (float)sin(per) * amplify);
}
- for (i = sEnd / 2; i < sEnd; i++)
+ for (; i < sEnd; i++)
{
setFloatSampleInWaveform(i, 0);
}
@@ -3083,17 +3083,72 @@ void SampleEditor::tool_generateAbsoluteSine(const FilterParameters* par)
const float numPeriods = (float)(6.283185307179586476925286766559 * par->getParameter(1).floatPart);
const float amplify = par->getParameter(0).floatPart;
- // generate half sine wave in first and second halves
- for (i = sStart; i < sEnd / 2; i++)
+ // generate absolute sine wave here
+ for (i = sStart; i < sEnd; i++)
+ {
+ float per = (i - sStart) / (float)sLen * numPeriods;
+ setFloatSampleInWaveform(i, fabs((float)sin(per) * amplify));
+ }
+
+ finishUndo();
+
+ postFilter();
+}
+
+void SampleEditor::tool_generateQuarterSine(const FilterParameters* par)
+{
+ if (isEmptySample())
+ return;
+
+ pp_int32 sStart = selectionStart;
+ pp_int32 sEnd = selectionEnd;
+
+ if (hasValidSelection())
+ {
+ if (sStart >= 0 && sEnd >= 0)
+ {
+ if (sEnd < sStart)
+ {
+ pp_int32 s = sEnd; sEnd = sStart; sStart = s;
+ }
+ }
+ }
+ else
+ {
+ sStart = 0;
+ sEnd = sample->samplen;
+ }
+
+ preFilter(&SampleEditor::tool_generateQuarterSine, par);
+
+ mp_sint32 sLen = sEnd - sStart;
+
+ prepareUndo();
+
+ pp_int32 i;
+
+ const float numPeriods = (float)(6.283185307179586476925286766559 * par->getParameter(1).floatPart);
+ const float amplify = par->getParameter(0).floatPart;
+
+ // generate quarter sine wave in first and third quarters
+ for (i = sStart; i < sStart + sLen / 4; i++)
{
float per = (i - sStart) / (float)sLen * numPeriods;
setFloatSampleInWaveform(i, (float)sin(per) * amplify);
}
- for (i = sEnd / 2; i < sEnd; i++)
+ for (; i < sStart + sLen / 2; i++)
{
- float per = (i - sEnd / 2) / (float)sLen * numPeriods;
+ setFloatSampleInWaveform(i, 0);
+ }
+ for (; i < sStart + sLen * 3 / 4; i++)
+ {
+ float per = (i - (sStart + sLen / 2)) / (float)sLen * numPeriods;
setFloatSampleInWaveform(i, (float)sin(per) * amplify);
}
+ for (; i < sEnd; i++)
+ {
+ setFloatSampleInWaveform(i, 0);
+ }
finishUndo();
diff --git a/src/tracker/SampleEditor.h b/src/tracker/SampleEditor.h
index a516c967..8757eeff 100644
--- a/src/tracker/SampleEditor.h
+++ b/src/tracker/SampleEditor.h
@@ -357,6 +357,7 @@ class SampleEditor : public EditorBase
void tool_generateSawtooth(const FilterParameters* par);
void tool_generateHalfSine(const FilterParameters* par);
void tool_generateAbsoluteSine(const FilterParameters* par);
+ void tool_generateQuarterSine(const FilterParameters* par);
void tool_applyLastFilter();
bool tool_canApplyLastFilter() const;
diff --git a/src/tracker/SampleEditorControl.cpp b/src/tracker/SampleEditorControl.cpp
index de6d8bae..a6b6e407 100644
--- a/src/tracker/SampleEditorControl.cpp
+++ b/src/tracker/SampleEditorControl.cpp
@@ -162,6 +162,7 @@ SampleEditorControl::SampleEditorControl(pp_int32 id,
subMenuGenerators->addEntry("Sawtooth" PPSTR_PERIODS, MenuCommandIDGenerateSawtooth);
subMenuGenerators->addEntry("Half Sine" PPSTR_PERIODS, MenuCommandIDGenerateHalfSine);
subMenuGenerators->addEntry("Absolute Sine" PPSTR_PERIODS, MenuCommandIDGenerateAbsoluteSine);
+ subMenuGenerators->addEntry("Quarter Sine" PPSTR_PERIODS, MenuCommandIDGenerateQuarterSine);
subMenuGenerators->addEntry("Silence" PPSTR_PERIODS, MenuCommandIDGenerateSilence);
// build context menu
@@ -1717,6 +1718,7 @@ void SampleEditorControl::invokeContextMenu(const PPPoint& p, bool translatePoin
subMenuGenerators->setState(MenuCommandIDGenerateSawtooth, isEmptySample);
subMenuGenerators->setState(MenuCommandIDGenerateHalfSine, isEmptySample);
subMenuGenerators->setState(MenuCommandIDGenerateAbsoluteSine, isEmptySample);
+ subMenuGenerators->setState(MenuCommandIDGenerateQuarterSine, isEmptySample);
subMenuGenerators->setState(MenuCommandIDGenerateSilence, isEmptySample);
parentScreen->setContextMenuControl(editMenuControl);
@@ -1907,6 +1909,10 @@ void SampleEditorControl::executeMenuCommand(pp_int32 commandId)
invokeToolParameterDialog(ToolHandlerResponder::SampleToolTypeGenerateAbsoluteSine);
break;
+ case MenuCommandIDGenerateQuarterSine:
+ invokeToolParameterDialog(ToolHandlerResponder::SampleToolTypeGenerateQuarterSine);
+ break;
+
}
}
diff --git a/src/tracker/SampleEditorControl.h b/src/tracker/SampleEditorControl.h
index 570aabcc..9f9bd0bf 100644
--- a/src/tracker/SampleEditorControl.h
+++ b/src/tracker/SampleEditorControl.h
@@ -309,7 +309,8 @@ class SampleEditorControl : public PPControl, public EventListenerInterface, pub
MenuCommandIDGenerateTriangle,
MenuCommandIDGenerateSawtooth,
MenuCommandIDGenerateHalfSine,
- MenuCommandIDGenerateAbsoluteSine
+ MenuCommandIDGenerateAbsoluteSine,
+ MenuCommandIDGenerateQuarterSine
};
void executeMenuCommand(pp_int32 commandId);
@@ -355,7 +356,8 @@ class SampleEditorControl : public PPControl, public EventListenerInterface, pub
SampleToolTypeGenerateTriangle,
SampleToolTypeGenerateSawtooth,
SampleToolTypeGenerateHalfSine,
- SampleToolTypeGenerateAbsoluteSine
+ SampleToolTypeGenerateAbsoluteSine,
+ SampleToolTypeGenerateQuarterSine
};
private:
diff --git a/src/tracker/SampleEditorControlToolHandler.cpp b/src/tracker/SampleEditorControlToolHandler.cpp
index 675d0b55..62292600 100644
--- a/src/tracker/SampleEditorControlToolHandler.cpp
+++ b/src/tracker/SampleEditorControlToolHandler.cpp
@@ -155,6 +155,7 @@ bool SampleEditorControl::invokeToolParameterDialog(SampleEditorControl::ToolHan
case ToolHandlerResponder::SampleToolTypeGenerateSawtooth:
case ToolHandlerResponder::SampleToolTypeGenerateHalfSine:
case ToolHandlerResponder::SampleToolTypeGenerateAbsoluteSine:
+ case ToolHandlerResponder::SampleToolTypeGenerateQuarterSine:
{
dialog = new DialogWithValues(parentScreen, toolHandlerResponder, PP_DEFAULT_ID, "Generate waveform" PPSTR_PERIODS, DialogWithValues::ValueStyleEnterTwoValues);
static_cast(dialog)->setValueOneCaption("Volume in percent:");
@@ -358,6 +359,17 @@ bool SampleEditorControl::invokeTool(ToolHandlerResponder::SampleToolTypes type)
break;
}
+ case ToolHandlerResponder::SampleToolTypeGenerateQuarterSine:
+ {
+ lastValues.waveFormVolume = static_cast(dialog)->getValueOne();
+ lastValues.waveFormNumPeriods = static_cast(dialog)->getValueTwo();
+ FilterParameters par(2);
+ par.setParameter(0, FilterParameters::Parameter(lastValues.waveFormVolume / 100.0f));
+ par.setParameter(1, FilterParameters::Parameter(lastValues.waveFormNumPeriods));
+ sampleEditor->tool_generateQuarterSine(&par);
+ break;
+ }
+
default:
break;
}
From 6d5dafa489bcb576e0a2a3c5f2b30c32b033d64d Mon Sep 17 00:00:00 2001
From: mothcompute <94941435+mothcompute@users.noreply.github.com>
Date: Thu, 14 Jul 2022 00:00:43 -0700
Subject: [PATCH 30/30] fix segfault when passing invalid filename on command
line (#276)
* fix segfault when passing invalid filename on command line
* fix formatting
---
src/tracker/sdl/SDL_Main.cpp | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/src/tracker/sdl/SDL_Main.cpp b/src/tracker/sdl/SDL_Main.cpp
index 75ffa1df..35a95b6b 100644
--- a/src/tracker/sdl/SDL_Main.cpp
+++ b/src/tracker/sdl/SDL_Main.cpp
@@ -65,6 +65,7 @@
#include
#include
#include
+#include
#include
#include "SDL_KeyTranslation.h"
@@ -971,13 +972,21 @@ int main(int argc, char *argv[])
if (loadFile)
{
- PPSystemString newCwd = path.getCurrent();
- path.change(oldCwd);
- SendFile(realpath(loadFile, loadFileAbsPath));
- path.change(newCwd);
- pp_uint16 chr[3] = {VK_RETURN, 0, 0};
- PPEvent event(eKeyDown, &chr, sizeof(chr));
- RaiseEventSerialized(&event);
+ struct stat statBuf;
+ if (stat(loadFile, &statBuf) != 0)
+ {
+ fprintf(stderr, "could not open %s: %s\n", loadFile, strerror(errno));
+ }
+ else
+ {
+ PPSystemString newCwd = path.getCurrent();
+ path.change(oldCwd);
+ SendFile(realpath(loadFile, loadFileAbsPath));
+ path.change(newCwd);
+ pp_uint16 chr[3] = {VK_RETURN, 0, 0};
+ PPEvent event(eKeyDown, &chr, sizeof(chr));
+ RaiseEventSerialized(&event);
+ }
}
// Main event loop
| | | | | | | | | | | | | | | | | | | | | | | | | | |