View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update | 
|---|---|---|---|---|---|
| 0001675 | OpenMPT | libopenmpt | public | 2023-03-07 19:59 | 2024-10-20 12:03 | 
| Reporter | Saga Musix | Assigned To | Saga Musix | ||
| Priority | normal | Severity | feature | Reproducibility | N/A | 
| Status | resolved | Resolution | fixed | ||
| Target Version | OpenMPT 1.32.01.00 / libopenmpt 0.8.0 (upgrade first) | Fixed in Version | OpenMPT 1.32.01.00 / libopenmpt 0.8.0 (upgrade first) | ||
| Summary | 0001675: libopenmpt API additions: retrieval of loop start position, playback time at given position | ||||
| Description | Two useful API additions would be: 
 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)  | ||||
| Tags | No tags attached. | ||||
| Has the bug occurred in previous versions? | |||||
| Tested code revision (in case you know it) | |||||
| 
	  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 );
 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-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 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.  | 
|
| 
	 restart-position-v2 was commited in r21867. I'll rework the documentation on the other patch right now.  | 
|
| 
	 restart-position-v2: 0.8.0-pre.10  | 
|
| 
	 How about   | 
|
	
 That should not be in "remarks" but instead in the proper "return" documentation. The other sentence is fine in "remarks".  | 
|
		 | 
|
| 
	 sounds good  | 
|
| 
	 
  | 
|
| 
	 get_time_at_position: 0.8.0-pre.11  | 
|
| 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.01.00 / libopenmpt 0.8.0 (upgrade first) | 
| 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.01.00 / libopenmpt 0.8.0 (upgrade first) | 
| 2024-10-20 12:02 | manx | Note Added: 0006135 |