View Issue Details

IDProjectCategoryView StatusLast Update
0001127OpenMPTlibopenmptpublic2020-01-05 10:39
ReporterSlender Assigned Tomanx  
PrioritynormalSeverityfeatureReproducibilityN/A
Status resolvedResolutionfixed 
Platformx64OSWindows 
Target VersionOpenMPT 1.29 / libopenmpt 0.5 (goals)Fixed in VersionOpenMPT 1.29 / libopenmpt 0.5 (goals) 
Summary0001127: Sample texts in Impulsetracker modules should be exposed in the libopenmpt message tag
Description

It seems that currently, in the foo_openmpt message tag, for Impulsetracker modules, comments are displayed, and if those aren't found, instrument texts are displayed. I've seen some old modules that will actually write comments in samples rather than instruments, so the message tag only shows instrument names. I believe that sample tags should be included along with instruments in the foo_openmpt message tag.

TagsNo tags attached.
Has the bug occurred in previous versions?
Tested code revision (in case you know it)

Activities

manx

manx

2018-06-10 05:11

administrator   ~0003548

If the song message is empty, we fall back to using the instrument names, if in turn they are completely empty, we fall back to using sample names. Although this heuristics work for most modules, it obviously cannot work for all modules, and I do not see an easy way to solve this.

It might be the case that the module in question only contains whitespace characters in the instrument names, and we could probably include that aspect in the heuristics.

Can you name/provide specific modules where the current heuristic fails?

Slender

Slender

2018-06-10 08:03

reporter   ~0003549

Yes, (-DF-RND.IT. https://www.dropbox.com/s/gyn60pu6ej569jj/%28-DF-RND.IT?dl=1

Saga Musix

Saga Musix

2018-06-12 13:19

administrator   ~0003551

It is more common in IT files to use sample texts rather than instrument texts for a song message, but of course this is not true for all modules. I guess we have to expose both texts if no comments are found in order to support both possible scenarios. The foobar plugin should probably also somehow expose the sample/instrument texts separately if it doesn't do so already, just like xmp-openmpt.

Slender

Slender

2018-06-26 19:03

reporter   ~0003569

Update. Here is a more permanent link to the test case I provided in earlier comments. ftp://ftp.modland.com/pub/modules/Impulsetracker/Corpse/coop-Dark%20Freddy/rainy%20day.it

Slender

Slender

2018-09-07 12:45

reporter   ~0003611

Slightly related to this, a lot of Protracker IFF files are affected by this as well, though the <message tag there is just exposing several space characters rather than the sample text, example: ftp://ftp.modland.com/pub/modules/Protracker%20IFF/DJ%20Pie/heaven.ptm

Saga Musix

Saga Musix

2018-09-07 17:17

administrator   ~0003612

Last edited: 2018-09-07 17:18

View 2 revisions

We could probably trim the message (and end up with an empty message in that case). I'm not sure if that's always a good idea though, e.g. when the message contains some ascii art and it's important that it appears in a rectangular shape (e.g. if the user renders text with a fixed background color). Either way it's a different issue that would not be solved by the proposed fix for the original issue at hand.

manx

manx

2018-09-07 18:06

administrator   ~0003613

Regarding the original issue, I think it probably makes sense to, depending on module format, try either instrument or sample names first in case the message is empty or non-existent. For IT it is probably more common to use sample names, for XM, it is always instrument names. I am also not opposed to, again depending on module format, just include both instrument and sample names in case of no real message (if that makes sense for some formats).

It might even make sense to just always include everything in the "message" metadata (with ordering depending on the format).

Regarding trimming anything, I am strongly opposed. If the names contain any spaces we should keep them as much as possible. The goal here is not to provide a somehow "optimized" look of what is stored in the module, but instead provide an as identical as possible representation of what is stored in the file.

manx

manx

2018-09-07 18:09

administrator   ~0003614

Or we do all of that and provide "message", "message_heuristics", "message_all", "message_raw", "message_trimmed" ;)

