Index: libopenmpt/bindings/freebasic/libopenmpt.bi =================================================================== --- libopenmpt/bindings/freebasic/libopenmpt.bi (revision 16918) +++ libopenmpt/bindings/freebasic/libopenmpt.bi (working copy) @@ -1076,9 +1076,18 @@ \param module The module handle to work on. \return The current tempo in tracker units. The exact meaning of this value depends on the tempo mode being used. + \deprecated Please use openmpt_module_get_current_tempo2(). '/ Declare Function openmpt_module_get_current_tempo(ByVal module As openmpt_module Ptr) As Long +/'* \brief Get the current tempo + + \param module The module handle to work on. + \return The current tempo in tracker units. The exact meaning of this value depends on the tempo mode being used. + \since 0.7.0 +'/ +Declare Function openmpt_module_get_current_tempo2(ByVal module As openmpt_module Ptr) As Long + /'* \brief Get the current order \param module The module handle to work on. Index: libopenmpt/bindings/freebasic/libopenmpt_ext.bi =================================================================== --- libopenmpt/bindings/freebasic/libopenmpt_ext.bi (revision 16918) +++ libopenmpt/bindings/freebasic/libopenmpt_ext.bi (working copy) @@ -134,6 +134,7 @@ \return 1 on success, 0 on failure. \remarks The tempo may be reset by pattern commands at any time. Use set_tempo_factor to apply a tempo factor that is independent of pattern commands. \sa openmpt_module_get_current_tempo + \deprecated Please use openmpt_module_ext_interface_interactive3.set_current_tempo2(). '/ set_current_tempo As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal tempo As Long) As Long @@ -348,6 +349,23 @@ get_note_finetune As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal channel As Long) As Double End Type +#define LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE3 "interactive3" + +Type openmpt_module_ext_interface_interactive3 + + /'* Set the current module tempo + + \param mod_ext The module handle to work on. + \param tempo The new tempo in range [32, 512]. The exact meaning of the value depends on the tempo mode used by the module. + \return 1 on success, 0 on failure. + \remarks The tempo may be reset by pattern commands at any time. Use set_tempo_factor to apply a tempo factor that is independent of pattern commands. + \sa openmpt_module_get_current_tempo2 + \since 0.7.0 + '/ + set_current_tempo As Function(ByVal mod_ext As openmpt_module_ext Ptr, ByVal tempo As Double) As Long + +End Type + End Extern /'* \brief Construct an openmpt_module_ext Index: libopenmpt/dox/changelog.md =================================================================== --- libopenmpt/dox/changelog.md (revision 16918) +++ libopenmpt/dox/changelog.md (working copy) @@ -8,6 +8,9 @@ ### libopenmpt 0.7.0-pre * [**New**] `GTK` and `GT2` files from Gramouf Tracker are now supported. + * [**New**] libopenmpt: New APIs for getting the current tempo as a floating + point value: `openmpt::module::get_current_tempo2()` (C++), and + `openmpt_module_get_current_tempo2()` (C). * [**New**] C API: New stream callbacks for various platform extensions to the C stdio interface: `openmpt_stream_get_file_posix_lfs64_callbacks()` in `libopenmpt/libopenmpt_stream_callbacks_file_posix_lfs64.h` for explicit @@ -38,6 +41,10 @@ `openmpt_probe_file_header()`, `openmpt_probe_file_header_without_filesize()`, and `openmpt_probe_file_header_from_stream()` in libopenmpt 0.3.0. + * [**New**] libopenmpt_ext: New interface `interactive3` adding + `openmpt::ext::interactive3::set_current_tempo2()` (C++) and + `openmpt_module_ext_interface_interactive3.set_current_tempo2()` (C) which + allow setting non-integer tempo values. * [**New**] `Makefile` `CONFIG=djgpp` now supports `CPU=` option to build optimized for a particular CPU. See `build/make/config-djgpp.mk` for all available options. `FLAVOURED_DIR=1` places the CPU-specific optimized Index: libopenmpt/libopenmpt.h =================================================================== --- libopenmpt/libopenmpt.h (revision 16918) +++ libopenmpt/libopenmpt.h (working copy) @@ -1159,8 +1159,16 @@ * * \param mod The module handle to work on. * \return The current tempo in tracker units. The exact meaning of this value depends on the tempo mode being used. + * \deprecated Please use openmpt_module_get_current_tempo2(). */ -LIBOPENMPT_API int32_t openmpt_module_get_current_tempo( openmpt_module * mod ); +LIBOPENMPT_API LIBOPENMPT_DEPRECATED int32_t openmpt_module_get_current_tempo( openmpt_module * mod ); +/*! \brief Get the current tempo + * + * \param mod The module handle to work on. + * \return The current tempo in tracker units. The exact meaning of this value depends on the tempo mode being used. + * \since 0.7.0 + */ +LIBOPENMPT_API double openmpt_module_get_current_tempo2( openmpt_module * mod ); /*! \brief Get the current order * * \param mod The module handle to work on. Index: libopenmpt/libopenmpt.hpp =================================================================== --- libopenmpt/libopenmpt.hpp (revision 16918) +++ libopenmpt/libopenmpt.hpp (working copy) @@ -843,8 +843,15 @@ //! Get the current tempo /*! \return The current tempo in tracker units. The exact meaning of this value depends on the tempo mode being used. + \deprecated Please use openmpt::module::get_current_tempo2(). */ - std::int32_t get_current_tempo() const; + LIBOPENMPT_ATTR_DEPRECATED std::int32_t get_current_tempo() const; + //! Get the current tempo + /*! + \return The current tempo in tracker units. The exact meaning of this value depends on the tempo mode being used. + \since 0.7.0 + */ + double get_current_tempo2() const; //! Get the current order /*! \return The current order at which the module is being played back. Index: libopenmpt/libopenmpt_c.cpp =================================================================== --- libopenmpt/libopenmpt_c.cpp (revision 16918) +++ libopenmpt/libopenmpt_c.cpp (working copy) @@ -967,6 +967,15 @@ } return 0; } +double openmpt_module_get_current_tempo2( openmpt_module * mod ) { + try { + openmpt::interface::check_soundfile( mod ); + return mod->impl->get_current_tempo2(); + } catch ( ... ) { + openmpt::report_exception( __func__, mod ); + } + return 0; +} int32_t openmpt_module_get_current_order( openmpt_module * mod ) { try { openmpt::interface::check_soundfile( mod ); @@ -1786,6 +1795,19 @@ +static int set_current_tempo2( openmpt_module_ext * mod_ext, double tempo ) { + try { + openmpt::interface::check_soundfile( mod_ext ); + mod_ext->impl->set_current_tempo2( tempo ); + return 1; + } catch ( ... ) { + openmpt::report_exception( __func__, mod_ext ? &mod_ext->mod : NULL ); + } + return 0; +} + + + /* add stuff here */ @@ -1844,6 +1866,13 @@ + } else if ( !std::strcmp( interface_id, LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE3 ) && ( interface_size == sizeof( openmpt_module_ext_interface_interactive3 ) ) ) { + openmpt_module_ext_interface_interactive3 * i = static_cast< openmpt_module_ext_interface_interactive3 * >( interface ); + i->set_current_tempo2 = &set_current_tempo2; + result = 1; + + + /* add stuff here */ Index: libopenmpt/libopenmpt_cxx.cpp =================================================================== --- libopenmpt/libopenmpt_cxx.cpp (revision 16918) +++ libopenmpt/libopenmpt_cxx.cpp (working copy) @@ -312,6 +312,9 @@ std::int32_t module::get_current_tempo() const { return impl->get_current_tempo(); } +double module::get_current_tempo2() const { + return impl->get_current_tempo2(); +} std::int32_t module::get_current_order() const { return impl->get_current_order(); } Index: libopenmpt/libopenmpt_ext.h =================================================================== --- libopenmpt/libopenmpt_ext.h (revision 16918) +++ libopenmpt/libopenmpt_ext.h (working copy) @@ -162,6 +162,7 @@ * \return 1 on success, 0 on failure. * \remarks The tempo may be reset by pattern commands at any time. Use openmpt_module_ext_interface_interactive::set_tempo_factor to apply a tempo factor that is independent of pattern commands. * \sa openmpt_module_get_current_tempo + * \deprecated Please use openmpt_module_ext_interface_interactive3::set_current_tempo2(). */ int ( * set_current_tempo ) ( openmpt_module_ext * mod_ext, int32_t tempo ); @@ -389,6 +390,26 @@ +#ifndef LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE3 +#define LIBOPENMPT_EXT_C_INTERFACE_INTERACTIVE3 "interactive3" +#endif + +typedef struct openmpt_module_ext_interface_interactive3 { + + /*! Set the current module tempo + * + * \param mod_ext The module handle to work on. + * \param tempo The new tempo in range [32, 512]. The exact meaning of the value depends on the tempo mode used by the module. + * \return 1 on success, 0 on failure. + * \remarks The tempo may be reset by pattern commands at any time. Use openmpt_module_ext_interface_interactive::set_tempo_factor to apply a tempo factor that is independent of pattern commands. + * \sa openmpt_module_get_current_tempo2 + */ + int ( * set_current_tempo2 ) ( openmpt_module_ext * mod_ext, double tempo ); + +} openmpt_module_ext_interface_interactive3; + + + /* add stuff here */ Index: libopenmpt/libopenmpt_ext.hpp =================================================================== --- libopenmpt/libopenmpt_ext.hpp (revision 16918) +++ libopenmpt/libopenmpt_ext.hpp (working copy) @@ -170,8 +170,9 @@ \throws openmpt::exception Throws an exception derived from openmpt::exception if the tempo is outside the specified range. \remarks The tempo may be reset by pattern commands at any time. Use openmpt::ext:interactive::set_tempo_factor to apply a tempo factor that is independent of pattern commands. \sa openmpt::module::get_current_tempo + \deprecated Please use openmpt::ext::interactive3::set_current_tempo2(). */ - virtual void set_current_tempo( std::int32_t tempo ) = 0; + LIBOPENMPT_ATTR_DEPRECATED virtual void set_current_tempo( std::int32_t tempo ) = 0; //! Set the current module tempo factor without affecting playback pitch /*! @@ -383,9 +384,33 @@ */ virtual double get_note_finetune( int32_t channel ) = 0; -}; // class interactive +}; // class interactive2 +#ifndef LIBOPENMPT_EXT_INTERFACE_INTERACTIVE3 +#define LIBOPENMPT_EXT_INTERFACE_INTERACTIVE3 +#endif + +LIBOPENMPT_DECLARE_EXT_CXX_INTERFACE(interactive3) + +class interactive3 { + + LIBOPENMPT_EXT_CXX_INTERFACE(interactive3) + + //! Set the current module tempo + /*! + \param tempo The new tempo in range [32, 512]. The exact meaning of the value depends on the tempo mode used by the module. + \throws openmpt::exception Throws an exception derived from openmpt::exception if the tempo is outside the specified range. + \remarks The tempo may be reset by pattern commands at any time. Use openmpt::ext:interactive::set_tempo_factor to apply a tempo factor that is independent of pattern commands. + \sa openmpt::module::get_current_tempo2 + \since 0.7.0 + */ + virtual void set_current_tempo2( double tempo ) = 0; + +}; // class interactive3 + + + /* add stuff here */ Index: libopenmpt/libopenmpt_ext_impl.cpp =================================================================== --- libopenmpt/libopenmpt_ext_impl.cpp (revision 16918) +++ libopenmpt/libopenmpt_ext_impl.cpp (working copy) @@ -85,6 +85,8 @@ return dynamic_cast< ext::interactive * >( this ); } else if ( interface_id == ext::interactive2_id ) { return dynamic_cast< ext::interactive2 * >( this ); + } else if ( interface_id == ext::interactive3_id ) { + return dynamic_cast< ext::interactive3 * >( this ); @@ -344,6 +346,13 @@ return chn.microTuning / 32768.0; } + void module_ext_impl::set_current_tempo2( double tempo ) { + if ( tempo < 32.0 || tempo > 512.0 ) { + throw openmpt::exception("invalid tempo"); + } + m_sndFile->m_PlayState.m_nMusicTempo = decltype( m_sndFile->m_PlayState.m_nMusicTempo )( tempo ); + } + /* add stuff here */ Index: libopenmpt/libopenmpt_ext_impl.hpp =================================================================== --- libopenmpt/libopenmpt_ext_impl.hpp (revision 16918) +++ libopenmpt/libopenmpt_ext_impl.hpp (working copy) @@ -21,6 +21,7 @@ , public ext::pattern_vis , public ext::interactive , public ext::interactive2 + , public ext::interactive3 @@ -112,6 +113,8 @@ double get_note_finetune( std::int32_t channel ) override; + void set_current_tempo2(double tempo) override; + /* add stuff here */ }; // class module_ext_impl Index: libopenmpt/libopenmpt_impl.cpp =================================================================== --- libopenmpt/libopenmpt_impl.cpp (revision 16918) +++ libopenmpt/libopenmpt_impl.cpp (working copy) @@ -1316,6 +1316,9 @@ std::int32_t module_impl::get_current_tempo() const { return static_cast( m_sndFile->m_PlayState.m_nMusicTempo.GetInt() ); } +double module_impl::get_current_tempo2() const { + return m_sndFile->m_PlayState.m_nMusicTempo.ToDouble(); +} std::int32_t module_impl::get_current_order() const { return m_sndFile->GetCurrentOrder(); } Index: libopenmpt/libopenmpt_impl.hpp =================================================================== --- libopenmpt/libopenmpt_impl.hpp (revision 16918) +++ libopenmpt/libopenmpt_impl.hpp (working copy) @@ -212,6 +212,7 @@ double get_current_estimated_bpm() const; std::int32_t get_current_speed() const; std::int32_t get_current_tempo() const; + double get_current_tempo2() const; std::int32_t get_current_order() const; std::int32_t get_current_pattern() const; std::int32_t get_current_row() const; Index: openmpt123/openmpt123.cpp =================================================================== --- openmpt123/openmpt123.cpp (revision 16918) +++ openmpt123/openmpt123.cpp (working copy) @@ -1286,7 +1286,7 @@ log << " "; log << "Spd:" << std::setw(2) << std::setfill(':') << mod.get_current_speed(); log << " "; - log << "Tmp:" << std::setw(3) << std::setfill(':') << mod.get_current_tempo(); + log << "Tmp:" << std::setw(6) << std::setfill(':') << std::fixed << std::setprecision(2) << mod.get_current_tempo2(); log << " "; log << std::endl; } @@ -1347,7 +1347,7 @@ log << " "; log << "Spd:" << std::setw(2) << std::setfill(':') << mod.get_current_speed(); log << "|"; - log << "Tmp:" << std::setw(3) << std::setfill(':') << mod.get_current_tempo(); + log << "Tmp:" << std::setw(3) << std::setfill(':') << std::fixed << std::setprecision(2) << mod.get_current_tempo2(); } } if ( flags.show_progress ) {