View Issue Details

IDProjectCategoryView StatusLast Update
0001675OpenMPTlibopenmptpublic2024-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) 
Summary0001675: libopenmpt API additions: retrieval of loop start position, playback time at given position
Description

Two useful API additions would be:

  • get_time_at_position(order, row) (similar to existing OpenMPT shortcut in pattern editor)
  • get_restart_position_order() / get_restart_position_row() - retrieve the order and row at which the currently selected subsong restarts. Need to determine the exact meaning in "all songs" playback mode, or maybe provide the subsong number as a parameter.

Combining those two APIs could give access to the position at which a module returns to when looping in seconds, but apart from that they can also provide other useful utilities (e.g. visualizing the module's order list and marking the restart position in a different color)

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

Activities

Saga Musix

Saga Musix

2024-10-19 16:09

administrator   ~0006102

get-time-at-position-v2.patch (5,985 bytes)   
Index: libopenmpt/bindings/freebasic/libopenmpt.bi
===================================================================
--- libopenmpt/bindings/freebasic/libopenmpt.bi	(revision 21858)
+++ libopenmpt/bindings/freebasic/libopenmpt.bi	(working copy)
@@ -806,6 +806,16 @@
 '/
 Declare Function openmpt_module_get_duration_seconds(ByVal module As openmpt_module Ptr) As Double
 
+/'* \brief Get approximate playback time in seconds at given position
+
+  \param module The module handle to work on.
+  \param order The order position at which the time should be retrieved.
+  \param row The pattern row number at which the time should be retrieved.
+  \return Approximate playback time in seconds of current sub-song at the given order and row combination. Negative if the position does not exist, or the pattern data is too complex to evaluate.
+  \since 0.8.0
+'/
+Declare Function openmpt_module_get_time_at_position(ByVal module As openmpt_module Ptr, ByVal order As Long, ByVal row As Long) As Double
+
+
 /'* \brief Set approximate current song position
 
   \param module The module handle to work on.
Index: libopenmpt/libopenmpt.h
===================================================================
--- libopenmpt/libopenmpt.h	(revision 21858)
+++ libopenmpt/libopenmpt.h	(working copy)
@@ -905,6 +905,15 @@
  */
 LIBOPENMPT_API double openmpt_module_get_duration_seconds( openmpt_module * mod );
 
+/*! \brief Get approximate playback time in seconds at given position
+ *
+ * \param mod The module handle to work on.
+ * \param order The order position at which the time should be retrieved.
+ * \param row The pattern row number at which the time should be retrieved.
+ * \return Approximate playback time in seconds of current sub-song at the given order and row combination. Negative if the position does not exist, or the pattern data is too complex to evaluate.
+ * \since 0.8.0
+ */
+LIBOPENMPT_API double openmpt_module_get_time_at_position( openmpt_module * mod, int32_t order, int32_t row );
+
 /*! \brief Set approximate current song position
  *
  * \param mod The module handle to work on.
Index: libopenmpt/libopenmpt.hpp
===================================================================
--- libopenmpt/libopenmpt.hpp	(revision 21858)
+++ libopenmpt/libopenmpt.hpp	(working copy)
@@ -618,6 +618,14 @@
 	*/
 	LIBOPENMPT_CXX_API_MEMBER double get_duration_seconds() const;
 
+	//! Get approximate playback time in seconds at given position
+	/*!
+	  \param order The order position at which the time should be retrieved.
+	  \param row The pattern row number at which the time should be retrieved.
+	  \return Approximate playback time in seconds of current sub-song at the given order and row combination. Negative if the position does not exist, or the pattern data is too complex to evaluate.
+	  \since 0.8.0
+	 */
+	LIBOPENMPT_CXX_API_MEMBER double get_time_at_position( std::int32_t order, std::int32_t row ) const;
+
 	//! Set approximate current song position
 	/*!
 	  \param seconds Seconds to seek to. If seconds is out of range, the position gets set to song start or end respectively.
Index: libopenmpt/libopenmpt_c.cpp
===================================================================
--- libopenmpt/libopenmpt_c.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_c.cpp	(working copy)
@@ -771,6 +771,16 @@
 	return 0.0;
 }
 
+double openmpt_module_get_time_at_position( openmpt_module * mod, int32_t order, int32_t row ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_time_at_position( order, row );
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return -1.0;
+}
+
 double openmpt_module_set_position_seconds( openmpt_module * mod, double seconds ) {
 	try {
 		openmpt::interface::check_soundfile( mod );
Index: libopenmpt/libopenmpt_cxx.cpp
===================================================================
--- libopenmpt/libopenmpt_cxx.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_cxx.cpp	(working copy)
@@ -251,6 +251,10 @@
 	return impl->get_duration_seconds();
 }
 
+double module::get_time_at_position( std::int32_t order, std::int32_t row ) const {
+	return impl->get_time_at_position( order, row );
+}
+
 double module::set_position_seconds( double seconds ) {
 	return impl->set_position_seconds( seconds );
 }
Index: libopenmpt/libopenmpt_impl.cpp
===================================================================
--- libopenmpt/libopenmpt_impl.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_impl.cpp	(working copy)
@@ -1075,6 +1075,15 @@
 	}
 	return subsongs[m_current_subsong].duration;
 }
+
+double module_impl::get_time_at_position( std::int32_t order, std::int32_t row ) const {
+	const auto t = m_sndFile->GetLength( OpenMPT::eNoAdjust, OpenMPT::GetLengthTarget( static_cast<OpenMPT::ORDERINDEX>( order ), static_cast<OpenMPT::ROWINDEX>( row ) ) ).back();
+	if ( t.targetReached )
+		return t.duration;
+	else
+		return -1.0;
+}
+
 void module_impl::select_subsong( std::int32_t subsong ) {
 	std::unique_ptr<subsongs_type> subsongs_temp = has_subsongs_inited() ? std::unique_ptr<subsongs_type>() : std::make_unique<subsongs_type>( get_subsongs() );
 	const subsongs_type & subsongs = has_subsongs_inited() ? m_subsongs : *subsongs_temp;
Index: libopenmpt/libopenmpt_impl.hpp
===================================================================
--- libopenmpt/libopenmpt_impl.hpp	(revision 21858)
+++ libopenmpt/libopenmpt_impl.hpp	(working copy)
@@ -201,6 +201,7 @@
 	void set_repeat_count( std::int32_t repeat_count );
 	std::int32_t get_repeat_count() const;
 	double get_duration_seconds() const;
+	double get_time_at_position( std::int32_t order, std::int32_t row ) const;
 	double set_position_seconds( double seconds );
 	double get_position_seconds() const;
 	double set_position_order_row( std::int32_t order, std::int32_t row );
get-time-at-position-v2.patch (5,985 bytes)   
restart-position-v1.patch (10,232 bytes)   
Index: libopenmpt/bindings/freebasic/libopenmpt.bi
===================================================================
--- libopenmpt/bindings/freebasic/libopenmpt.bi	(revision 21858)
+++ libopenmpt/bindings/freebasic/libopenmpt.bi	(working copy)
@@ -775,6 +775,25 @@
 '/
 Declare Function openmpt_module_get_selected_subsong(ByVal module As openmpt_module Ptr) As Long
 
+/'* \brief Get the restart order of the specified sub-song
+
+  \param module The module handle to work on.
+  \param subsong Index of the sub-song to retrieve the restart position from.
+  \return The restart order of the specified sub-song. This is the order to which playback returns after the last pattern row of the song has been played. -1 is returned if if sub-song is not in range [0,openmpt_module_get_num_subsongs()[
+  \sa openmpt_module_get_restart_row
+  \since 0.8.0
+'/
+Declare Function openmpt_module_get_restart_order(ByVal module As openmpt_module Ptr, ByVal subsong As Long) As Long
+/'* \brief Get the restart row of the specified sub-song
+
+  \param module The module handle to work on.
+  \param subsong Index of the sub-song to retrieve the restart position from.
+  \return The restart row of the specified sub-song. This is the first played row of the order to which playback returns after the last pattern row of the song has been played. -1 is returned if if sub-song is not in range [0,openmpt_module_get_num_subsongs()[
+  \sa openmpt_module_get_restart_order
+  \since 0.8.0
+'/
+Declare Function openmpt_module_get_restart_row(ByVal module As openmpt_module Ptr, ByVal subsong As Long) As Long
+
 /'* \brief Set Repeat Count
 
   \param module The module handle to work on.
Index: libopenmpt/libopenmpt.h
===================================================================
--- libopenmpt/libopenmpt.h	(revision 21858)
+++ libopenmpt/libopenmpt.h	(working copy)
@@ -875,6 +875,26 @@
  * \since 0.3.0
  */
 LIBOPENMPT_API int32_t openmpt_module_get_selected_subsong( openmpt_module * mod );
+
+/*! \brief Get the restart order of the specified sub-song
+ *
+ * \param mod The module handle to work on.
+ * \param subsong Index of the sub-song to retrieve the restart position from.
+ * \return The restart order of the specified sub-song. This is the order to which playback returns after the last pattern row of the song has been played. -1 is returned if if sub-song is not in range [0,openmpt_module_get_num_subsongs()[
+ * \sa openmpt_module_get_restart_row
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_restart_order( openmpt_module * mod, int32_t subsong );
+/*! \brief Get the restart row of the specified sub-song
+ *
+ * \param mod The module handle to work on.
+ * \param subsong Index of the sub-song to retrieve the restart position from.
+ * \return The restart row of the specified sub-song. This is the first played row of the order to which playback returns after the last pattern row of the song has been played. -1 is returned if if sub-song is not in range [0,openmpt_module_get_num_subsongs()[
+ * \sa openmpt_module_get_restart_order
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_restart_row( openmpt_module * mod, int32_t subsong );
+
 /*! \brief Set Repeat Count
  *
  * \param mod The module handle to work on.
Index: libopenmpt/libopenmpt.hpp
===================================================================
--- libopenmpt/libopenmpt.hpp	(revision 21858)
+++ libopenmpt/libopenmpt.hpp	(working copy)
@@ -592,6 +592,26 @@
 	  \since 0.3.0
 	*/
 	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_selected_subsong() const;
+
+	//! Get the restart order of the specified sub-song
+	/*!
+	  \param subsong Index of the sub-song to retrieve the restart position from.
+	  \return The restart order of the specified sub-song. This is the order to which playback returns after the last pattern row of the song has been played.
+	  \throws openmpt::exception Throws an exception derived from openmpt::exception if sub-song is not in range [0,openmpt::module::get_num_subsongs()[
+	  \sa openmpt::module::get_restart_row
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_restart_order( std::int32_t subsong ) const;
+	//! Get the restart row of the specified sub-song
+	/*!
+	  \param subsong Index of the sub-song to retrieve the restart position from.
+	  \return The restart row of the specified sub-song. This is the first played row of the order to which playback returns after the last pattern row of the song has been played.
+	  \throws openmpt::exception Throws an exception derived from openmpt::exception if sub-song is not in range [0,openmpt::module::get_num_subsongs()[
+	  \sa openmpt::module::get_restart_order
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_restart_row( std::int32_t subsong ) const;
+
 	//! Set Repeat Count
 	/*!
 	  \param repeat_count Repeat Count
Index: libopenmpt/libopenmpt_c.cpp
===================================================================
--- libopenmpt/libopenmpt_c.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_c.cpp	(working copy)
@@ -741,6 +741,26 @@
 	return -1;
 }
 
+int32_t openmpt_module_get_restart_order( openmpt_module * mod, int32_t subsong ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_restart_order( subsong );
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return -1;
+}
+
+int32_t openmpt_module_get_restart_row( openmpt_module * mod, int32_t subsong ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_restart_row( subsong );
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return -1;
+}
+
 int openmpt_module_set_repeat_count( openmpt_module * mod, int32_t repeat_count ) {
 	try {
 		openmpt::interface::check_soundfile( mod );
Index: libopenmpt/libopenmpt_cxx.cpp
===================================================================
--- libopenmpt/libopenmpt_cxx.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_cxx.cpp	(working copy)
@@ -240,6 +240,13 @@
 	return impl->get_selected_subsong();
 }
 
+std::int32_t module::get_restart_order( std::int32_t subsong ) const {
+	return impl->get_restart_order( subsong );
+}
+std::int32_t module::get_restart_row( std::int32_t subsong ) const {
+	return impl->get_restart_row( subsong );
+}
+
 void module::set_repeat_count( std::int32_t repeat_count ) {
 	impl->set_repeat_count( repeat_count );
 }
Index: libopenmpt/libopenmpt_impl.cpp
===================================================================
--- libopenmpt/libopenmpt_impl.cpp	(revision 21858)
+++ libopenmpt/libopenmpt_impl.cpp	(working copy)
@@ -306,11 +306,13 @@
 	m_sndFile->AddToLog( static_cast<OpenMPT::LogLevel>( loglevel ), mpt::transcode<mpt::ustring>( mpt::common_encoding::utf8, text ) );
 }
 
-module_impl::subsong_data::subsong_data( double duration, std::int32_t start_row, std::int32_t start_order, std::int32_t sequence )
+module_impl::subsong_data::subsong_data( double duration, std::int32_t start_row, std::int32_t start_order, std::int32_t sequence, std::int32_t restart_row, std::int32_t restart_order )
 	: duration(duration)
 	, start_row(start_row)
 	, start_order(start_order)
 	, sequence(sequence)
+	, restart_row( restart_row )
+	, restart_order(restart_order)
 {
 	return;
 }
@@ -436,7 +438,7 @@
 	for ( OpenMPT::SEQUENCEINDEX seq = 0; seq < m_sndFile->Order.GetNumSequences(); ++seq ) {
 		const std::vector<OpenMPT::GetLengthType> lengths = m_sndFile->GetLength( OpenMPT::eNoAdjust, OpenMPT::GetLengthTarget( true ).StartPos( seq, 0, 0 ) );
 		for ( const auto & l : lengths ) {
-			subsongs.push_back( subsong_data( l.duration, l.startRow, l.startOrder, seq ) );
+			subsongs.push_back( subsong_data( l.duration, l.startRow, l.startOrder, seq, l.lastRow, l.lastOrder ) );
 		}
 	}
 	return subsongs;
@@ -1093,6 +1095,24 @@
 std::int32_t module_impl::get_selected_subsong() const {
 	return m_current_subsong;
 }
+
+std::int32_t module_impl::get_restart_order( std::int32_t subsong ) const {
+	std::unique_ptr<subsongs_type> subsongs_temp = has_subsongs_inited() ? std::unique_ptr<subsongs_type>() : std::make_unique<subsongs_type>( get_subsongs() );
+	const subsongs_type & subsongs = has_subsongs_inited() ? m_subsongs : *subsongs_temp;
+	if ( subsong < 0 || subsong >= static_cast<std::int32_t>( subsongs.size() ) ) {
+		throw openmpt::exception( "invalid subsong" );
+	}
+	return subsongs[subsong].restart_order;
+}
+std::int32_t module_impl::get_restart_row( std::int32_t subsong ) const {
+	std::unique_ptr<subsongs_type> subsongs_temp = has_subsongs_inited() ? std::unique_ptr<subsongs_type>() : std::make_unique<subsongs_type>( get_subsongs() );
+	const subsongs_type & subsongs = has_subsongs_inited() ? m_subsongs : *subsongs_temp;
+	if ( subsong < 0 || subsong >= static_cast<std::int32_t>( subsongs.size() ) ) {
+		throw openmpt::exception( "invalid subsong" );
+	}
+	return subsongs[subsong].restart_row;
+}
+
 void module_impl::set_repeat_count( std::int32_t repeat_count ) {
 	m_sndFile->SetRepeatCount( repeat_count );
 }
Index: libopenmpt/libopenmpt_impl.hpp
===================================================================
--- libopenmpt/libopenmpt_impl.hpp	(revision 21858)
+++ libopenmpt/libopenmpt_impl.hpp	(working copy)
@@ -107,7 +107,9 @@
 		std::int32_t start_row;
 		std::int32_t start_order;
 		std::int32_t sequence;
-		subsong_data( double duration, std::int32_t start_row, std::int32_t start_order, std::int32_t sequence );
+		std::int32_t restart_row;
+		std::int32_t restart_order;
+		subsong_data( double duration, std::int32_t start_row, std::int32_t start_order, std::int32_t sequence, std::int32_t restart_row, std::int32_t restart_order );
 	}; // struct subsong_data
 
 	typedef std::vector<subsong_data> subsongs_type;
@@ -198,6 +200,10 @@
 public:
 	void select_subsong( std::int32_t subsong );
 	std::int32_t get_selected_subsong() const;
+	
+	std::int32_t get_restart_order( std::int32_t subsong ) const;
+	std::int32_t get_restart_row( std::int32_t subsong ) const;
+
 	void set_repeat_count( std::int32_t repeat_count );
 	std::int32_t get_repeat_count() const;
 	double get_duration_seconds() const;
restart-position-v1.patch (10,232 bytes)   
Saga Musix

Saga Musix

2024-10-20 11:26

administrator   ~0006119

restart-position-v2.patch (10,236 bytes)   
Index: libopenmpt/bindings/freebasic/libopenmpt.bi
===================================================================
--- libopenmpt/bindings/freebasic/libopenmpt.bi	(revision 21863)
+++ libopenmpt/bindings/freebasic/libopenmpt.bi	(working copy)
@@ -775,6 +775,25 @@
 '/
 Declare Function openmpt_module_get_selected_subsong(ByVal module As openmpt_module Ptr) As Long
 
+/'* \brief Get the restart order of the specified sub-song
+
+  \param module The module handle to work on.
+  \param subsong Index of the sub-song to retrieve the restart position from.
+  \return The restart order of the specified sub-song. This is the order to which playback returns after the last pattern row of the song has been played. -1 is returned if if sub-song is not in range [0,openmpt_module_get_num_subsongs()[
+  \sa openmpt_module_get_restart_row
+  \since 0.8.0
+'/
+Declare Function openmpt_module_get_restart_order(ByVal module As openmpt_module Ptr, ByVal subsong As Long) As Long
+/'* \brief Get the restart row of the specified sub-song
+
+  \param module The module handle to work on.
+  \param subsong Index of the sub-song to retrieve the restart position from.
+  \return The restart row of the specified sub-song. This is the first played row of the order to which playback returns after the last pattern row of the song has been played. -1 is returned if if sub-song is not in range [0,openmpt_module_get_num_subsongs()[
+  \sa openmpt_module_get_restart_order
+  \since 0.8.0
+'/
+Declare Function openmpt_module_get_restart_row(ByVal module As openmpt_module Ptr, ByVal subsong As Long) As Long
+
 /'* \brief Set Repeat Count
 
   \param module The module handle to work on.
Index: libopenmpt/libopenmpt.h
===================================================================
--- libopenmpt/libopenmpt.h	(revision 21863)
+++ libopenmpt/libopenmpt.h	(working copy)
@@ -875,6 +875,26 @@
  * \since 0.3.0
  */
 LIBOPENMPT_API int32_t openmpt_module_get_selected_subsong( openmpt_module * mod );
+
+/*! \brief Get the restart order of the specified sub-song
+ *
+ * \param mod The module handle to work on.
+ * \param subsong Index of the sub-song to retrieve the restart position from.
+ * \return The restart order of the specified sub-song. This is the order to which playback returns after the last pattern row of the song has been played. -1 is returned if if sub-song is not in range [0,openmpt_module_get_num_subsongs()[
+ * \sa openmpt_module_get_restart_row
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_restart_order( openmpt_module * mod, int32_t subsong );
+/*! \brief Get the restart row of the specified sub-song
+ *
+ * \param mod The module handle to work on.
+ * \param subsong Index of the sub-song to retrieve the restart position from.
+ * \return The restart row of the specified sub-song. This is the first played row of the order to which playback returns after the last pattern row of the song has been played. -1 is returned if if sub-song is not in range [0,openmpt_module_get_num_subsongs()[
+ * \sa openmpt_module_get_restart_order
+ * \since 0.8.0
+ */
+LIBOPENMPT_API int32_t openmpt_module_get_restart_row( openmpt_module * mod, int32_t subsong );
+
 /*! \brief Set Repeat Count
  *
  * \param mod The module handle to work on.
Index: libopenmpt/libopenmpt.hpp
===================================================================
--- libopenmpt/libopenmpt.hpp	(revision 21863)
+++ libopenmpt/libopenmpt.hpp	(working copy)
@@ -592,6 +592,26 @@
 	  \since 0.3.0
 	*/
 	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_selected_subsong() const;
+
+	//! Get the restart order of the specified sub-song
+	/*!
+	  \param subsong Index of the sub-song to retrieve the restart position from.
+	  \return The restart order of the specified sub-song. This is the order to which playback returns after the last pattern row of the song has been played.
+	  \throws openmpt::exception Throws an exception derived from openmpt::exception if sub-song is not in range [0,openmpt::module::get_num_subsongs()[
+	  \sa openmpt::module::get_restart_row
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_restart_order( std::int32_t subsong ) const;
+	//! Get the restart row of the specified sub-song
+	/*!
+	  \param subsong Index of the sub-song to retrieve the restart position from.
+	  \return The restart row of the specified sub-song. This is the first played row of the order to which playback returns after the last pattern row of the song has been played.
+	  \throws openmpt::exception Throws an exception derived from openmpt::exception if sub-song is not in range [0,openmpt::module::get_num_subsongs()[
+	  \sa openmpt::module::get_restart_order
+	  \since 0.8.0
+	*/
+	LIBOPENMPT_CXX_API_MEMBER std::int32_t get_restart_row( std::int32_t subsong ) const;
+
 	//! Set Repeat Count
 	/*!
 	  \param repeat_count Repeat Count
Index: libopenmpt/libopenmpt_c.cpp
===================================================================
--- libopenmpt/libopenmpt_c.cpp	(revision 21863)
+++ libopenmpt/libopenmpt_c.cpp	(working copy)
@@ -741,6 +741,26 @@
 	return -1;
 }
 
+int32_t openmpt_module_get_restart_order( openmpt_module * mod, int32_t subsong ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_restart_order( subsong );
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return -1;
+}
+
+int32_t openmpt_module_get_restart_row( openmpt_module * mod, int32_t subsong ) {
+	try {
+		openmpt::interface::check_soundfile( mod );
+		return mod->impl->get_restart_row( subsong );
+	} catch ( ... ) {
+		openmpt::report_exception( __func__, mod );
+	}
+	return -1;
+}
+
 int openmpt_module_set_repeat_count( openmpt_module * mod, int32_t repeat_count ) {
 	try {
 		openmpt::interface::check_soundfile( mod );
Index: libopenmpt/libopenmpt_cxx.cpp
===================================================================
--- libopenmpt/libopenmpt_cxx.cpp	(revision 21863)
+++ libopenmpt/libopenmpt_cxx.cpp	(working copy)
@@ -240,6 +240,13 @@
 	return impl->get_selected_subsong();
 }
 
+std::int32_t module::get_restart_order( std::int32_t subsong ) const {
+	return impl->get_restart_order( subsong );
+}
+std::int32_t module::get_restart_row( std::int32_t subsong ) const {
+	return impl->get_restart_row( subsong );
+}
+
 void module::set_repeat_count( std::int32_t repeat_count ) {
 	impl->set_repeat_count( repeat_count );
 }
Index: libopenmpt/libopenmpt_impl.cpp
===================================================================
--- libopenmpt/libopenmpt_impl.cpp	(revision 21863)
+++ libopenmpt/libopenmpt_impl.cpp	(working copy)
@@ -306,11 +306,13 @@
 	m_sndFile->AddToLog( static_cast<OpenMPT::LogLevel>( loglevel ), mpt::transcode<mpt::ustring>( mpt::common_encoding::utf8, text ) );
 }
 
-module_impl::subsong_data::subsong_data( double duration, std::int32_t start_row, std::int32_t start_order, std::int32_t sequence )
+module_impl::subsong_data::subsong_data( double duration, std::int32_t start_row, std::int32_t start_order, std::int32_t sequence, std::int32_t restart_row, std::int32_t restart_order )
 	: duration(duration)
 	, start_row(start_row)
 	, start_order(start_order)
 	, sequence(sequence)
+	, restart_row(restart_row)
+	, restart_order(restart_order)
 {
 	return;
 }
@@ -436,7 +438,7 @@
 	for ( OpenMPT::SEQUENCEINDEX seq = 0; seq < m_sndFile->Order.GetNumSequences(); ++seq ) {
 		const std::vector<OpenMPT::GetLengthType> lengths = m_sndFile->GetLength( OpenMPT::eNoAdjust, OpenMPT::GetLengthTarget( true ).StartPos( seq, 0, 0 ) );
 		for ( const auto & l : lengths ) {
-			subsongs.push_back( subsong_data( l.duration, l.startRow, l.startOrder, seq ) );
+			subsongs.push_back( subsong_data( l.duration, l.startRow, l.startOrder, seq, l.restartRow, l.restartOrder ) );
 		}
 	}
 	return subsongs;
@@ -1093,6 +1095,24 @@
 std::int32_t module_impl::get_selected_subsong() const {
 	return m_current_subsong;
 }
+
+std::int32_t module_impl::get_restart_order( std::int32_t subsong ) const {
+	std::unique_ptr<subsongs_type> subsongs_temp = has_subsongs_inited() ? std::unique_ptr<subsongs_type>() : std::make_unique<subsongs_type>( get_subsongs() );
+	const subsongs_type & subsongs = has_subsongs_inited() ? m_subsongs : *subsongs_temp;
+	if ( subsong < 0 || subsong >= static_cast<std::int32_t>( subsongs.size() ) ) {
+		throw openmpt::exception( "invalid subsong" );
+	}
+	return subsongs[subsong].restart_order;
+}
+std::int32_t module_impl::get_restart_row( std::int32_t subsong ) const {
+	std::unique_ptr<subsongs_type> subsongs_temp = has_subsongs_inited() ? std::unique_ptr<subsongs_type>() : std::make_unique<subsongs_type>( get_subsongs() );
+	const subsongs_type & subsongs = has_subsongs_inited() ? m_subsongs : *subsongs_temp;
+	if ( subsong < 0 || subsong >= static_cast<std::int32_t>( subsongs.size() ) ) {
+		throw openmpt::exception( "invalid subsong" );
+	}
+	return subsongs[subsong].restart_row;
+}
+
 void module_impl::set_repeat_count( std::int32_t repeat_count ) {
 	m_sndFile->SetRepeatCount( repeat_count );
 }
Index: libopenmpt/libopenmpt_impl.hpp
===================================================================
--- libopenmpt/libopenmpt_impl.hpp	(revision 21863)
+++ libopenmpt/libopenmpt_impl.hpp	(working copy)
@@ -107,7 +107,9 @@
 		std::int32_t start_row;
 		std::int32_t start_order;
 		std::int32_t sequence;
-		subsong_data( double duration, std::int32_t start_row, std::int32_t start_order, std::int32_t sequence );
+		std::int32_t restart_row;
+		std::int32_t restart_order;
+		subsong_data( double duration, std::int32_t start_row, std::int32_t start_order, std::int32_t sequence, std::int32_t restart_row, std::int32_t restart_order );
 	}; // struct subsong_data
 
 	typedef std::vector<subsong_data> subsongs_type;
@@ -198,6 +200,10 @@
 public:
 	void select_subsong( std::int32_t subsong );
 	std::int32_t get_selected_subsong() const;
+	
+	std::int32_t get_restart_order( std::int32_t subsong ) const;
+	std::int32_t get_restart_row( std::int32_t subsong ) const;
+
 	void set_repeat_count( std::int32_t repeat_count );
 	std::int32_t get_repeat_count() const;
 	double get_duration_seconds() const;
restart-position-v2.patch (10,236 bytes)   
manx

manx

2024-10-20 11:46

administrator   ~0006123

restart-position-v2 is fine I guess

get-time-at-position documentation can probably be improved. We need to state that the time returned is the first occurrence of the given position in a playthrough. "At the given row" is also not precise enough, we should document "the start of the given row" or something like that.

Saga Musix

Saga Musix

2024-10-20 11:50

administrator   ~0006126

restart-position-v2 was commited in r21867. I'll rework the documentation on the other patch right now.

manx

manx

2024-10-20 11:52

administrator   ~0006127

restart-position-v2: 0.8.0-pre.10

Saga Musix

Saga Musix

2024-10-20 11:55

administrator   ~0006130

Last edited: 2024-10-20 11:55

How about \remarks If an order / row combination is played multiple times (e.g. due the pattern loops), the first occurence of this position is returned. The returned time is the approximate time at the start of the row.

manx

manx

2024-10-20 11:56

administrator   ~0006131

The returned time is the approximate time at the start of the row.

That should not be in "remarks" but instead in the proper "return" documentation. The other sentence is fine in "remarks".

Saga Musix

Saga Musix

2024-10-20 11:57

administrator   ~0006132

 * \return Approximate playback time in seconds of current sub-song at the start of the given order and row combination. Negative if the position does not exist, or the pattern data is too complex to evaluate.
 * \remarks If an order / row combination is played multiple times (e.g. due the pattern loops), the first occurence of this position is returned.
manx

manx

2024-10-20 11:58

administrator   ~0006133

sounds good

Saga Musix

Saga Musix

2024-10-20 12:01

administrator   ~0006134

get_time_at_position implemented in r21869.

manx

manx

2024-10-20 12:02

administrator   ~0006135

get_time_at_position: 0.8.0-pre.11

Issue History

Date Modified Username Field Change
2023-03-07 19:59 Saga Musix New Issue
2024-10-19 16:09 Saga Musix Note Added: 0006102
2024-10-19 16:09 Saga Musix File Added: get-time-at-position-v2.patch
2024-10-19 16:09 Saga Musix File Added: restart-position-v1.patch
2024-10-19 16:09 Saga Musix File Deleted: get-time-at-position-v1.patch
2024-10-19 16:16 Saga Musix Assigned To => Saga Musix
2024-10-19 16:16 Saga Musix Status new => assigned
2024-10-19 16:17 Saga Musix Target Version => OpenMPT 1.32 / libopenmpt 0.8 (goals)
2024-10-19 19:27 Saga Musix Status assigned => feedback
2024-10-20 11:26 Saga Musix Note Added: 0006119
2024-10-20 11:26 Saga Musix File Added: restart-position-v2.patch
2024-10-20 11:46 manx Note Added: 0006123
2024-10-20 11:50 Saga Musix Note Added: 0006126
2024-10-20 11:52 manx Note Added: 0006127
2024-10-20 11:55 Saga Musix Note Added: 0006130
2024-10-20 11:55 Saga Musix Note Edited: 0006130
2024-10-20 11:56 manx Note Added: 0006131
2024-10-20 11:57 Saga Musix Note Added: 0006132
2024-10-20 11:58 manx Note Added: 0006133
2024-10-20 12:01 Saga Musix Note Added: 0006134
2024-10-20 12:01 Saga Musix Status feedback => resolved
2024-10-20 12:01 Saga Musix Resolution open => fixed
2024-10-20 12:01 Saga Musix Fixed in Version => OpenMPT 1.32 / libopenmpt 0.8 (goals)
2024-10-20 12:02 manx Note Added: 0006135