That's probably not very useful. However, no matter what single variation we choose, I think there will always be some files where the chosen solution will not be optimal.

Saga Musix

Saga Musix

2018-09-07 18:10

administrator   ~0003615

I don't think it makes much sense to attach sample/instrument texts to the message metadata if there is already a message text (weird messages like the one in heaven.ptm notwithstanding). Generally I think if a player wants to list both the message and sample/instr texts I think that the player developer should decide the best way to represent them (e.g. with separators between different sections). To be clear, this means of course that foo_openmpt should handle this situation better, and I think that libopenmpt already does the right thing in this case.

But if there is no message, it makes sense to just include both instrument and sample texts for most formats. Maybe not so much for XM and clones where samples belong to instruments, but for IT-like formats where sample and instrument lists are completely separate, it makes sense to list both.

Slender

Slender

2019-02-19 17:44

reporter   ~0003852

Should this be closed since foo_openmpt is discontinued as of 0.5?

manx

manx

2019-02-19 17:45

administrator   ~0003853

No, this is still relevant for libopenmpt in general.

manx

manx

2020-01-01 11:20

administrator   ~0004172

message-heuristic-v1.patch (9,716 bytes)   
Index: libopenmpt/libopenmpt_impl.cpp
===================================================================
--- libopenmpt/libopenmpt_impl.cpp	(revision 12440)
+++ libopenmpt/libopenmpt_impl.cpp	(working copy)
@@ -1145,6 +1145,40 @@
 		"warnings",
 	};
 }
