View Issue Details

IDProjectCategoryView StatusLast Update
0001832OpenMPTlibopenmptpublic2024-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) 
Summary0001832: libopenmpt API addition: Retrieve pattern highlights
Description

libopenmpt should provide functions for retrieving the rows per beat and rows per mesaure settings.

Since this value can differ from pattern to pattern, the API should probably look like this:

int32 module::get_rows_per_beat(int32 pattern)
int32 module::get_rows_per_measure(int32 pattern)

Or, similar to 0001766, we need to provide a variant for both pattern and order retrieval:

int32 module::get_rows_per_beat_pattern(int32 pattern)
int32 module::get_rows_per_measure_pattern(int32 pattern)
int32 module::get_rows_per_beat_order(int32 order)
int32 module::get_rows_per_measure_order(int32 order)
TagsNo tags attached.
Has the bug occurred in previous versions?
Tested code revision (in case you know it)

Relationships

related to 0001766 resolvedSaga Musix Provide a way to retrieve numeric values of +++ and --- values via libopenmpt API 

Activities

Saga Musix

Saga Musix

2024-10-19 16:32

administrator   ~0006103

pattern-time-signatures-v1.patch (8,784 bytes)   
Index: libopenmpt/bindings/freebasic/libopenmpt.bi
===================================================================
--- libopenmpt/bindings/freebasic/libopenmpt.bi	(revision 21858)
+++ libopenmpt/bindings/freebasic/libopenmpt.bi	(working copy)
@@ -1281,6 +1281,26 @@
 '/
 Declare Function openmpt_module_get_pattern_num_rows(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
 
+/'* \brief Get the rows per beat of a pattern
+
+  \param mod The module handle to work on.
+  \param pattern The pattern whose time signature should be retrieved.
+  \return The rows per beat of the given pattern. If the pattern does not exist, 0 is returned.
+  \remarks Many module format do not support time signature information. In this case, the returned value may be an incorrect estimation.
+  \since 0.8.0
+'/
+Declare Function openmpt_module_get_pattern_rows_per_beat(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
+
+/'* \brief Get the rows per beat of a measure
+
+  \param mod The module handle to work on.
+  \param pattern The pattern whose time signature should be retrieved.
+  \return The rows per measure of the given pattern. If the pattern does not exist, 0 is returned.
+  \remarks Many module format do not support time signature information. In this case, the returned value may be an incorrect estimation.
+  \since 0.8.0
+'/
+Declare Function openmpt_module_get_pattern_rows_per_measure(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
+
 /'* \brief Get raw pattern content
 
   \param module The module handle to work on.
Index: libopenmpt/libopenmpt.h
===================================================================
--- libopenmpt/libopenmpt.h	(revision 21858)
+++ libopenmpt/libopenmpt.h	(working copy)
@@ -1338,6 +1338,25 @@
  */
 LIBOPENMPT_API int32_t openmpt_module_get_pattern_num_rows( openmpt_module * mod, int32_t pattern );
 
+/*! \brief Get the rows per beat of a pattern
+ *
+ * \param mod The module handle to work on.
+ * \param pattern The pattern whose time signature should be retrieved.
+ * \return The rows per beat of the given pattern. If the pattern does not exist, 0 is returned.
+ * \remarks Many module format do not support time signature information. In this case, the returned value may be an incorrect estimation.
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_pattern_rows_per_beat( openmpt_module * mod, int32_t pattern );
+
+/*! \brief Get the rows per beat of a measure
+ *
+ * \param mod The module handle to work on.
+ * \param pattern The pattern whose time signature should be retrieved.
+ * \return The rows per measure of the given pattern. If the pattern does not exist, 0 is returned.
+ * \remarks Many module format do not support time signature information. In this case, the returned value may be an incorrect estimation.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_pattern_rows_per_measure(openmpt_module* mod, int32_t pattern);
+
 /*! \brief Get raw pattern content
  *
  * \param mod The module handle to work on.
Index: libopenmpt/libopenmpt.hpp
===================================================================
--- libopenmpt/libopenmpt.hpp	(revision 21858)
+++ libopenmpt/libopenmpt.hpp	(working copy)
@@ -996,6 +996,24 @@
 	*/
 	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_pattern_num_rows( std::int32_t pattern ) const;
 
+	//! Get the rows per beat of a pattern
+	/*!
+	  \param pattern The pattern whose time signature should be retrieved.
+	  \return The rows per beat of the given pattern. If the pattern does not exist, 0 is returned.
+	  \remarks Many module format do not support time signature information. In this case, the returned value may be an incorrect estimation.
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_pattern_rows_per_beat( std::int32_t pattern ) const;
+
+	//! Get the rows per beat of a measure
+	/*!
+	  \param pattern The pattern whose time signature should be retrieved.
+	  \return The rows per measure of the given pattern. If the pattern does not exist, 0 is returned.
+	  \remarks Many module format do not support time signature information. In this case, the returned value may be an incorrect estimation.
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_pattern_rows_per_measure( std::int32_t pattern ) const;
+
 	//! Get raw pattern content
 	/*!
 	  \param pattern The pattern whose data should be retrieved.
Index: libopenmpt/libopenmpt_c.cpp
===================================================================
--- libopenmpt/libopenmpt_c.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_c.cpp	(working copy)
@@ -1235,6 +1235,25 @@
 	return 0;
 }
 
+int32_t openmpt_module_get_pattern_rows_per_beat( openmpt_module * mod, int32_t pattern ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_pattern_rows_per_beat( pattern );
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+int32_t openmpt_module_get_pattern_rows_per_measure( openmpt_module * mod, int32_t pattern ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_pattern_rows_per_measure( pattern );
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+
 uint8_t openmpt_module_get_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command ) {
 	try {
 		openmpt::interface::check_soundfile( mod );
Index: libopenmpt/libopenmpt_cxx.cpp
===================================================================
--- libopenmpt/libopenmpt_cxx.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_cxx.cpp	(working copy)
@@ -393,6 +393,14 @@
 	return impl->get_pattern_num_rows( pattern );
 }
 
+std::int32_t module::get_pattern_rows_per_beat( std::int32_t pattern ) const {
+	return impl->get_pattern_rows_per_beat( pattern );
+}
+
+std::int32_t module::get_pattern_rows_per_measure( std::int32_t pattern ) const {
+	return impl->get_pattern_rows_per_measure( pattern );
+}
+
 std::uint8_t module::get_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const {
 	return impl->get_pattern_row_channel_command( pattern, row, channel, command );
 }
Index: libopenmpt/libopenmpt_impl.cpp
===================================================================
--- libopenmpt/libopenmpt_impl.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_impl.cpp	(working copy)
@@ -1464,6 +1464,26 @@
 	return m_sndFile->Patterns[p].GetNumRows();
 }
 
+std::int32_t module_impl::get_pattern_rows_per_beat( 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;
+	}
+	if ( m_sndFile->Patterns[p].GetOverrideSignature() ) {
+		return m_sndFile->Patterns[p].GetRowsPerBeat();
+	}
+	return m_sndFile->m_nDefaultRowsPerBeat;
+}
+
+std::int32_t module_impl::get_pattern_rows_per_measure( 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;
+	}
+	if ( m_sndFile->Patterns[p].GetOverrideSignature() ) {
+		return m_sndFile->Patterns[p].GetRowsPerMeasure();
+	}
+	return m_sndFile->m_nDefaultRowsPerMeasure;
+}
+
 std::uint8_t module_impl::get_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) 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)
@@ -245,6 +245,8 @@
 	std::vector<std::string> get_sample_names() const;
 	std::int32_t get_order_pattern( std::int32_t o ) const;
 	std::int32_t get_pattern_num_rows( std::int32_t p ) const;
+	std::int32_t get_pattern_rows_per_beat( std::int32_t pattern ) const;
+	std::int32_t get_pattern_rows_per_measure( std::int32_t pattern ) 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;
 	std::string highlight_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const;
Saga Musix

Saga Musix

2024-10-19 16:42

administrator   ~0006104

On second thought, these functions are typically not to be used in an order list context, so only having a pattern variant (as with get_pattern_num_rows) should be enough.

Saga Musix

Saga Musix

2024-10-19 19:05

administrator   ~0006113

Documenting that the functions may also return 0 if the time signature is undefined, just in case that ever becomes a possibility.

pattern-time-signatures-v2.patch (9,128 bytes)   
Index: libopenmpt/bindings/freebasic/libopenmpt.bi
===================================================================
--- libopenmpt/bindings/freebasic/libopenmpt.bi	(revision 21858)
+++ libopenmpt/bindings/freebasic/libopenmpt.bi	(working copy)
@@ -1281,6 +1281,26 @@
 '/
 Declare Function openmpt_module_get_pattern_num_rows(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
 
+/'* \brief Get the rows per beat of a pattern
+
+  \param mod The module handle to work on.
+  \param pattern The pattern whose time signature should be retrieved.
+  \return The rows per beat of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+  \remarks Many module format do not support time signature information. In this case, the returned value may be an incorrect estimation.
+  \since 0.8.0
+'/
+Declare Function openmpt_module_get_pattern_rows_per_beat(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
+
+/'* \brief Get the rows per beat of a measure
+
+  \param mod The module handle to work on.
+  \param pattern The pattern whose time signature should be retrieved.
+  \return The rows per measure of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+  \remarks Many module format do not support time signature information. In this case, the returned value may be an incorrect estimation.
+  \since 0.8.0
+'/
+Declare Function openmpt_module_get_pattern_rows_per_measure(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
+
 /'* \brief Get raw pattern content
 
   \param module The module handle to work on.
Index: libopenmpt/libopenmpt.h
===================================================================
--- libopenmpt/libopenmpt.h	(revision 21858)
+++ libopenmpt/libopenmpt.h	(working copy)
@@ -1338,6 +1338,25 @@
  */
 LIBOPENMPT_API int32_t openmpt_module_get_pattern_num_rows( openmpt_module * mod, int32_t pattern );
 
+/*! \brief Get the rows per beat of a pattern
+ *
+ * \param mod The module handle to work on.
+ * \param pattern The pattern whose time signature should be retrieved.
+ * \return The rows per beat of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+ * \remarks Many module format do not support time signature information. In this case, the returned value may be an incorrect estimation.
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_pattern_rows_per_beat( openmpt_module * mod, int32_t pattern );
+
+/*! \brief Get the rows per beat of a measure
+ *
+ * \param mod The module handle to work on.
+ * \param pattern The pattern whose time signature should be retrieved.
+ * \return The rows per measure of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+ * \remarks Many module format do not support time signature information. In this case, the returned value may be an incorrect estimation.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_pattern_rows_per_measure(openmpt_module* mod, int32_t pattern);
+
 /*! \brief Get raw pattern content
  *
  * \param mod The module handle to work on.
Index: libopenmpt/libopenmpt.hpp
===================================================================
--- libopenmpt/libopenmpt.hpp	(revision 21858)
+++ libopenmpt/libopenmpt.hpp	(working copy)
@@ -996,6 +996,24 @@
 	*/
 	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_pattern_num_rows( std::int32_t pattern ) const;
 
+	//! Get the rows per beat of a pattern
+	/*!
+	  \param pattern The pattern whose time signature should be retrieved.
+	  \return The rows per beat of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+	  \remarks Many module format do not support time signature information. In this case, the returned value may be an incorrect estimation.
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_pattern_rows_per_beat( std::int32_t pattern ) const;
+
+	//! Get the rows per beat of a measure
+	/*!
+	  \param pattern The pattern whose time signature should be retrieved.
+	  \return The rows per measure of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+	  \remarks Many module format do not support time signature information. In this case, the returned value may be an incorrect estimation.
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_pattern_rows_per_measure( std::int32_t pattern ) const;
+
 	//! Get raw pattern content
 	/*!
 	  \param pattern The pattern whose data should be retrieved.
Index: libopenmpt/libopenmpt_c.cpp
===================================================================
--- libopenmpt/libopenmpt_c.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_c.cpp	(working copy)
@@ -1235,6 +1235,25 @@
 	return 0;
 }
 
+int32_t openmpt_module_get_pattern_rows_per_beat( openmpt_module * mod, int32_t pattern ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_pattern_rows_per_beat( pattern );
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+int32_t openmpt_module_get_pattern_rows_per_measure( openmpt_module * mod, int32_t pattern ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_pattern_rows_per_measure( pattern );
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+
 uint8_t openmpt_module_get_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command ) {
 	try {
 		openmpt::interface::check_soundfile( mod );
Index: libopenmpt/libopenmpt_cxx.cpp
===================================================================
--- libopenmpt/libopenmpt_cxx.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_cxx.cpp	(working copy)
@@ -393,6 +393,14 @@
 	return impl->get_pattern_num_rows( pattern );
 }
 
+std::int32_t module::get_pattern_rows_per_beat( std::int32_t pattern ) const {
+	return impl->get_pattern_rows_per_beat( pattern );
+}
+
+std::int32_t module::get_pattern_rows_per_measure( std::int32_t pattern ) const {
+	return impl->get_pattern_rows_per_measure( pattern );
+}
+
 std::uint8_t module::get_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const {
 	return impl->get_pattern_row_channel_command( pattern, row, channel, command );
 }
Index: libopenmpt/libopenmpt_impl.cpp
===================================================================
--- libopenmpt/libopenmpt_impl.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_impl.cpp	(working copy)
@@ -1464,6 +1464,26 @@
 	return m_sndFile->Patterns[p].GetNumRows();
 }
 
+std::int32_t module_impl::get_pattern_rows_per_beat( 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;
+	}
+	if ( m_sndFile->Patterns[p].GetOverrideSignature() ) {
+		return m_sndFile->Patterns[p].GetRowsPerBeat();
+	}
+	return m_sndFile->m_nDefaultRowsPerBeat;
+}
+
+std::int32_t module_impl::get_pattern_rows_per_measure( 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;
+	}
+	if ( m_sndFile->Patterns[p].GetOverrideSignature() ) {
+		return m_sndFile->Patterns[p].GetRowsPerMeasure();
+	}
+	return m_sndFile->m_nDefaultRowsPerMeasure;
+}
+
 std::uint8_t module_impl::get_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) 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)
@@ -245,6 +245,8 @@
 	std::vector<std::string> get_sample_names() const;
 	std::int32_t get_order_pattern( std::int32_t o ) const;
 	std::int32_t get_pattern_num_rows( std::int32_t p ) const;
+	std::int32_t get_pattern_rows_per_beat( std::int32_t pattern ) const;
+	std::int32_t get_pattern_rows_per_measure( std::int32_t pattern ) 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;
 	std::string highlight_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const;
manx

manx

2024-10-20 08:02

administrator   ~0006115

Typo at "Many module formats do not ".

Maybe we can return -1 for invalid pattern? We do not appear to do that for similar functions, but it's probably better to not shove "undefined value" and "invalid pattern" into the same return value.

Saga Musix

Saga Musix

2024-10-20 10:02

administrator   ~0006117

I thought about that too but I reached the conclusion that an empty / non-existing pattern does, in fact, not have a defined time signature, so you could argue that the function returns 0 because the pattern's time signature is undefined, not because the pattern doesn't exist. I have no strong feelings for interpreting it that way, though, either way works.

Saga Musix

Saga Musix

2024-10-20 11:29

administrator   ~0006120

Comment updated. It now uses the same wording as openmpt_module_get_current_estimated_bpm.

pattern-time-signatures-v3.patch (8,941 bytes)   
Index: libopenmpt/bindings/freebasic/libopenmpt.bi
===================================================================
--- libopenmpt/bindings/freebasic/libopenmpt.bi	(revision 21863)
+++ libopenmpt/bindings/freebasic/libopenmpt.bi	(working copy)
@@ -1314,6 +1314,26 @@
 '/
 Declare Function openmpt_module_get_pattern_num_rows(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
 
+/'* \brief Get the rows per beat of a pattern
+
+  \param mod The module handle to work on.
+  \param pattern The pattern whose time signature should be retrieved.
+  \return The rows per beat of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+  \remarks Many module formats lack time signature metadata. In this case, the returned value may be an incorrect estimation.
+  \since 0.8.0
+'/
+Declare Function openmpt_module_get_pattern_rows_per_beat(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
+
+/'* \brief Get the rows per beat of a measure
+
+  \param mod The module handle to work on.
+  \param pattern The pattern whose time signature should be retrieved.
+  \return The rows per measure of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+  \remarks Many module formats lack time signature metadata. In this case, the returned value may be an incorrect estimation.
+  \since 0.8.0
+'/
+Declare Function openmpt_module_get_pattern_rows_per_measure(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
+
 /'* \brief Get raw pattern content
 
   \param module The module handle to work on.
Index: libopenmpt/libopenmpt.h
===================================================================
--- libopenmpt/libopenmpt.h	(revision 21863)
+++ libopenmpt/libopenmpt.h	(working copy)
@@ -1372,6 +1372,25 @@
  */
 LIBOPENMPT_API int32_t openmpt_module_get_pattern_num_rows( openmpt_module * mod, int32_t pattern );
 
+/*! \brief Get the rows per beat of a pattern
+ *
+ * \param mod The module handle to work on.
+ * \param pattern The pattern whose time signature should be retrieved.
+ * \return The rows per beat of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+ * \remarks Many module formats lack time signature metadata. In this case, the returned value may be an incorrect estimation.
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_pattern_rows_per_beat( openmpt_module * mod, int32_t pattern );
+
+/*! \brief Get the rows per beat of a measure
+ *
+ * \param mod The module handle to work on.
+ * \param pattern The pattern whose time signature should be retrieved.
+ * \return The rows per measure of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+ * \remarks Many module formats lack time signature metadata. In this case, the returned value may be an incorrect estimation.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_pattern_rows_per_measure(openmpt_module* mod, int32_t pattern);
+
 /*! \brief Get raw pattern content
  *
  * \param mod The module handle to work on.
Index: libopenmpt/libopenmpt.hpp
===================================================================
--- libopenmpt/libopenmpt.hpp	(revision 21863)
+++ libopenmpt/libopenmpt.hpp	(working copy)
@@ -1029,6 +1029,24 @@
 	*/
 	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_pattern_num_rows( std::int32_t pattern ) const;
 
+	//! Get the rows per beat of a pattern
+	/*!
+	  \param pattern The pattern whose time signature should be retrieved.
+	  \return The rows per beat of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+	  \remarks Many module formats lack time signature metadata. In this case, the returned value may be an incorrect estimation.
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_pattern_rows_per_beat( std::int32_t pattern ) const;
+
+	//! Get the rows per beat of a measure
+	/*!
+	  \param pattern The pattern whose time signature should be retrieved.
+	  \return The rows per measure of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+	  \remarks Many module formats lack time signature metadata. In this case, the returned value may be an incorrect estimation.
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_pattern_rows_per_measure( std::int32_t pattern ) const;
+
 	//! Get raw pattern content
 	/*!
 	  \param pattern The pattern whose data should be retrieved.
Index: libopenmpt/libopenmpt_c.cpp
===================================================================
--- libopenmpt/libopenmpt_c.cpp	(revision 21863)
+++ libopenmpt/libopenmpt_c.cpp	(working copy)
@@ -1273,6 +1273,25 @@
 	return 0;
 }
 
+int32_t openmpt_module_get_pattern_rows_per_beat( openmpt_module * mod, int32_t pattern ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_pattern_rows_per_beat( pattern );
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+int32_t openmpt_module_get_pattern_rows_per_measure( openmpt_module * mod, int32_t pattern ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_pattern_rows_per_measure( pattern );
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+
 uint8_t openmpt_module_get_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command ) {
 	try {
 		openmpt::interface::check_soundfile( mod );
Index: libopenmpt/libopenmpt_cxx.cpp
===================================================================
--- libopenmpt/libopenmpt_cxx.cpp	(revision 21863)
+++ libopenmpt/libopenmpt_cxx.cpp	(working copy)
@@ -407,6 +407,14 @@
 	return impl->get_pattern_num_rows( pattern );
 }
 
+std::int32_t module::get_pattern_rows_per_beat( std::int32_t pattern ) const {
+	return impl->get_pattern_rows_per_beat( pattern );
+}
+
+std::int32_t module::get_pattern_rows_per_measure( std::int32_t pattern ) const {
+	return impl->get_pattern_rows_per_measure( pattern );
+}
+
 std::uint8_t module::get_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const {
 	return impl->get_pattern_row_channel_command( pattern, row, channel, command );
 }
Index: libopenmpt/libopenmpt_impl.cpp
===================================================================
--- libopenmpt/libopenmpt_impl.cpp	(revision 21863)
+++ libopenmpt/libopenmpt_impl.cpp	(working copy)
@@ -1484,6 +1484,26 @@
 	return m_sndFile->Patterns[p].GetNumRows();
 }
 
+std::int32_t module_impl::get_pattern_rows_per_beat( 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;
+	}
+	if ( m_sndFile->Patterns[p].GetOverrideSignature() ) {
+		return m_sndFile->Patterns[p].GetRowsPerBeat();
+	}
+	return m_sndFile->m_nDefaultRowsPerBeat;
+}
+
+std::int32_t module_impl::get_pattern_rows_per_measure( 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;
+	}
+	if ( m_sndFile->Patterns[p].GetOverrideSignature() ) {
+		return m_sndFile->Patterns[p].GetRowsPerMeasure();
+	}
+	return m_sndFile->m_nDefaultRowsPerMeasure;
+}
+
 std::uint8_t module_impl::get_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) 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 21863)
+++ libopenmpt/libopenmpt_impl.hpp	(working copy)
@@ -249,6 +249,8 @@
 	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::int32_t get_pattern_rows_per_beat( std::int32_t pattern ) const;
+	std::int32_t get_pattern_rows_per_measure( std::int32_t pattern ) 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;
 	std::string highlight_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const;
manx

manx

2024-10-20 11:32

administrator   ~0006121

Get the rows per beat of a measure

"rows per measure of a pattern"?

LIBOPENMPT_API int32_t openmpt_module_get_pattern_rows_per_measure(openmpt_module* mod, int32_t pattern);

whitespace formatting

Saga Musix

Saga Musix

2024-10-20 11:41

administrator   ~0006122

Both fixed

pattern-time-signatures-v4.patch (8,953 bytes)   
Index: libopenmpt/bindings/freebasic/libopenmpt.bi
===================================================================
--- libopenmpt/bindings/freebasic/libopenmpt.bi	(revision 21864)
+++ libopenmpt/bindings/freebasic/libopenmpt.bi	(working copy)
@@ -1314,6 +1314,26 @@
 '/
 Declare Function openmpt_module_get_pattern_num_rows(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
 
+/'* \brief Get the rows per beat of a pattern
+
+  \param mod The module handle to work on.
+  \param pattern The pattern whose time signature should be retrieved.
+  \return The rows per beat of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+  \remarks Many module formats lack time signature metadata. In this case, the returned value may be an incorrect estimation.
+  \since 0.8.0
+'/
+Declare Function openmpt_module_get_pattern_rows_per_beat(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
+
+/'* \brief Get the rows per measure of a pattern
+
+  \param mod The module handle to work on.
+  \param pattern The pattern whose time signature should be retrieved.
+  \return The rows per measure of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+  \remarks Many module formats lack time signature metadata. In this case, the returned value may be an incorrect estimation.
+  \since 0.8.0
+'/
+Declare Function openmpt_module_get_pattern_rows_per_measure(ByVal module As openmpt_module Ptr, ByVal pattern As Long) As Long
+
 /'* \brief Get raw pattern content
 
   \param module The module handle to work on.
Index: libopenmpt/libopenmpt.h
===================================================================
--- libopenmpt/libopenmpt.h	(revision 21864)
+++ libopenmpt/libopenmpt.h	(working copy)
@@ -1372,6 +1372,25 @@
  */
 LIBOPENMPT_API int32_t openmpt_module_get_pattern_num_rows( openmpt_module * mod, int32_t pattern );
 
+/*! \brief Get the rows per beat of a pattern
+ *
+ * \param mod The module handle to work on.
+ * \param pattern The pattern whose time signature should be retrieved.
+ * \return The rows per beat of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+ * \remarks Many module formats lack time signature metadata. In this case, the returned value may be an incorrect estimation.
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_pattern_rows_per_beat( openmpt_module * mod, int32_t pattern );
+
+/*! \brief Get the rows per measure of a pattern
+ *
+ * \param mod The module handle to work on.
+ * \param pattern The pattern whose time signature should be retrieved.
+ * \return The rows per measure of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+ * \remarks Many module formats lack time signature metadata. In this case, the returned value may be an incorrect estimation.
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_pattern_rows_per_measure( openmpt_module * mod, int32_t pattern );
+
 /*! \brief Get raw pattern content
  *
  * \param mod The module handle to work on.
Index: libopenmpt/libopenmpt.hpp
===================================================================
--- libopenmpt/libopenmpt.hpp	(revision 21864)
+++ libopenmpt/libopenmpt.hpp	(working copy)
@@ -1029,6 +1029,24 @@
 	*/
 	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_pattern_num_rows( std::int32_t pattern ) const;
 
+	//! Get the rows per beat of a pattern
+	/*!
+	  \param pattern The pattern whose time signature should be retrieved.
+	  \return The rows per beat of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+	  \remarks Many module formats lack time signature metadata. In this case, the returned value may be an incorrect estimation.
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_pattern_rows_per_beat( std::int32_t pattern ) const;
+
+	//! Get the rows per measure of a pattern
+	/*!
+	  \param pattern The pattern whose time signature should be retrieved.
+	  \return The rows per measure of the given pattern. If the pattern does not exist or the time signature is not defined, 0 is returned.
+	  \remarks Many module formats lack time signature metadata. In this case, the returned value may be an incorrect estimation.
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_pattern_rows_per_measure( std::int32_t pattern ) const;
+
 	//! Get raw pattern content
 	/*!
 	  \param pattern The pattern whose data should be retrieved.
Index: libopenmpt/libopenmpt_c.cpp
===================================================================
--- libopenmpt/libopenmpt_c.cpp	(revision 21864)
+++ libopenmpt/libopenmpt_c.cpp	(working copy)
@@ -1273,6 +1273,25 @@
 	return 0;
 }
 
+int32_t openmpt_module_get_pattern_rows_per_beat( openmpt_module * mod, int32_t pattern ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_pattern_rows_per_beat( pattern );
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+int32_t openmpt_module_get_pattern_rows_per_measure( openmpt_module * mod, int32_t pattern ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_pattern_rows_per_measure( pattern );
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return 0;
+}
+
 uint8_t openmpt_module_get_pattern_row_channel_command( openmpt_module * mod, int32_t pattern, int32_t row, int32_t channel, int command ) {
 	try {
 		openmpt::interface::check_soundfile( mod );
Index: libopenmpt/libopenmpt_cxx.cpp
===================================================================
--- libopenmpt/libopenmpt_cxx.cpp	(revision 21864)
+++ libopenmpt/libopenmpt_cxx.cpp	(working copy)
@@ -407,6 +407,14 @@
 	return impl->get_pattern_num_rows( pattern );
 }
 
+std::int32_t module::get_pattern_rows_per_beat( std::int32_t pattern ) const {
+	return impl->get_pattern_rows_per_beat( pattern );
+}
+
+std::int32_t module::get_pattern_rows_per_measure( std::int32_t pattern ) const {
+	return impl->get_pattern_rows_per_measure( pattern );
+}
+
 std::uint8_t module::get_pattern_row_channel_command( std::int32_t pattern, std::int32_t row, std::int32_t channel, int command ) const {
 	return impl->get_pattern_row_channel_command( pattern, row, channel, command );
 }
Index: libopenmpt/libopenmpt_impl.cpp
===================================================================
--- libopenmpt/libopenmpt_impl.cpp	(revision 21864)
+++ libopenmpt/libopenmpt_impl.cpp	(working copy)
@@ -1484,6 +1484,26 @@
 	return m_sndFile->Patterns[p].GetNumRows();
 }
 
+std::int32_t module_impl::get_pattern_rows_per_beat( 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;
+	}
+	if ( m_sndFile->Patterns[p].GetOverrideSignature() ) {
+		return m_sndFile->Patterns[p].GetRowsPerBeat();
+	}
+	return m_sndFile->m_nDefaultRowsPerBeat;
+}
+
+std::int32_t module_impl::get_pattern_rows_per_measure( 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;
+	}
+	if ( m_sndFile->Patterns[p].GetOverrideSignature() ) {
+		return m_sndFile->Patterns[p].GetRowsPerMeasure();
+	}
+	return m_sndFile->m_nDefaultRowsPerMeasure;
+}
+
 std::uint8_t module_impl::get_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) 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 21864)
+++ libopenmpt/libopenmpt_impl.hpp	(working copy)
@@ -249,6 +249,8 @@
 	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::int32_t get_pattern_rows_per_beat( std::int32_t pattern ) const;
+	std::int32_t get_pattern_rows_per_measure( std::int32_t pattern ) 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;
 	std::string highlight_pattern_row_channel_command( std::int32_t p, std::int32_t r, std::int32_t c, int cmd ) const;
manx

manx

2024-10-20 11:47

administrator   ~0006124

looks good now

Saga Musix

Saga Musix

2024-10-20 11:49

administrator   ~0006125

Implemented in r21865.

manx

manx

2024-10-20 11:53

administrator   ~0006128

0.8.0-pre.9

Issue History

Date Modified Username Field Change
2024-10-19 16:13 Saga Musix New Issue
2024-10-19 16:13 Saga Musix Status new => assigned
2024-10-19 16:13 Saga Musix Assigned To => Saga Musix
2024-10-19 16:13 Saga Musix Description Updated
2024-10-19 16:14 Saga Musix Relationship added related to 0001766
2024-10-19 16:32 Saga Musix Note Added: 0006103
2024-10-19 16:32 Saga Musix File Added: pattern-time-signatures-v1.patch
2024-10-19 16:42 Saga Musix Note Added: 0006104
2024-10-19 19:05 Saga Musix Note Added: 0006113
2024-10-19 19:05 Saga Musix File Added: pattern-time-signatures-v2.patch
2024-10-19 19:27 Saga Musix Status assigned => feedback
2024-10-20 08:02 manx Note Added: 0006115
2024-10-20 10:02 Saga Musix Note Added: 0006117
2024-10-20 11:29 Saga Musix Note Added: 0006120
2024-10-20 11:29 Saga Musix File Added: pattern-time-signatures-v3.patch
2024-10-20 11:32 manx Note Added: 0006121
2024-10-20 11:41 Saga Musix Note Added: 0006122
2024-10-20 11:41 Saga Musix File Added: pattern-time-signatures-v4.patch
2024-10-20 11:47 manx Note Added: 0006124
2024-10-20 11:49 Saga Musix Note Added: 0006125
2024-10-20 11:49 Saga Musix Status feedback => resolved
2024-10-20 11:49 Saga Musix Resolution open => fixed
2024-10-20 11:49 Saga Musix Fixed in Version => OpenMPT 1.32 / libopenmpt 0.8 (goals)
2024-10-20 11:53 manx Note Added: 0006128