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 );