+std::string module_impl::get_message_instruments() const {
+	std::string retval;
+	std::string tmp;
+	bool valid = false;
+	for ( INSTRUMENTINDEX i = 1; i <= m_sndFile->GetNumInstruments(); ++i ) {
+		std::string instname = m_sndFile->GetInstrumentName( i );
+		if ( !instname.empty() ) {
+			valid = true;
+		}
+		tmp += instname;
+		tmp += "\n";
+	}
+	if ( valid ) {
+		retval = tmp;
+	}
+	return retval;
+}
+std::string module_impl::get_message_samples() const {
+	std::string retval;
+	std::string tmp;
+	bool valid = false;
+	for ( SAMPLEINDEX i = 1; i <= m_sndFile->GetNumSamples(); ++i ) {
+		std::string samplename = m_sndFile->GetSampleName( i );
+		if ( !samplename.empty() ) {
+			valid = true;
+		}
+		tmp += samplename;
+		tmp += "\n";
+	}
+	if ( valid ) {
+		retval = tmp;
+	}
+	return retval;
+}
 std::string module_impl::get_metadata( const std::string & key ) const {
 	if ( key == std::string("type") ) {
 		return mpt::ToCharset(mpt::Charset::UTF8, m_sndFile->m_modFormat.type );
@@ -1172,35 +1206,55 @@
 	} else if ( key == std::string("message") ) {
 		std::string retval = m_sndFile->m_songMessage.GetFormatted( SongMessage::leLF );
 		if ( retval.empty() ) {
-			std::string tmp;
-			bool valid = false;
-			for ( INSTRUMENTINDEX i = 1; i <= m_sndFile->GetNumInstruments(); ++i ) {
-				std::string instname = m_sndFile->GetInstrumentName( i );
-				if ( !instname.empty() ) {
-					valid = true;
-				}
-				tmp += instname;
-				tmp += "\n";
+			switch ( m_sndFile->m_modFormat.messageHeuristic ) {
+				case ModMessageHeuristicOrder::Instruments:
+					retval = get_message_instruments();
+					break;
+				case ModMessageHeuristicOrder::Samples:
+					retval = get_message_samples();
+					break;
+				case ModMessageHeuristicOrder::InstrumentsSamples:
+					if ( retval.empty() ) {
+						retval = get_message_instruments();
+					}
+					if ( retval.empty() ) {
+						retval = get_message_samples();
+					}
+					break;
+				case ModMessageHeuristicOrder::SamplesInstruments:
+					if ( retval.empty() ) {
+						retval = get_message_samples();
+					}
+					if ( retval.empty() ) {
+						retval = get_message_instruments();
+					}
+					break;
+				case ModMessageHeuristicOrder::BothInstrumentsSamples:
+					{
+						std::string message_instruments = get_message_instruments();
+						std::string message_samples = get_message_samples();
+						if ( !message_instruments.empty() ) {
+							retval += std::move( message_instruments );
+						}
+						if ( !message_samples.empty() ) {
+							retval += std::move( message_samples );
+						}
+					}
+					break;
+				case ModMessageHeuristicOrder::BothSamplesInstruments:
+					{
+						std::string message_instruments = get_message_instruments();
+						std::string message_samples = get_message_samples();
+						if ( !message_samples.empty() ) {
+							retval += std::move( message_samples );
+						}
+						if ( !message_instruments.empty() ) {
+							retval += std::move( message_instruments );
+						}
+					}
+					break;
 			}
-			if ( valid ) {
-				retval = tmp;
-			}
 		}
-		if ( retval.empty() ) {
-			std::string tmp;
-			bool valid = false;
-			for ( SAMPLEINDEX i = 1; i <= m_sndFile->GetNumSamples(); ++i ) {
-				std::string samplename = m_sndFile->GetSampleName( i );
-				if ( !samplename.empty() ) {
-					valid = true;
-				}
-				tmp += samplename;
-				tmp += "\n";
-			}
-			if ( valid ) {
-				retval = tmp;
-			}
-		}
 		return mod_string_to_utf8( retval );
 	} else if ( key == std::string("message_raw") ) {
 		std::string retval = m_sndFile->m_songMessage.GetFormatted( SongMessage::leLF );
Index: libopenmpt/libopenmpt_impl.hpp
===================================================================
--- libopenmpt/libopenmpt_impl.hpp	(revision 12440)
+++ libopenmpt/libopenmpt_impl.hpp	(working copy)
@@ -146,6 +146,8 @@
 	std::size_t read_wrapper( std::size_t count, float * left, float * right, float * rear_left, float * rear_right );
 	std::size_t read_interleaved_wrapper( std::size_t count, std::size_t channels, std::int16_t * interleaved );
 	std::size_t read_interleaved_wrapper( std::size_t count, std::size_t channels, float * interleaved );
+	std::string get_message_instruments() const;
+	std::string get_message_samples() const;
 	std::pair< std::string, std::string > format_and_highlight_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int command ) const;
 	std::pair< std::string, std::string > format_and_highlight_pattern_row_channel( std::int32_t p, std::int32_t r, std::int32_t c, std::size_t width, bool pad ) const;
 	static double could_open_probability( const OpenMPT::FileReader & file, double effort, std::unique_ptr<log_interface> log );
Index: soundlib/Load_it.cpp
===================================================================
--- soundlib/Load_it.cpp	(revision 12440)
+++ soundlib/Load_it.cpp	(working copy)
@@ -1257,6 +1257,7 @@
 	m_modFormat.type = (GetType() == MOD_TYPE_MPT) ? U_("mptm") : U_("it");
 	m_modFormat.madeWithTracker = std::move(madeWithTracker);
 	m_modFormat.charset = m_dwLastSavedWithVersion ? mpt::Charset::Windows1252 : mpt::Charset::CP437;
+	m_modFormat.messageHeuristic = ModMessageHeuristicOrder::Samples;
 
 	return true;
 }
Index: soundlib/Load_itp.cpp
===================================================================
--- soundlib/Load_itp.cpp	(revision 12440)
+++ soundlib/Load_itp.cpp	(working copy)
@@ -399,6 +399,7 @@
 	m_modFormat.type = U_("itp");
 	m_modFormat.madeWithTracker = U_("OpenMPT ") + mpt::ufmt::val(m_dwLastSavedWithVersion);
 	m_modFormat.charset = mpt::Charset::Windows1252;
+	m_modFormat.messageHeuristic = ModMessageHeuristicOrder::Samples;
 
 	return true;
 #endif // MPT_EXTERNAL_SAMPLES
Index: soundlib/Load_mo3.cpp
===================================================================
--- soundlib/Load_mo3.cpp	(revision 12440)
+++ soundlib/Load_mo3.cpp	(working copy)
@@ -831,11 +831,13 @@
 
 	mpt::ustring originalFormatType;
 	mpt::ustring originalFormatName;
+	ModMessageHeuristicOrder messageHeuristic = ModMessageHeuristicOrder::Default;
 	if(fileHeader.flags & MO3FileHeader::isIT)
 	{
 		SetType(MOD_TYPE_IT);
 		originalFormatType = U_("it");
 		originalFormatName = U_("Impulse Tracker");
+		messageHeuristic = ModMessageHeuristicOrder::Samples;
 	} else if(fileHeader.flags & MO3FileHeader::isS3M)
 	{
 		SetType(MOD_TYPE_S3M);
@@ -856,6 +858,7 @@
 		SetType(MOD_TYPE_XM);
 		originalFormatType = U_("xm");
 		originalFormatName = U_("FastTracker 2");
+		messageHeuristic = ModMessageHeuristicOrder::InstrumentsSamples;
 	}
 
 	if(fileHeader.flags & MO3FileHeader::linearSlides)
@@ -1948,6 +1951,7 @@
 		m_modFormat.charset = mpt::Charset::ISO8859_1;
 	else
 		m_modFormat.charset = mpt::Charset::CP437;
+	m_modFormat.messageHeuristic = messageHeuristic;
 
 	if(unsupportedSamples)
 	{
Index: soundlib/Load_xm.cpp
===================================================================
--- soundlib/Load_xm.cpp	(revision 12440)
+++ soundlib/Load_xm.cpp	(working copy)
@@ -1032,6 +1032,7 @@
 		m_modFormat.originalType = U_("xm");
 		m_modFormat.madeWithTracker = std::move(madeWithTracker);
 		m_modFormat.charset = m_dwLastSavedWithVersion ? mpt::Charset::Windows1252 : mpt::Charset::CP437;
+		m_modFormat.messageHeuristic = ModMessageHeuristicOrder::InstrumentsSamples;
 	} else
 	{
 		m_modFormat.formatName = mpt::format(U_("FastTracker 2 v%1.%2"))(fileHeader.version >> 8, mpt::ufmt::hex0<2>(fileHeader.version & 0xFF));
@@ -1038,6 +1039,7 @@
 		m_modFormat.type = U_("xm");
 		m_modFormat.madeWithTracker = std::move(madeWithTracker);
 		m_modFormat.charset = m_dwLastSavedWithVersion ? mpt::Charset::Windows1252 : mpt::Charset::CP437;
+		m_modFormat.messageHeuristic = ModMessageHeuristicOrder::InstrumentsSamples;
 	}
 
 	return true;
Index: soundlib/Sndfile.cpp
===================================================================
--- soundlib/Sndfile.cpp	(revision 12440)
+++ soundlib/Sndfile.cpp	(working copy)
@@ -1576,6 +1576,21 @@
 	Patterns.OnModTypeChanged(oldType);
 
 	m_modFormat.type = mpt::ToUnicode(mpt::Charset::UTF8, GetModSpecifications().fileExtension);
+	switch(newType)
+	{
+	case MOD_TYPE_MPT:
+		m_modFormat.messageHeuristic = ModMessageHeuristicOrder::Samples;
+		break;
+	case MOD_TYPE_IT:
+		m_modFormat.messageHeuristic = ModMessageHeuristicOrder::Samples;
+		break;
+	case MOD_TYPE_XM:
+		m_modFormat.messageHeuristic = ModMessageHeuristicOrder::InstrumentsSamples;
+		break;
+	default:
+		m_modFormat.messageHeuristic = ModMessageHeuristicOrder::Default;
+		break;
+	}
 }
 
 #endif // MODPLUG_TRACKER
