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( order ), static_cast( 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_temp = has_subsongs_inited() ? std::unique_ptr() : std::make_unique( 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 );