View Issue Details

IDProjectCategoryView StatusLast Update
0001766OpenMPTlibopenmptpublic2024-10-20 12:03
ReporterSaga Musix Assigned ToSaga Musix  
PrioritynormalSeverityfeatureReproducibilityN/A
Status resolvedResolutionfixed 
Target VersionOpenMPT 1.32 / libopenmpt 0.8 (goals)Fixed in VersionOpenMPT 1.32 / libopenmpt 0.8 (goals) 
Summary0001766: Provide a way to retrieve numeric values of +++ and --- values via libopenmpt API
Description

Right now libopenmpt users have to assume that +++ patterns have pattern ID 65534 and --- patterns are 65535. These values should be retrievable via an API call instead.

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

Relationships

related to 0001017 new Tick boundary rendering (was: Provide access to next play position
related to 0001832 resolvedSaga Musix libopenmpt API addition: Retrieve pattern highlights 

Activities

Saga Musix

Saga Musix

2024-03-30 13:15

administrator   ~0005893

See https://github.com/kajott/TrackMeister/issues/7

manx

manx

2024-03-30 13:18

administrator   ~0005894

This is also somewhat related to tick boundary rendering, because we need to decide whether to expose the intermediate state of hitting a skip pattern or not.

manx

manx

2024-03-30 19:57

administrator   ~0005898

There are basically 3 approaches possible here:

1.

bool is_order_skip_pattern(int32 ordernum);
bool is_pattern_skip_pattern(int32 patternnum);
bool is_order_stop_pattern(int32 ordernum);
bool is_pattern_stop_pattern(int32 patternnum);

2.

int32 get_skip_pattern_num();
int32 get_stop_pattern_num();

3.

enum pattern_type {
 normal,
 skip,
 stop,
};
pattern_type get_order_pattern_type(int32 ordernum);
pattern_type get_pattern_pattern_type(int32 patternum);

I have no idea which one would be best. Suggested names are not final, of course.

Option 2 has the disadvantage of requiring an API change if there ever should be multiple possible magic numbers per type.

Saga Musix

Saga Musix

2024-03-30 21:56

administrator   ~0005899

Last edited: 2024-03-30 21:56

In fact the skip / stop indices used to differ between formats, for no good reason. I unified them a long time ago and I don't think we'd ever want to go back to that.

Saga Musix

Saga Musix

2024-06-10 18:33

administrator   ~0005968

Option 2 would allow for writing code with the fewest calls into libopenmpt - the values would only have to be retrieved once and then the whole order list can be processed using those values. Of course it would mean that adding a new type of pattern index would require a new function instead of just adding a new enum value - but with 50+ formats supported by now, and with the knowledge of other formats that are currently unsupported, I'm not even sure what that new type of pattern could be.

Saga Musix

Saga Musix

2024-10-19 12:34

administrator   ~0006098

Proposed implementation for option 2

Saga Musix

Saga Musix

2024-10-19 12:54

administrator   ~0006099

order_list_index.patch (6,730 bytes)   
Index: libopenmpt/bindings/freebasic/libopenmpt.bi
===================================================================
--- libopenmpt/bindings/freebasic/libopenmpt.bi	(revision 21858)
+++ libopenmpt/bindings/freebasic/libopenmpt.bi	(working copy)
@@ -1273,6 +1273,20 @@
 '/
 Declare Function openmpt_module_get_order_pattern(ByVal module As openmpt_module Ptr, ByVal order As Long) As Long
 
+/'* \brief Get skip ("+++") pattern index
+
+  \param module The module handle to work on.
+  \return The pattern index that represents skip items in the order list. During playback, this order list item is ignored and playback resumes at the next order list item.
+'/
+Declare Function openmpt_module_get_skip_pattern_num(ByVal module As openmpt_module Ptr) As Long
+
+/'* \brief Get stop("---") pattern index
+
+  \param module The module handle to work on.
+  \return The pattern index that represents stop items in the order list. When this order list item is reached, playback continues at the restart position of the current subsong.
+'/
+Declare Function openmpt_module_get_stop_pattern_num(ByVal module As openmpt_module Ptr) As Long
+
 /'* \brief Get the number of rows in a pattern
 
   \param module The module handle to work on.
Index: libopenmpt/libopenmpt.h
===================================================================
--- libopenmpt/libopenmpt.h	(revision 21858)
+++ libopenmpt/libopenmpt.h	(working copy)
@@ -1330,6 +1330,18 @@
  * \return The pattern index found at the given order position of the current sequence.
  */
 LIBOPENMPT_API int32_t openmpt_module_get_order_pattern( openmpt_module * mod, int32_t order );
+/*! \brief Get skip ("+++") pattern index
+ *
+ * \param mod The module handle to work on.
+ * \return The pattern index that represents skip items in the order list. During playback, this order list item is ignored and playback resumes at the next order list item.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_skip_pattern_num( openmpt_module * mod );
+/*! \brief Get stop("---") pattern index
+ *
+ * \param mod The module handle to work on.
+ * \return The pattern index that represents stop items in the order list. When this order list item is reached, playback continues at the restart position of the current subsong.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_stop_pattern_num( openmpt_module * mod );
 /*! \brief Get the number of rows in a pattern
  *
  * \param mod The module handle to work on.
Index: libopenmpt/libopenmpt.hpp
===================================================================
--- libopenmpt/libopenmpt.hpp	(revision 21858)
+++ libopenmpt/libopenmpt.hpp	(working copy)
@@ -989,6 +989,18 @@
 	*/
 	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_order_pattern( std::int32_t order ) const;
 
+	//! Get skip ("+++") pattern index
+	/*!
+	  \return The pattern index that represents skip items in the order list. During playback, this order list item is ignored and playback resumes at the next order list item.
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_skip_pattern_num() const;
+
+	//! Get stop ("---") pattern index
+	/*!
+	  \return The pattern index that represents stop items in the order list. When this order list item is reached, playback continues at the restart position of the current subsong.
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_stop_pattern_num() const;
+
 	//! Get the number of rows in a pattern
 	/*!
 	  \param pattern The pattern whose row count should be retrieved.
Index: libopenmpt/libopenmpt_c.cpp
===================================================================
--- libopenmpt/libopenmpt_c.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_c.cpp	(working copy)
@@ -1225,6 +1225,26 @@
 	return 0;
 }
 
+int32_t openmpt_module_get_skip_pattern_num( openmpt_module * mod ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_skip_pattern_num();
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+
+int32_t openmpt_module_get_stop_pattern_num( openmpt_module * mod ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_stop_pattern_num();
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+
 int32_t openmpt_module_get_pattern_num_rows( openmpt_module * mod, int32_t pattern ) {
 	try {
 		openmpt::interface::check_soundfile( mod );
Index: libopenmpt/libopenmpt_cxx.cpp
===================================================================
--- libopenmpt/libopenmpt_cxx.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_cxx.cpp	(working copy)
@@ -389,6 +389,12 @@
 std::int32_t module::get_order_pattern( std::int32_t order ) const {
 	return impl->get_order_pattern( order );
 }
+std::int32_t module::get_skip_pattern_num() const {
+	return module_impl::get_skip_pattern_num();
+}
+std::int32_t module::get_stop_pattern_num() const {
+	return module_impl::get_stop_pattern_num();
+}
 std::int32_t module::get_pattern_num_rows( std::int32_t pattern ) const {
 	return impl->get_pattern_num_rows( pattern );
 }
Index: libopenmpt/libopenmpt_impl.cpp
===================================================================
--- libopenmpt/libopenmpt_impl.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_impl.cpp	(working copy)
@@ -1457,6 +1457,12 @@
 	}
 	return m_sndFile->Order()[o];
 }
+std::int32_t module_impl::get_skip_pattern_num() {
+	return OpenMPT::PATTERNINDEX_SKIP;
+}
+std::int32_t module_impl::get_stop_pattern_num() {
+	return OpenMPT::PATTERNINDEX_INVALID;
+}
 std::int32_t module_impl::get_pattern_num_rows( std::int32_t p ) const {
 	if ( !mpt::is_in_range( p, std::numeric_limits<OpenMPT::PATTERNINDEX>::min(), std::numeric_limits<OpenMPT::PATTERNINDEX>::max() ) || !m_sndFile->Patterns.IsValidPat( static_cast<OpenMPT::PATTERNINDEX>( p ) ) ) {
 		return 0;
Index: libopenmpt/libopenmpt_impl.hpp
===================================================================
--- libopenmpt/libopenmpt_impl.hpp	(revision 21858)
+++ libopenmpt/libopenmpt_impl.hpp	(working copy)
@@ -244,6 +244,8 @@
 	std::vector<std::string> get_instrument_names() const;
 	std::vector<std::string> get_sample_names() const;
 	std::int32_t get_order_pattern( std::int32_t o ) const;
+	static std::int32_t get_skip_pattern_num();
+	static std::int32_t get_stop_pattern_num();
 	std::int32_t get_pattern_num_rows( std::int32_t p ) const;
 	std::uint8_t get_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const;
 	std::string format_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const;
order_list_index.patch (6,730 bytes)   
manx

manx

2024-10-19 12:57

administrator   ~0006100

I think I still prefer option 1.

Saga Musix

Saga Musix

2024-10-19 17:17

administrator   ~0006106

Alternative implementation following option 1.

order_list_index-v2.patch (12,339 bytes)   
Index: libopenmpt/bindings/freebasic/libopenmpt.bi
===================================================================
--- libopenmpt/bindings/freebasic/libopenmpt.bi	(revision 21858)
+++ libopenmpt/bindings/freebasic/libopenmpt.bi	(working copy)
@@ -1273,6 +1273,39 @@
 '/
 Declare Function openmpt_module_get_order_pattern(ByVal module As openmpt_module Ptr, ByVal order As Long) As Long
 
+/'* \brief Check if specified order is a skip ("+++") item
+
+  \param The order item to check.
+  \return Returns non-zero value if the pattern index at the given order position represents a skip item. During playback, this item is ignored and playback resumes at the next order list item.
+  \sa openmpt_module_is_order_stop_pattern, openmpt_module_is_pattern_skip_pattern
+  \since 0.8.0
+'/
+Declare Function openmpt_module_is_order_skip_pattern(ByVal module As openmpt_module Ptr, ByVal order As Long) As Long
+/'* \brief Check if specified pattern index is a skip ("+++") item
+
+  \param The pattern index to check.
+  \return Returns non-zero value if the pattern index represents a skip item. During playback, this item is ignored and playback resumes at the next order list item.
+  \sa openmpt_module_is_order_stop_pattern, openmpt_module_is_order_skip_pattern, openmpt_module_get_order_pattern
+  \since 0.8.0
+'/
+Declare Function openmpt_module_is_pattern_skip_pattern(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
+/'* \brief Check if specified order is a stop ("---") item
+
+  \param The order item to check.
+  \return Returns non-zero value if the pattern index at the given order position represents a stop item. When this item is reached, playback continues at the restart position of the current sub-song.
+  \sa openmpt_module_is_order_skip_pattern, openmpt_module_is_pattern_stop_pattern
+  \since 0.8.0
+'/
+Declare Function openmpt_module_is_order_stop_pattern(ByVal module As openmpt_module Ptr, ByVal order As Long) As Long
+/'* \brief Check if specified pattern index is a stop ("---") item
+
+  \param The pattern index to check.
+  \return Returns non-zero value if the pattern index represents a stop item. When this item is reached, playback continues at the restart position of the current sub-song.
+  \sa openmpt_module_is_order_skip_pattern, openmpt_module_is_order_stop_pattern openmpt_module_get_order_pattern
+  \since 0.8.0
+'/
+Declare Function openmpt_module_is_pattern_stop_pattern(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
+
 /'* \brief Get the number of rows in a pattern
 
   \param module The module handle to work on.
Index: libopenmpt/libopenmpt.h
===================================================================
--- libopenmpt/libopenmpt.h	(revision 21858)
+++ libopenmpt/libopenmpt.h	(working copy)
@@ -1330,6 +1330,40 @@
  * \return The pattern index found at the given order position of the current sequence.
  */
 LIBOPENMPT_API int32_t openmpt_module_get_order_pattern( openmpt_module * mod, int32_t order );
+
+/*! \brief Check if specified order is a skip ("+++") item
+ *
+ * \param The order item to check.
+ * \return Returns non-zero value if the pattern index at the given order position represents a skip item. During playback, this item is ignored and playback resumes at the next order list item.
+ * \sa openmpt_module_is_order_stop_pattern, openmpt_module_is_pattern_skip_pattern
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int openmpt_module_is_order_skip_pattern( openmpt_module * mod, int32_t order );
+/*! \brief Check if specified pattern index is a skip ("+++") item
+ *
+ * \param The pattern index to check.
+ * \return Returns non-zero value if the pattern index represents a skip item. During playback, this item is ignored and playback resumes at the next order list item.
+ * \sa openmpt_module_is_order_stop_pattern, openmpt_module_is_order_skip_pattern, openmpt_module_get_order_pattern
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int openmpt_module_is_pattern_skip_pattern( openmpt_module * mod, int32_t pattern );
+/*! \brief Check if specified order is a stop ("---") item
+ *
+ * \param The order item to check.
+ * \return Returns non-zero value if the pattern index at the given order position represents a stop item. When this item is reached, playback continues at the restart position of the current sub-song.
+ * \sa openmpt_module_is_order_skip_pattern, openmpt_module_is_pattern_stop_pattern
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int openmpt_module_is_order_stop_pattern( openmpt_module * mod, int32_t order );
+/*! \brief Check if specified pattern index is a stop ("---") item
+ *
+ * \param The pattern index to check.
+ * \return Returns non-zero value if the pattern index represents a stop item. When this item is reached, playback continues at the restart position of the current sub-song.
+ * \sa openmpt_module_is_order_skip_pattern, openmpt_module_is_order_stop_pattern openmpt_module_get_order_pattern
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int openmpt_module_is_order_stop_pattern( openmpt_module * mod, int32_t pattern );
+
 /*! \brief Get the number of rows in a pattern
  *
  * \param mod The module handle to work on.
Index: libopenmpt/libopenmpt.hpp
===================================================================
--- libopenmpt/libopenmpt.hpp	(revision 21858)
+++ libopenmpt/libopenmpt.hpp	(working copy)
@@ -989,6 +989,39 @@
 	*/
 	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_order_pattern( std::int32_t order ) const;
 
+	//! Check if specified order is a skip ("+++") item
+	/*!
+	  \param The order item to check.
+	  \return Returns true if the pattern index at the given order position represents a skip item. During playback, this item is ignored and playback resumes at the next order list item.
+	  \sa openmpt::module::is_order_stop_pattern, openmpt::module::is_pattern_skip_pattern
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER bool is_order_skip_pattern( std::int32_t order ) const ;
+	//! Check if specified pattern index is a skip ("+++") item
+	/*!
+	  \param The pattern index to check.
+	  \return Returns true if the pattern index represents a skip item. During playback, this item is ignored and playback resumes at the next order list item.
+	  \sa openmpt::module::is_order_stop_pattern, openmpt::module::is_order_skip_pattern, openmpt::module::get_order_pattern
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER bool is_pattern_skip_pattern( std::int32_t pattern ) const;
+	//! Check if specified order is a stop ("---") item
+	/*!
+	  \param The order item to check.
+	  \return Returns true if the pattern index at the given order position represents a stop item. When this item is reached, playback continues at the restart position of the current sub-song.
+	  \sa openmpt::module::is_order_skip_pattern, openmpt::module::is_pattern_stop_pattern
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER bool is_order_stop_pattern( std::int32_t order ) const;
+	//! Check if specified pattern index is a stop ("---") item
+	/*!
+	  \param The pattern index to check.
+	  \return Returns true if the pattern index represents a stop item. When this item is reached, playback continues at the restart position of the current sub-song.
+	  \sa openmpt::module::is_order_skip_pattern, openmpt::module::is_order_stop_pattern openmpt::module::get_order_pattern
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER bool is_pattern_stop_pattern( std::int32_t pattern ) const;
+
 	//! Get the number of rows in a pattern
 	/*!
 	  \param pattern The pattern whose row count should be retrieved.
Index: libopenmpt/libopenmpt_c.cpp
===================================================================
--- libopenmpt/libopenmpt_c.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_c.cpp	(working copy)
@@ -1225,6 +1225,44 @@
 	return 0;
 }
 
+int openmpt_module_is_order_skip_pattern( openmpt_module * mod, int32_t order ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->is_order_skip_pattern( order ) ? 1 : 0;
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+int openmpt_module_is_pattern_skip_pattern( openmpt_module * mod, int32_t pattern ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->is_pattern_skip_pattern( pattern ) ? 1 : 0;
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+int openmpt_module_is_order_stop_pattern( openmpt_module * mod, int32_t order ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->is_order_stop_pattern( order ) ? 1 : 0;
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+int openmpt_module_is_is_order_stop_pattern( openmpt_module * mod, int32_t pattern ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->is_order_stop_pattern( pattern ) ? 1 : 0;
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+
+
 int32_t openmpt_module_get_pattern_num_rows( openmpt_module * mod, int32_t pattern ) {
 	try {
 		openmpt::interface::check_soundfile( mod );
Index: libopenmpt/libopenmpt_cxx.cpp
===================================================================
--- libopenmpt/libopenmpt_cxx.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_cxx.cpp	(working copy)
@@ -389,6 +389,20 @@
 std::int32_t module::get_order_pattern( std::int32_t order ) const {
 	return impl->get_order_pattern( order );
 }
+
+bool module::is_order_skip_pattern(std::int32_t order) const {
+	return impl->is_order_skip_pattern( order );
+}
+bool module::is_pattern_skip_pattern( std::int32_t pattern ) const {
+	return module_impl::is_pattern_skip_pattern( pattern );
+}
+bool module::is_order_stop_pattern( std::int32_t order ) const {
+	return impl->is_order_stop_pattern( order );
+}
+bool module::is_pattern_stop_pattern( std::int32_t pattern ) const {
+	return module_impl::is_pattern_stop_pattern( pattern );
+}
+
 std::int32_t module::get_pattern_num_rows( std::int32_t pattern ) const {
 	return impl->get_pattern_num_rows( pattern );
 }
Index: libopenmpt/libopenmpt_impl.cpp
===================================================================
--- libopenmpt/libopenmpt_impl.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_impl.cpp	(working copy)
@@ -1457,6 +1457,26 @@
 	}
 	return m_sndFile->Order()[o];
 }
+
+bool module_impl::is_order_skip_pattern( std::int32_t order ) const {
+	if ( order < 0 || order >= m_sndFile->Order().GetLengthTailTrimmed() ) {
+		return false;
+	}
+	return is_pattern_skip_pattern( m_sndFile->Order()[order] );
+}
+bool module_impl::is_pattern_skip_pattern( std::int32_t pattern ) {
+	return pattern == OpenMPT::PATTERNINDEX_SKIP;
+}
+bool module_impl::is_order_stop_pattern( std::int32_t order ) const {
+	if ( order < 0 || order >= m_sndFile->Order().GetLengthTailTrimmed() ) {
+		return false;
+	}
+	return is_pattern_stop_pattern( m_sndFile->Order()[order] );
+}
+bool module_impl::is_pattern_stop_pattern( std::int32_t pattern ) {
+	return pattern == OpenMPT::PATTERNINDEX_INVALID;
+}
+
 std::int32_t module_impl::get_pattern_num_rows( std::int32_t p ) const {
 	if ( !mpt::is_in_range( p, std::numeric_limits<OpenMPT::PATTERNINDEX>::min(), std::numeric_limits<OpenMPT::PATTERNINDEX>::max() ) || !m_sndFile->Patterns.IsValidPat( static_cast<OpenMPT::PATTERNINDEX>( p ) ) ) {
 		return 0;
Index: libopenmpt/libopenmpt_impl.hpp
===================================================================
--- libopenmpt/libopenmpt_impl.hpp	(revision 21858)
+++ libopenmpt/libopenmpt_impl.hpp	(working copy)
@@ -244,6 +244,10 @@
 	std::vector<std::string> get_instrument_names() const;
 	std::vector<std::string> get_sample_names() const;
 	std::int32_t get_order_pattern( std::int32_t o ) const;
+	bool is_order_skip_pattern( std::int32_t order ) const;
+	static bool is_pattern_skip_pattern( std::int32_t pattern );
+	bool is_order_stop_pattern( std::int32_t order ) const;
+	static bool is_pattern_stop_pattern( std::int32_t pattern );
 	std::int32_t get_pattern_num_rows( std::int32_t p ) const;
 	std::uint8_t get_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const;
 	std::string format_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const;
order_list_index-v2.patch (12,339 bytes)   
manx

manx

2024-10-19 17:29

administrator   ~0006107

I would not make is_pattern_skip_pattern static, even though it could be in the current implementation. There is a real danger that users might call it, independent from any module, see that it is always the same, and hardcode that value themselves, which is results in a leaked implementation detail magic value. Tying it to a module instance reduces that risk (not to zero, of course).

We additionally have the option to not name is_order_skip_pattern the way it is named, but instead remove the reference to pattern from its name, which would allow more orderlist-specific features independent of mapping to specific patterns (or magic pattern values). Maybe is_order_skip_order. Sounds somewhat bad, not sure if really useful.

Saga Musix

Saga Musix

2024-10-19 17:31

administrator   ~0006108

It's only static in the impl class; the actual C/C++ interface still requires a module instance.

Regarding the naming, we could also go for skip_item (in both order and pattern cases) and stop_item respectively.

manx

manx

2024-10-19 17:32

administrator   ~0006109

It's only static in the impl class

Oh, I missed that, that's fine of course.

manx

manx

2024-10-19 17:34

administrator   ~0006110

item makes sense for pattern, for order one could maybe also consider entry.

Saga Musix

Saga Musix

2024-10-19 17:35

administrator   ~0006111

That makes the two API variants even more distinct, which is probably good for telling them apart. I will try that.

Saga Musix

Saga Musix

2024-10-19 17:41

administrator   ~0006112

Renamed to is_order_skip_entry, is_pattern_skip_item, is_order_stop_entry, is_pattern_stop_item.

order_list_index-v3.patch (12,201 bytes)   
Index: libopenmpt/bindings/freebasic/libopenmpt.bi
===================================================================
--- libopenmpt/bindings/freebasic/libopenmpt.bi	(revision 21858)
+++ libopenmpt/bindings/freebasic/libopenmpt.bi	(working copy)
@@ -1273,6 +1273,39 @@
 '/
 Declare Function openmpt_module_get_order_pattern(ByVal module As openmpt_module Ptr, ByVal order As Long) As Long
 
+/'* \brief Check if specified order is a skip ("+++") item
+
+  \param The order item to check.
+  \return Returns non-zero value if the pattern index at the given order position represents a skip item. During playback, this item is ignored and playback resumes at the next order list item.
+  \sa openmpt_module_is_order_stop_entry, openmpt_module_is_pattern_skip_item
+  \since 0.8.0
+'/
+Declare Function openmpt_module_is_order_skip_entry(ByVal module As openmpt_module Ptr, ByVal order As Long) As Long
+/'* \brief Check if specified pattern index is a skip ("+++") item
+
+  \param The pattern index to check.
+  \return Returns non-zero value if the pattern index represents a skip item. During playback, this item is ignored and playback resumes at the next order list item.
+  \sa openmpt_module_is_pattern_stop_item, openmpt_module_is_order_skip_entry, openmpt_module_get_order_pattern
+  \since 0.8.0
+'/
+Declare Function openmpt_module_is_pattern_skip_item(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
+/'* \brief Check if specified order is a stop ("---") item
+
+  \param The order item to check.
+  \return Returns non-zero value if the pattern index at the given order position represents a stop item. When this item is reached, playback continues at the restart position of the current sub-song.
+  \sa openmpt_module_is_order_skip_entry, openmpt_module_is_pattern_stop_item
+  \since 0.8.0
+'/
+Declare Function openmpt_module_is_order_stop_entry(ByVal module As openmpt_module Ptr, ByVal order As Long) As Long
+/'* \brief Check if specified pattern index is a stop ("---") item
+
+  \param The pattern index to check.
+  \return Returns non-zero value if the pattern index represents a stop item. When this item is reached, playback continues at the restart position of the current sub-song.
+  \sa openmpt_module_is_pattern_skip_item, openmpt_module_is_order_stop_entry, openmpt_module_get_order_pattern
+  \since 0.8.0
+'/
+Declare Function openmpt_module_is_pattern_stop_item(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
+
 /'* \brief Get the number of rows in a pattern
 
   \param module The module handle to work on.
Index: libopenmpt/libopenmpt.h
===================================================================
--- libopenmpt/libopenmpt.h	(revision 21858)
+++ libopenmpt/libopenmpt.h	(working copy)
@@ -1330,6 +1330,40 @@
  * \return The pattern index found at the given order position of the current sequence.
  */
 LIBOPENMPT_API int32_t openmpt_module_get_order_pattern( openmpt_module * mod, int32_t order );
+
+/*! \brief Check if specified order is a skip ("+++") item
+ *
+ * \param The order item to check.
+ * \return Returns non-zero value if the pattern index at the given order position represents a skip item. During playback, this item is ignored and playback resumes at the next order list item.
+ * \sa openmpt_module_is_order_stop_entry, openmpt_module_is_pattern_skip_item
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int openmpt_module_is_order_skip_entry( openmpt_module * mod, int32_t order );
+/*! \brief Check if specified pattern index is a skip ("+++") item
+ *
+ * \param The pattern index to check.
+ * \return Returns non-zero value if the pattern index represents a skip item. During playback, this item is ignored and playback resumes at the next order list item.
+ * \sa openmpt_module_is_pattern_stop_item, openmpt_module_is_order_skip_entry, openmpt_module_get_order_pattern
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int openmpt_module_is_pattern_skip_item( openmpt_module * mod, int32_t pattern );
+/*! \brief Check if specified order is a stop ("---") item
+ *
+ * \param The order item to check.
+ * \return Returns non-zero value if the pattern index at the given order position represents a stop item. When this item is reached, playback continues at the restart position of the current sub-song.
+ * \sa openmpt_module_is_order_skip_entry, openmpt_module_is_pattern_stop_item
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int openmpt_module_is_order_stop_entry( openmpt_module * mod, int32_t order );
+/*! \brief Check if specified pattern index is a stop ("---") item
+ *
+ * \param The pattern index to check.
+ * \return Returns non-zero value if the pattern index represents a stop item. When this item is reached, playback continues at the restart position of the current sub-song.
+ * \sa openmpt_module_is_pattern_skip_item, openmpt_module_is_order_stop_entry, openmpt_module_get_order_pattern
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int openmpt_module_is_pattern_stop_item( openmpt_module * mod, int32_t pattern );
+
 /*! \brief Get the number of rows in a pattern
  *
  * \param mod The module handle to work on.
Index: libopenmpt/libopenmpt.hpp
===================================================================
--- libopenmpt/libopenmpt.hpp	(revision 21858)
+++ libopenmpt/libopenmpt.hpp	(working copy)
@@ -989,6 +989,39 @@
 	*/
 	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_order_pattern( std::int32_t order ) const;
 
+	//! Check if specified order is a skip ("+++") item
+	/*!
+	  \param The order item to check.
+	  \return Returns true if the pattern index at the given order position represents a skip item. During playback, this item is ignored and playback resumes at the next order list item.
+	  \sa openmpt::module::is_order_stop_entry, openmpt::module::is_pattern_skip_item
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER bool is_order_skip_entry( std::int32_t order ) const ;
+	//! Check if specified pattern index is a skip ("+++") item
+	/*!
+	  \param The pattern index to check.
+	  \return Returns true if the pattern index represents a skip item. During playback, this item is ignored and playback resumes at the next order list item.
+	  \sa openmpt::module::is_pattern_stop_item, openmpt::module::is_order_skip_entry, openmpt::module::get_order_pattern
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER bool is_pattern_skip_item( std::int32_t pattern ) const;
+	//! Check if specified order is a stop ("---") item
+	/*!
+	  \param The order item to check.
+	  \return Returns true if the pattern index at the given order position represents a stop item. When this item is reached, playback continues at the restart position of the current sub-song.
+	  \sa openmpt::module::is_order_skip_entry, openmpt::module::is_pattern_stop_item
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER bool is_order_stop_entry( std::int32_t order ) const;
+	//! Check if specified pattern index is a stop ("---") item
+	/*!
+	  \param The pattern index to check.
+	  \return Returns true if the pattern index represents a stop item. When this item is reached, playback continues at the restart position of the current sub-song.
+	  \sa openmpt::module::is_pattern_skip_item, openmpt::module::is_order_stop_entry, openmpt::module::get_order_pattern
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER bool is_pattern_stop_item( std::int32_t pattern ) const;
+
 	//! Get the number of rows in a pattern
 	/*!
 	  \param pattern The pattern whose row count should be retrieved.
Index: libopenmpt/libopenmpt_c.cpp
===================================================================
--- libopenmpt/libopenmpt_c.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_c.cpp	(working copy)
@@ -1225,6 +1225,44 @@
 	return 0;
 }
 
+int openmpt_module_is_order_skip_entry( openmpt_module * mod, int32_t order ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->is_order_skip_entry( order ) ? 1 : 0;
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+int openmpt_module_is_pattern_skip_item( openmpt_module * mod, int32_t pattern ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->is_pattern_skip_item( pattern ) ? 1 : 0;
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+int openmpt_module_is_order_stop_entry( openmpt_module * mod, int32_t order ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->is_order_stop_entry( order ) ? 1 : 0;
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+int openmpt_module_is_pattern_stop_item( openmpt_module * mod, int32_t pattern ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->is_pattern_stop_item( pattern ) ? 1 : 0;
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+
+
 int32_t openmpt_module_get_pattern_num_rows( openmpt_module * mod, int32_t pattern ) {
 	try {
 		openmpt::interface::check_soundfile( mod );
Index: libopenmpt/libopenmpt_cxx.cpp
===================================================================
--- libopenmpt/libopenmpt_cxx.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_cxx.cpp	(working copy)
@@ -389,6 +389,20 @@
 std::int32_t module::get_order_pattern( std::int32_t order ) const {
 	return impl->get_order_pattern( order );
 }
+
+bool module::is_order_skip_entry(std::int32_t order) const {
+	return impl->is_order_skip_entry( order );
+}
+bool module::is_pattern_skip_item( std::int32_t pattern ) const {
+	return module_impl::is_pattern_skip_item( pattern );
+}
+bool module::is_order_stop_entry( std::int32_t order ) const {
+	return impl->is_order_stop_entry( order );
+}
+bool module::is_pattern_stop_item( std::int32_t pattern ) const {
+	return module_impl::is_pattern_stop_item( pattern );
+}
+
 std::int32_t module::get_pattern_num_rows( std::int32_t pattern ) const {
 	return impl->get_pattern_num_rows( pattern );
 }
Index: libopenmpt/libopenmpt_impl.cpp
===================================================================
--- libopenmpt/libopenmpt_impl.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_impl.cpp	(working copy)
@@ -1457,6 +1457,26 @@
 	}
 	return m_sndFile->Order()[o];
 }
+
+bool module_impl::is_order_skip_entry( std::int32_t order ) const {
+	if ( order < 0 || order >= m_sndFile->Order().GetLengthTailTrimmed() ) {
+		return false;
+	}
+	return is_pattern_skip_item( m_sndFile->Order()[order] );
+}
+bool module_impl::is_pattern_skip_item( std::int32_t pattern ) {
+	return pattern == OpenMPT::PATTERNINDEX_SKIP;
+}
+bool module_impl::is_order_stop_entry( std::int32_t order ) const {
+	if ( order < 0 || order >= m_sndFile->Order().GetLengthTailTrimmed() ) {
+		return false;
+	}
+	return is_pattern_stop_item( m_sndFile->Order()[order] );
+}
+bool module_impl::is_pattern_stop_item( std::int32_t pattern ) {
+	return pattern == OpenMPT::PATTERNINDEX_INVALID;
+}
+
 std::int32_t module_impl::get_pattern_num_rows( std::int32_t p ) const {
 	if ( !mpt::is_in_range( p, std::numeric_limits<OpenMPT::PATTERNINDEX>::min(), std::numeric_limits<OpenMPT::PATTERNINDEX>::max() ) || !m_sndFile->Patterns.IsValidPat( static_cast<OpenMPT::PATTERNINDEX>( p ) ) ) {
 		return 0;
Index: libopenmpt/libopenmpt_impl.hpp
===================================================================
--- libopenmpt/libopenmpt_impl.hpp	(revision 21858)
+++ libopenmpt/libopenmpt_impl.hpp	(working copy)
@@ -244,6 +244,10 @@
 	std::vector<std::string> get_instrument_names() const;
 	std::vector<std::string> get_sample_names() const;
 	std::int32_t get_order_pattern( std::int32_t o ) const;
+	bool is_order_skip_entry( std::int32_t order ) const;
+	static bool is_pattern_skip_item( std::int32_t pattern );
+	bool is_order_stop_entry( std::int32_t order ) const;
+	static bool is_pattern_stop_item( std::int32_t pattern );
 	std::int32_t get_pattern_num_rows( std::int32_t p ) const;
 	std::uint8_t get_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const;
 	std::string format_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const;
order_list_index-v3.patch (12,201 bytes)   
manx

manx

2024-10-20 08:03

administrator   ~0006116

looks good

Saga Musix

Saga Musix

2024-10-20 11:22

administrator   ~0006118

Added in r21863.

manx

manx

2024-10-20 11:53

administrator   ~0006129

0.8.0-pre.8

Issue History

Date Modified Username Field Change
2024-03-30 13:14 Saga Musix New Issue
2024-03-30 13:15 Saga Musix Note Added: 0005893
2024-03-30 13:16 manx Relationship added related to 0001017
2024-03-30 13:16 manx Assigned To => manx
2024-03-30 13:16 manx Status new => confirmed
2024-03-30 13:18 manx Note Added: 0005894
2024-03-30 19:57 manx Note Added: 0005898
2024-03-30 21:56 Saga Musix Note Added: 0005899
2024-03-30 21:56 Saga Musix Note Edited: 0005899
2024-06-10 18:33 Saga Musix Note Added: 0005968
2024-10-19 12:34 Saga Musix Note Added: 0006098
2024-10-19 12:34 Saga Musix File Added: order_list_index.patch
2024-10-19 12:39 Saga Musix Assigned To manx => Saga Musix
2024-10-19 12:39 Saga Musix Status confirmed => feedback
2024-10-19 12:54 Saga Musix File Deleted: order_list_index.patch
2024-10-19 12:54 Saga Musix Note Added: 0006099
2024-10-19 12:54 Saga Musix File Added: order_list_index.patch
2024-10-19 12:57 manx Note Added: 0006100
2024-10-19 16:14 Saga Musix Relationship added related to 0001832
2024-10-19 17:17 Saga Musix Note Added: 0006106
2024-10-19 17:17 Saga Musix File Added: order_list_index-v2.patch
2024-10-19 17:29 manx Note Added: 0006107
2024-10-19 17:31 Saga Musix Note Added: 0006108
2024-10-19 17:32 manx Note Added: 0006109
2024-10-19 17:34 manx Note Added: 0006110
2024-10-19 17:35 Saga Musix Note Added: 0006111
2024-10-19 17:41 Saga Musix Note Added: 0006112
2024-10-19 17:41 Saga Musix File Added: order_list_index-v3.patch
2024-10-20 08:03 manx Note Added: 0006116
2024-10-20 11:22 Saga Musix Note Added: 0006118
2024-10-20 11:22 Saga Musix Status feedback => resolved
2024-10-20 11:22 Saga Musix Resolution open => fixed
2024-10-20 11:22 Saga Musix Fixed in Version => OpenMPT 1.32 / libopenmpt 0.8 (goals)
2024-10-20 11:53 manx Note Added: 0006129