Index: soundlib/Sndfile.h
===================================================================
--- soundlib/Sndfile.h	(revision 12440)
+++ soundlib/Sndfile.h	(working copy)
@@ -247,6 +247,17 @@
 };
 
 
+enum class ModMessageHeuristicOrder
+{
+	Instruments,
+	Samples,
+	InstrumentsSamples,
+	SamplesInstruments,
+	BothInstrumentsSamples,
+	BothSamplesInstruments,
+	Default = InstrumentsSamples,
+};
+
 struct ModFormatDetails
 {
 	mpt::ustring formatName;         // "FastTracker 2"
@@ -255,6 +266,7 @@
 	mpt::ustring originalFormatName; // "FastTracker 2" in the case of converted formats like MO3 or GDM
 	mpt::ustring originalType;       // "xm" in the case of converted formats like MO3 or GDM
 	mpt::Charset charset = mpt::Charset::UTF8;
+	ModMessageHeuristicOrder messageHeuristic = ModMessageHeuristicOrder::Default;
 };
 
 
message-heuristic-v1.patch (9,716 bytes)   
Saga Musix

Saga Musix

2020-01-01 12:43

administrator   ~0004173

Other XM-like formats: MDL, IMF

To avoid duplicating code between loaders and Sndfile.cpp (mod conversion), I would rather have this information in a function in CSoundFile (using a switch statement similar to that in added in the mod conversion code). This information is inherently bound to how the file format is structured, so it doesn't make much sense to be able to differentiate it on a per-tracker basis like charsets etc.. This avoids the danger of having inconsistent values between loaders and after mod conversion (which is only applicable to OpenMPT), and all the information regarding this feature is centered in a single place.

manx

manx

2020-01-01 12:57

administrator   ~0004174

Patch is even shorter this way.

message-heuristic-v2.patch (6,679 bytes)   
Index: libopenmpt/libopenmpt_impl.cpp
===================================================================
--- libopenmpt/libopenmpt_impl.cpp	(revision 12440)
+++ libopenmpt/libopenmpt_impl.cpp	(working copy)
@@ -1145,6 +1145,40 @@
 		"warnings",
 	};
 }
+std::string module_impl::get_message_instruments() const {
+	std::string retval;
+	std::string tmp;
+	bool valid = false;
+	for ( INSTRUMENTINDEX i = 1; i <= m_sndFile->GetNumInstruments(); ++i ) {
+		std::string instname = m_sndFile->GetInstrumentName( i );
+		if ( !instname.empty() ) {
+			valid = true;
+		}
+		tmp += instname;
+		tmp += "\n";
+	}
+	if ( valid ) {
+		retval = tmp;
+	}
+	return retval;
+}
+std::string module_impl::get_message_samples() const {
+	std::string retval;
+	std::string tmp;
+	bool valid = false;
+	for ( SAMPLEINDEX i = 1; i <= m_sndFile->GetNumSamples(); ++i ) {
+		std::string samplename = m_sndFile->GetSampleName( i );
+		if ( !samplename.empty() ) {
+			valid = true;
+		}
+		tmp += samplename;
+		tmp += "\n";
+	}
+	if ( valid ) {
+		retval = tmp;
+	}
+	return retval;
+}
 std::string module_impl::get_metadata( const std::string & key ) const {
 	if ( key == std::string("type") ) {
 		return mpt::ToCharset(mpt::Charset::UTF8, m_sndFile->m_modFormat.type );
@@ -1172,35 +1206,55 @@
 	} else if ( key == std::string("message") ) {
 		std::string retval = m_sndFile->m_songMessage.GetFormatted( SongMessage::leLF );
 		if ( retval.empty() ) {
-			std::string tmp;
-			bool valid = false;
-			for ( INSTRUMENTINDEX i = 1; i <= m_sndFile->GetNumInstruments(); ++i ) {
-				std::string instname = m_sndFile->GetInstrumentName( i );
-				if ( !instname.empty() ) {
-					valid = true;
-				}
-				tmp += instname;
-				tmp += "\n";
+			switch ( m_sndFile->GetMessageHeuristic() ) {
+				case ModMessageHeuristicOrder::Instruments:
+					retval = get_message_instruments();
+					break;
+				case ModMessageHeuristicOrder::Samples:
+					retval = get_message_samples();
+					break;
+				case ModMessageHeuristicOrder::InstrumentsSamples:
+					if ( retval.empty() ) {
+						retval = get_message_instruments();
+					}
+					if ( retval.empty() ) {
+						retval = get_message_samples();
+					}
+					break;
+				case ModMessageHeuristicOrder::SamplesInstruments:
+					if ( retval.empty() ) {
+						retval = get_message_samples();
+					}
+					if ( retval.empty() ) {
+						retval = get_message_instruments();
+					}
+					break;
+				case ModMessageHeuristicOrder::BothInstrumentsSamples:
+					{
+						std::string message_instruments = get_message_instruments();
+						std::string message_samples = get_message_samples();
+						if ( !message_instruments.empty() ) {
+							retval += std::move( message_instruments );
+						}
+						if ( !message_samples.empty() ) {
+							retval += std::move( message_samples );
+						}
+					}
+					break;
+				case ModMessageHeuristicOrder::BothSamplesInstruments:
+					{
+						std::string message_instruments = get_message_instruments();
+						std::string message_samples = get_message_samples();
+						if ( !message_samples.empty() ) {
+							retval += std::move( message_samples );
+						}
+						if ( !message_instruments.empty() ) {
+							retval += std::move( message_instruments );
+						}
+					}
+					break;
 			}
-			if ( valid ) {
-				retval = tmp;
-			}
 		}
-		if ( retval.empty() ) {
-			std::string tmp;
-			bool valid = false;
-			for ( SAMPLEINDEX i = 1; i <= m_sndFile->GetNumSamples(); ++i ) {
-				std::string samplename = m_sndFile->GetSampleName( i );
-				if ( !samplename.empty() ) {
-					valid = true;
-				}
-				tmp += samplename;
-				tmp += "\n";
-			}
-			if ( valid ) {
-				retval = tmp;
-			}
-		}
 		return mod_string_to_utf8( retval );
 	} else if ( key == std::string("message_raw") ) {
 		std::string retval = m_sndFile->m_songMessage.GetFormatted( SongMessage::leLF );
Index: libopenmpt/libopenmpt_impl.hpp
===================================================================
--- libopenmpt/libopenmpt_impl.hpp	(revision 12440)
+++ libopenmpt/libopenmpt_impl.hpp	(working copy)
@@ -146,6 +146,8 @@
 	std::size_t read_wrapper( std::size_t count, float * left, float * right, float * rear_left, float * rear_right );
 	std::size_t read_interleaved_wrapper( std::size_t count, std::size_t channels, std::int16_t * interleaved );
 	std::size_t read_interleaved_wrapper( std::size_t count, std::size_t channels, float * interleaved );
+	std::string get_message_instruments() const;
+	std::string get_message_samples() const;
 	std::pair< std::string, std::string > format_and_highlight_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int command ) const;
 	std::pair< std::string, std::string > format_and_highlight_pattern_row_channel( std::int32_t p, std::int32_t r, std::int32_t c, std::size_t width, bool pad ) const;
 	static double could_open_probability( const OpenMPT::FileReader & file, double effort, std::unique_ptr<log_interface> log );
Index: soundlib/Sndfile.cpp
===================================================================
--- soundlib/Sndfile.cpp	(revision 12440)
+++ soundlib/Sndfile.cpp	(working copy)
@@ -1581,6 +1581,34 @@
 #endif // MODPLUG_TRACKER
 
 
+ModMessageHeuristicOrder CSoundFile::GetMessageHeuristic() const
+{
+	ModMessageHeuristicOrder result = ModMessageHeuristicOrder::Default;
+	switch(GetType())
+	{
+	case MOD_TYPE_MPT:
+		result = ModMessageHeuristicOrder::Samples;
+		break;
+	case MOD_TYPE_IT:
+		result = ModMessageHeuristicOrder::Samples;
+		break;
+	case MOD_TYPE_XM:
+		result = ModMessageHeuristicOrder::InstrumentsSamples;
+		break;
+	case MOD_TYPE_MDL:
+		result = ModMessageHeuristicOrder::InstrumentsSamples;
+		break;
+	case MOD_TYPE_IMF:
+		result = ModMessageHeuristicOrder::InstrumentsSamples;
+		break;
+	default:
+		result = ModMessageHeuristicOrder::Default;
+		break;
+	}
+	return result;
+}
+
+
 bool CSoundFile::SetTitle(const std::string &newTitle)
 {
 	if(m_songName != newTitle)
Index: soundlib/Sndfile.h
===================================================================
--- soundlib/Sndfile.h	(revision 12440)
+++ soundlib/Sndfile.h	(working copy)
@@ -247,6 +247,17 @@
 };
 
 
+enum class ModMessageHeuristicOrder
+{
+	Instruments,
+	Samples,
+	InstrumentsSamples,
+	SamplesInstruments,
+	BothInstrumentsSamples,
+	BothSamplesInstruments,
+	Default = InstrumentsSamples,
+};
+
 struct ModFormatDetails
 {
 	mpt::ustring formatName;         // "FastTracker 2"
@@ -674,6 +685,8 @@
 		#endif // MODPLUG_TRACKER
 	}
 
+	ModMessageHeuristicOrder GetMessageHeuristic() const;
+
 	void SetPreAmp(uint32 vol);
 	uint32 GetPreAmp() const { return m_MixerSettings.m_nPreAmp; }
 
message-heuristic-v2.patch (6,679 bytes)   
manx

manx

2020-01-05 10:39

administrator   ~0004177

r12446

Issue History

Date Modified Username Field Change
2018-06-09 22:51 Slender New Issue
2018-06-10 05:11 manx Assigned To => manx
2018-06-10 05:11 manx Status new => feedback
2018-06-10 05:11 manx Note Added: 0003548
2018-06-10 08:03 Slender Note Added: 0003549
2018-06-10 08:03 Slender Status feedback => assigned
2018-06-12 13:19 Saga Musix Note Added: 0003551
2018-06-26 19:03 Slender Note Added: 0003569
2018-09-07 12:45 Slender Note Added: 0003611
2018-09-07 17:17 Saga Musix Note Added: 0003612
2018-09-07 17:18 Saga Musix Note Edited: 0003612 View Revisions
2018-09-07 18:06 manx Note Added: 0003613
2018-09-07 18:09 manx Note Added: 0003614
2018-09-07 18:10 Saga Musix Note Added: 0003615
2019-02-19 17:44 Slender Note Added: 0003852
2019-02-19 17:45 manx Note Added: 0003853
2019-02-19 17:46 manx Category Player input plugins (xmp-openmpt, in_openmpt, foo_openmpt) => libopenmpt
2019-02-19 17:46 manx Target Version => OpenMPT 1.29 / libopenmpt 0.5 (goals)
2019-02-22 08:58 manx Summary Sample texts in Impulsetracker modules should be exposed in the foo_openmpt message tag => Sample texts in Impulsetracker modules should be exposed in the libopenmpt message tag
2020-01-01 11:20 manx Note Added: 0004172
2020-01-01 11:20 manx File Added: message-heuristic-v1.patch
2020-01-01 12:43 Saga Musix Note Added: 0004173
2020-01-01 12:57 manx Note Added: 0004174
2020-01-01 12:57 manx File Added: message-heuristic-v2.patch
2020-01-05 10:39 manx Status assigned => resolved
2020-01-05 10:39 manx Resolution open => fixed
2020-01-05 10:39 manx Fixed in Version => OpenMPT 1.29 / libopenmpt 0.5 (goals)
2020-01-05 10:39 manx Note Added: 0004177