Codebase list libopenmpt / 0534120
Imported Upstream version 0.2.7561~beta20.5 James Cowgill 7 years ago
25 changed file(s) with 732 addition(s) and 231 deletion(s). Raw diff Collapse all Expand all
00 The OpenMPT code is licensed under the BSD license.
11
2 Copyright (c) 2004-2016, OpenMPT contributors
2 Copyright (c) 2004-2017, OpenMPT contributors
33 Copyright (c) 1997-2003, Olivier Lapicque
44 All rights reserved.
55
53685368 maintainer-clean-generic:
53695369 @echo "This command is intended for maintainers to use"
53705370 @echo "it deletes files that may require special tools to rebuild."
5371 @DX_COND_doc_FALSE@clean-local:
5372 @DX_COND_doc_FALSE@install-data-local:
53715373 @DX_COND_doc_FALSE@uninstall-local:
5372 @DX_COND_doc_FALSE@install-data-local:
5373 @DX_COND_doc_FALSE@clean-local:
53745374 clean: clean-am
53755375
53765376 clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
755755
756756 forceinline int32 muldiv(int32 a, int32 b, int32 c)
757757 {
758 return static_cast<int32>( mul32to64( a, b ) / c );
758 return mpt::saturate_cast<int32>( mul32to64( a, b ) / c );
759759 }
760760
761761 forceinline int32 muldivr(int32 a, int32 b, int32 c)
762762 {
763 return static_cast<int32>( ( mul32to64( a, b ) + ( c / 2 ) ) / c );
763 return mpt::saturate_cast<int32>( ( mul32to64( a, b ) + ( c / 2 ) ) / c );
764764 }
765765
766766 // Do not use overloading because catching unsigned version by accident results in slower X86 code.
767767 forceinline uint32 muldiv_unsigned(uint32 a, uint32 b, uint32 c)
768768 {
769 return static_cast<uint32>( mul32to64_unsigned( a, b ) / c );
769 return mpt::saturate_cast<uint32>( mul32to64_unsigned( a, b ) / c );
770770 }
771771 forceinline uint32 muldivr_unsigned(uint32 a, uint32 b, uint32 c)
772772 {
773 return static_cast<uint32>( ( mul32to64_unsigned( a, b ) + ( c / 2 ) ) / c );
773 return mpt::saturate_cast<uint32>( ( mul32to64_unsigned( a, b ) + ( c / 2u ) ) / c );
774774 }
775775
776776 forceinline int32 muldivrfloor(int64 a, uint32 b, uint32 c)
777777 {
778778 a *= b;
779 a += c / 2;
779 a += c / 2u;
780780 return (a >= 0) ? mpt::saturate_cast<int32>(a / c) : mpt::saturate_cast<int32>((a - (c - 1)) / c);
781781 }
782782
582582 "libopenmpt (based on OpenMPT / ModPlug Tracker)\n"
583583 #endif
584584 "\n"
585 "Copyright \xC2\xA9 2004-2016 Contributors\n"
585 "Copyright \xC2\xA9 2004-2017 Contributors\n"
586586 "Copyright \xC2\xA9 1997-2003 Olivier Lapicque\n"
587587 "\n"
588588 "Contributors:\n"
589 "Johannes Schultz (2008-2016)\n"
590 "J\xC3\xB6rn Heusipp (2012-2016)\n"
589 "Johannes Schultz (2008-2017)\n"
590 "J\xC3\xB6rn Heusipp (2012-2017)\n"
591591 "Ahti Lepp\xC3\xA4nen (2005-2011)\n"
592592 "Robin Fernandes (2004-2007)\n"
593593 "Sergiy Pylypenko (2007)\n"
752752 return MPT_UTF8(
753753 "The OpenMPT code is licensed under the BSD license." "\n"
754754 "" "\n"
755 "Copyright (c) 2004-2016, OpenMPT contributors" "\n"
755 "Copyright (c) 2004-2017, OpenMPT contributors" "\n"
756756 "Copyright (c) 1997-2003, Olivier Lapicque" "\n"
757757 "All rights reserved." "\n"
758758 "" "\n"
1717 //Version definitions. The only thing that needs to be changed when changing version number.
1818 #define VER_MAJORMAJOR 1
1919 #define VER_MAJOR 26
20 #define VER_MINOR 07
20 #define VER_MINOR 08
2121 #define VER_MINORMINOR 00
2222
2323 //Version string. For example "1.17.02.28"
00 #! /bin/sh
11 # Guess values for system-dependent variables and create Makefiles.
2 # Generated by GNU Autoconf 2.69 for libopenmpt 0.2.7386-autotools.
2 # Generated by GNU Autoconf 2.69 for libopenmpt 0.2.7561-autotools.
33 #
44 # Report bugs to <https://bugs.openmpt.org/>.
55 #
589589 # Identity of this package.
590590 PACKAGE_NAME='libopenmpt'
591591 PACKAGE_TARNAME='libopenmpt'
592 PACKAGE_VERSION='0.2.7386-autotools'
593 PACKAGE_STRING='libopenmpt 0.2.7386-autotools'
592 PACKAGE_VERSION='0.2.7561-autotools'
593 PACKAGE_STRING='libopenmpt 0.2.7561-autotools'
594594 PACKAGE_BUGREPORT='https://bugs.openmpt.org/'
595595 PACKAGE_URL='https://lib.openmpt.org/'
596596
14621462 # Omit some internal or obsolete options to make the list less imposing.
14631463 # This message is too long to be a string in the A/UX 3.1 sh.
14641464 cat <<_ACEOF
1465 \`configure' configures libopenmpt 0.2.7386-autotools to adapt to many kinds of systems.
1465 \`configure' configures libopenmpt 0.2.7561-autotools to adapt to many kinds of systems.
14661466
14671467 Usage: $0 [OPTION]... [VAR=VALUE]...
14681468
15321532
15331533 if test -n "$ac_init_help"; then
15341534 case $ac_init_help in
1535 short | recursive ) echo "Configuration of libopenmpt 0.2.7386-autotools:";;
1535 short | recursive ) echo "Configuration of libopenmpt 0.2.7561-autotools:";;
15361536 esac
15371537 cat <<\_ACEOF
15381538
17221722 test -n "$ac_init_help" && exit $ac_status
17231723 if $ac_init_version; then
17241724 cat <<\_ACEOF
1725 libopenmpt configure 0.2.7386-autotools
1725 libopenmpt configure 0.2.7561-autotools
17261726 generated by GNU Autoconf 2.69
17271727
17281728 Copyright (C) 2012 Free Software Foundation, Inc.
22122212 This file contains any messages produced by compilers while
22132213 running configure, to aid debugging if configure makes a mistake.
22142214
2215 It was created by libopenmpt $as_me 0.2.7386-autotools, which was
2215 It was created by libopenmpt $as_me 0.2.7561-autotools, which was
22162216 generated by GNU Autoconf 2.69. Invocation command line was
22172217
22182218 $ $0 $@
30833083
30843084 # Define the identity of the package.
30853085 PACKAGE='libopenmpt'
3086 VERSION='0.2.7386-autotools'
3086 VERSION='0.2.7561-autotools'
30873087
30883088
30893089 cat >>confdefs.h <<_ACEOF
1662516625 $as_echo "#define MPT_SVNURL \"https://source.openmpt.org/svn/openmpt/branches/1.26-maintenance\"" >>confdefs.h
1662616626
1662716627
16628 $as_echo "#define MPT_SVNVERSION \"7386\"" >>confdefs.h
16629
16630
16631 $as_echo "#define MPT_SVNDATE \"2016-11-20T16:45:27.412655Z\"" >>confdefs.h
16628 $as_echo "#define MPT_SVNVERSION \"7561\"" >>confdefs.h
16629
16630
16631 $as_echo "#define MPT_SVNDATE \"2017-02-05T16:23:49.365208Z\"" >>confdefs.h
1663216632
1663316633
1663416634 $as_echo "#define MPT_PACKAGE true" >>confdefs.h
2115121151 # report actual input values of CONFIG_FILES etc. instead of their
2115221152 # values after options handling.
2115321153 ac_log="
21154 This file was extended by libopenmpt $as_me 0.2.7386-autotools, which was
21154 This file was extended by libopenmpt $as_me 0.2.7561-autotools, which was
2115521155 generated by GNU Autoconf 2.69. Invocation command line was
2115621156
2115721157 CONFIG_FILES = $CONFIG_FILES
2121821218 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
2121921219 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
2122021220 ac_cs_version="\\
21221 libopenmpt config.status 0.2.7386-autotools
21221 libopenmpt config.status 0.2.7561-autotools
2122221222 configured by $0, generated by GNU Autoconf 2.69,
2122321223 with options \\"\$ac_cs_config\\"
2122421224
0 AC_INIT([libopenmpt], [0.2.7386-autotools], [https://bugs.openmpt.org/], [libopenmpt], [https://lib.openmpt.org/])
0 AC_INIT([libopenmpt], [0.2.7561-autotools], [https://bugs.openmpt.org/], [libopenmpt], [https://lib.openmpt.org/])
11 AC_PREREQ([2.68])
22
33 AC_CONFIG_MACRO_DIR([m4])
2020 AC_PROG_INSTALL
2121
2222 AC_DEFINE([MPT_SVNURL], ["https://source.openmpt.org/svn/openmpt/branches/1.26-maintenance"], [svn version])
23 AC_DEFINE([MPT_SVNVERSION], ["7386"], [svn version])
24 AC_DEFINE([MPT_SVNDATE], ["2016-11-20T16:45:27.412655Z"], [svn date])
23 AC_DEFINE([MPT_SVNVERSION], ["7561"], [svn version])
24 AC_DEFINE([MPT_SVNDATE], ["2017-02-05T16:23:49.365208Z"], [svn date])
2525 AC_DEFINE([MPT_PACKAGE], [true], [is package])
2626
2727 LIBOPENMPT_REQUIRES_PRIVATE=
33
44 For fully detailed change log, please see the source repository directly. This
55 is just a high-level summary.
6
7 ### libopenmpt 0.2-beta20.5 (2017-02-05)
8
9 * [**Bug**] libmodplug: C++ API did not build with MSVC2008 in 0.2-beta20.4.
10
11 ### libopenmpt 0.2-beta20.4 (2017-02-05, not released)
12
13 * [**Bug**] Possible hangs with malformed files containing cyclic plugin
14 routings.
15
16 * libmodplug: Added all missing C++ API symbols that are accessable via the
17 public libmodplug header file.
18 * Channel frequency could wrap around after some excessive portamento / down
19 in some formats since libopenmpt 0.2-beta17.
20 * Playback improvements for S3M files made with Impulse Tracker and
21 Schism Tracker.
622
723 ### libopenmpt 0.2-beta20.3 (2016-11-20)
824
1818 the C API as long as a **C99** compatible **stdint.h** is available.
1919 * Any **C++98** / **C++03** / **C++11** / **C++14** / **C++1z** compatible
2020 compiler should work with the C++ API. **C++98** and **C++03** compilers
21 require a **C99** compatible **stdint.h** to be avilable.
21 require a **C99** compatible **stdint.h** to be available.
2222 * **J2B** support requires an inflate (deflate decompression) implementation:
2323 * **zlib**
2424 * **miniz** can be used internally if no zlib is available.
121121 * threads when using only const member functions from all threads.
122122 * - Consecutive accesses can happen from different threads.
123123 * - Different objects can be accessed concurrently from different threads.
124 *
125 * \section libopenmpt-cpp-windows Windows support
126 *
127 * Using the libopenmpt C++ API when libopenmpt is compiled as a DLL on Windows
128 * requires `#define LIBOPENMPT_USE_DLL` (or some equivalent build system
129 * configuration) before `#include <libopenmpt/libopenmpt.hpp>` in order to
130 * correctly import the symbols from the DLL.
124131 *
125132 * \section libopenmpt-cpp-detailed Detailed documentation
126133 *
11 * libopenmpt_modplug_cpp.cpp
22 * --------------------------
33 * Purpose: libopenmpt emulation of the libmodplug c++ interface
4 * Notes : WARNING! THIS IS INCOMPLETE!
4 * Notes : WARNING! THIS IS A HACK!
55 * Authors: OpenMPT Devs
66 * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
77 */
1616
1717 This is a dirty hack to emulate just so much of the libmodplug c++
1818 interface so that the current known users (mainly xmms-modplug itself,
19 gstreamer modplug, and stuff based on those 2) work. This is neither
20 a complete nor a correct implementation.
21 Symbols unused by these implementations are not included.
19 gstreamer modplug, audacious, and stuff based on those) work. This is
20 neither a complete nor a correct implementation.
2221 Metadata and other state is not provided or updated.
2322
2423 */
5453 #define LIBOPENMPT_MODPLUG_API LIBOPENMPT_API_HELPER_EXPORT
5554 #endif /* _MSC_VER */
5655
56 namespace {
57
5758 template <class T>
5859 void Clear( T & x )
5960 {
6061 std::memset( &x, 0, sizeof(T) );
62 }
63
6164 }
6265
6366 class LIBOPENMPT_MODPLUG_API CSoundFile;
180183 set_self( this, m );
181184 std::strncpy( m_szNames[0], mod->get_metadata("title").c_str(), sizeof( m_szNames[0] ) );
182185 m_szNames[0][ sizeof( m_szNames[0] ) - 1 ] = '\0';
186 std::string type = mod->get_metadata("type");
187 m_nType = MOD_TYPE_NONE;
188 if ( type == "mod" ) {
189 m_nType = MOD_TYPE_MOD;
190 } else if ( type == "s3m" ) {
191 m_nType = MOD_TYPE_S3M;
192 } else if ( type == "xm" ) {
193 m_nType = MOD_TYPE_XM;
194 } else if ( type == "med" ) {
195 m_nType = MOD_TYPE_MED;
196 } else if ( type == "mtm" ) {
197 m_nType = MOD_TYPE_MTM;
198 } else if ( type == "it" ) {
199 m_nType = MOD_TYPE_IT;
200 } else if ( type == "669" ) {
201 m_nType = MOD_TYPE_669;
202 } else if ( type == "ult" ) {
203 m_nType = MOD_TYPE_ULT;
204 } else if ( type == "stm" ) {
205 m_nType = MOD_TYPE_STM;
206 } else if ( type == "far" ) {
207 m_nType = MOD_TYPE_FAR;
208 } else if ( type == "s3m" ) {
209 m_nType = MOD_TYPE_WAV;
210 } else if ( type == "amf" ) {
211 m_nType = MOD_TYPE_AMF;
212 } else if ( type == "ams" ) {
213 m_nType = MOD_TYPE_AMS;
214 } else if ( type == "dsm" ) {
215 m_nType = MOD_TYPE_DSM;
216 } else if ( type == "mdl" ) {
217 m_nType = MOD_TYPE_MDL;
218 } else if ( type == "okt" ) {
219 m_nType = MOD_TYPE_OKT;
220 } else if ( type == "mid" ) {
221 m_nType = MOD_TYPE_MID;
222 } else if ( type == "dmf" ) {
223 m_nType = MOD_TYPE_DMF;
224 } else if ( type == "ptm" ) {
225 m_nType = MOD_TYPE_PTM;
226 } else if ( type == "dbm" ) {
227 m_nType = MOD_TYPE_DBM;
228 } else if ( type == "mt2" ) {
229 m_nType = MOD_TYPE_MT2;
230 } else if ( type == "amf0" ) {
231 m_nType = MOD_TYPE_AMF0;
232 } else if ( type == "psm" ) {
233 m_nType = MOD_TYPE_PSM;
234 } else if ( type == "j2b" ) {
235 m_nType = MOD_TYPE_J2B;
236 } else if ( type == "abc" ) {
237 m_nType = MOD_TYPE_ABC;
238 } else if ( type == "pat" ) {
239 m_nType = MOD_TYPE_PAT;
240 } else if ( type == "umx" ) {
241 m_nType = MOD_TYPE_UMX;
242 } else {
243 m_nType = MOD_TYPE_IT; // fallback, most complex type
244 }
245 m_nChannels = mod->get_num_channels();
246 m_nMasterVolume = 128;
247 m_nSamples = mod->get_num_samples();
183248 return TRUE;
184249 } catch ( ... ) {
185250 Destroy();
194259 set_self( this, 0 );
195260 }
196261 return TRUE;
262 }
263
264 UINT CSoundFile::GetNumChannels() const {
265 mpcpplog();
266 return mod->get_num_channels();
267 }
268
269 static int vol128_To_millibel( unsigned int vol ) {
270 return static_cast<int>( 2000.0 * std::log10( static_cast<int>( vol ) / 128.0 ) );
271 }
272
273 BOOL CSoundFile::SetMasterVolume( UINT vol, BOOL bAdjustAGC ) {
274 UNUSED(bAdjustAGC);
275 mpcpplog();
276 m_nMasterVolume = vol;
277 mod->set_render_param( openmpt::module::RENDER_MASTERGAIN_MILLIBEL, vol128_To_millibel( m_nMasterVolume ) );
278 return TRUE;
279 }
280
281 UINT CSoundFile::GetNumPatterns() const {
282 mpcpplog();
283 return mod->get_num_patterns();
284 }
285
286 UINT CSoundFile::GetNumInstruments() const {
287 mpcpplog();
288 return mod->get_num_instruments();
289 }
290
291 void CSoundFile::SetCurrentOrder( UINT nOrder ) {
292 mpcpplog();
293 mod->set_position_order_row( nOrder, 0 );
294 }
295
296 UINT CSoundFile::GetSampleName( UINT nSample, LPSTR s ) const {
297 UNUSED(nSample);
298 mpcpplog();
299 if ( !s ) {
300 return 0;
301 }
302 // todo
303 return 0;
304 }
305
306 UINT CSoundFile::GetInstrumentName( UINT nInstr, LPSTR s ) const {
307 UNUSED(nInstr);
308 mpcpplog();
309 if ( !s ) {
310 return 0;
311 }
312 // todo
313 return 0;
314 }
315
316 void CSoundFile::LoopPattern( int nPat, int nRow ) {
317 UNUSED(nPat);
318 UNUSED(nRow);
319 mpcpplog();
320 // todo
321 }
322
323 void CSoundFile::CheckCPUUsage( UINT nCPU ) {
324 UNUSED(nCPU);
325 mpcpplog();
326 }
327
328 BOOL CSoundFile::SetPatternName( UINT nPat, LPCSTR lpszName ) {
329 UNUSED(nPat);
330 mpcpplog();
331 if ( !lpszName ) {
332 return FALSE;
333 }
334 // todo
335 return TRUE;
336 }
337
338 BOOL CSoundFile::GetPatternName( UINT nPat, LPSTR lpszName, UINT cbSize ) const {
339 UNUSED(nPat);
340 mpcpplog();
341 if ( !lpszName || cbSize <= 0 ) {
342 return FALSE;
343 }
344 std::memset( lpszName, 0, cbSize );
345 // todo
346 return TRUE;
347 }
348
349 BOOL CSoundFile::ReadXM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
350 BOOL CSoundFile::ReadS3M(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
351 BOOL CSoundFile::ReadMod(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
352 BOOL CSoundFile::ReadMed(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
353 BOOL CSoundFile::ReadMTM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
354 BOOL CSoundFile::ReadSTM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
355 BOOL CSoundFile::ReadIT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
356 BOOL CSoundFile::Read669(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
357 BOOL CSoundFile::ReadUlt(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
358 BOOL CSoundFile::ReadWav(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
359 BOOL CSoundFile::ReadDSM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
360 BOOL CSoundFile::ReadFAR(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
361 BOOL CSoundFile::ReadAMS(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
362 BOOL CSoundFile::ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
363 BOOL CSoundFile::ReadMDL(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
364 BOOL CSoundFile::ReadOKT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
365 BOOL CSoundFile::ReadDMF(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
366 BOOL CSoundFile::ReadPTM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
367 BOOL CSoundFile::ReadDBM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
368 BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
369 BOOL CSoundFile::ReadMT2(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
370 BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
371 BOOL CSoundFile::ReadJ2B(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
372 BOOL CSoundFile::ReadUMX(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
373 BOOL CSoundFile::ReadABC(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
374 BOOL CSoundFile::TestABC(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
375 BOOL CSoundFile::ReadMID(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
376 BOOL CSoundFile::TestMID(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
377 BOOL CSoundFile::ReadPAT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
378 BOOL CSoundFile::TestPAT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
379
380 #ifndef MODPLUG_NO_FILESAVE
381
382 UINT CSoundFile::WriteSample( FILE * f, MODINSTRUMENT * pins, UINT nFlags, UINT nMaxLen ) {
383 UNUSED(f);
384 UNUSED(pins);
385 UNUSED(nFlags);
386 UNUSED(nMaxLen);
387 mpcpplog();
388 return 0;
389 }
390
391 BOOL CSoundFile::SaveXM( LPCSTR lpszFileName, UINT nPacking ) {
392 UNUSED(lpszFileName);
393 UNUSED(nPacking);
394 mpcpplog();
395 return FALSE;
396 }
397
398 BOOL CSoundFile::SaveS3M( LPCSTR lpszFileName, UINT nPacking ) {
399 UNUSED(lpszFileName);
400 UNUSED(nPacking);
401 mpcpplog();
402 return FALSE;
403 }
404
405 BOOL CSoundFile::SaveMod( LPCSTR lpszFileName, UINT nPacking ) {
406 UNUSED(lpszFileName);
407 UNUSED(nPacking);
408 mpcpplog();
409 return FALSE;
410 }
411
412 BOOL CSoundFile::SaveIT( LPCSTR lpszFileName, UINT nPacking ) {
413 UNUSED(lpszFileName);
414 UNUSED(nPacking);
415 mpcpplog();
416 return FALSE;
417 }
418
419 #endif
420
421 UINT CSoundFile::GetBestSaveFormat() const {
422 mpcpplog();
423 return MOD_TYPE_IT;
424 }
425
426 UINT CSoundFile::GetSaveFormats() const {
427 mpcpplog();
428 return MOD_TYPE_IT;
429 }
430
431 void CSoundFile::ConvertModCommand( MODCOMMAND * ) const {
432 mpcpplog();
433 }
434
435 void CSoundFile::S3MConvert( MODCOMMAND * m, BOOL bIT ) const {
436 UNUSED(m);
437 UNUSED(bIT);
438 mpcpplog();
439 }
440
441 void CSoundFile::S3MSaveConvert( UINT * pcmd, UINT * pprm, BOOL bIT ) const {
442 UNUSED(pcmd);
443 UNUSED(pprm);
444 UNUSED(bIT);
445 mpcpplog();
446 }
447
448 WORD CSoundFile::ModSaveCommand( const MODCOMMAND * m, BOOL bXM ) const {
449 UNUSED(m);
450 UNUSED(bXM);
451 mpcpplog();
452 return 0;
453 }
454
455 VOID CSoundFile::ResetChannels() {
456 mpcpplog();
457 }
458
459 UINT CSoundFile::CreateStereoMix( int count ) {
460 UNUSED(count);
461 mpcpplog();
462 return 0;
463 }
464
465 BOOL CSoundFile::FadeSong( UINT msec ) {
466 UNUSED(msec);
467 mpcpplog();
468 return TRUE;
469 }
470
471 BOOL CSoundFile::GlobalFadeSong( UINT msec ) {
472 UNUSED(msec);
473 mpcpplog();
474 return TRUE;
475 }
476
477 BOOL CSoundFile::InitPlayer( BOOL bReset ) {
478 UNUSED(bReset);
479 mpcpplog();
480 return TRUE;
481 }
482
483 BOOL CSoundFile::SetMixConfig( UINT nStereoSeparation, UINT nMaxMixChannels ) {
484 UNUSED(nMaxMixChannels);
485 mpcpplog();
486 m_nStereoSeparation = nStereoSeparation;
487 return TRUE;
488 }
489
490 DWORD CSoundFile::InitSysInfo() {
491 mpcpplog();
492 return 0;
493 }
494
495 void CSoundFile::SetAGC( BOOL b ) {
496 UNUSED(b);
497 mpcpplog();
498 }
499
500 void CSoundFile::ResetAGC() {
501 mpcpplog();
502 }
503
504 void CSoundFile::ProcessAGC( int count ) {
505 UNUSED(count);
506 mpcpplog();
197507 }
198508
199509 BOOL CSoundFile::SetWaveConfig( UINT nRate, UINT nBits, UINT nChannels, BOOL bMMX ) {
303613 return static_cast<UINT>( std::strlen( s ) + 1 );
304614 }
305615
616 UINT CSoundFile::GetRawSongComments( LPSTR s, UINT cbsize, UINT linesize ) {
617 UNUSED(linesize);
618 mpcpplog();
619 if ( !s ) {
620 return 0;
621 }
622 if ( cbsize <= 0 ) {
623 return 0;
624 }
625 if ( !mod ) {
626 s[0] = '\0';
627 return 1;
628 }
629 std::strncpy( s, mod->get_metadata("message_raw").c_str(), cbsize );
630 s[ cbsize - 1 ] = '\0';
631 return static_cast<UINT>( std::strlen( s ) + 1 );
632 }
633
306634 void CSoundFile::SetCurrentPos( UINT nPos ) {
307635 mpcpplog();
308636 if ( mod ) mod->set_position_seconds( nPos );
312640 mpcpplog();
313641 if ( mod ) return static_cast<UINT>( mod->get_position_seconds() + 0.5 );
314642 return 0;
643 }
644
645 static int get_stereo_separation() {
646 mpcpplog();
647 return CSoundFile::m_nStereoSeparation * 100 / 128;
315648 }
316649
317650 static int get_filter_length() {
378711 out = &tmpbuf[0];
379712 }
380713
714 mod->set_render_param( openmpt::module::RENDER_STEREOSEPARATION_PERCENT, get_stereo_separation() );
381715 mod->set_render_param( openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH, get_filter_length() );
382716 std::size_t frames_rendered = 0;
383717 if ( get_num_channels() == 1 ) {
402736 return static_cast<UINT>( frames_rendered * get_frame_size() );
403737 }
404738
739
405740 /*
406741
407742 gstreamer modplug calls:
430765
431766 */
432767
768
769 // really very internal symbols, probably nothing calls these directly
770
771 #if defined(__clang__)
772 #pragma clang diagnostic push
773 #pragma clang diagnostic ignored "-Wunknown-pragmas"
774 #pragma clang diagnostic ignored "-Wunused-parameter"
775 #elif defined(__GNUC__)
776 #pragma GCC diagnostic push
777 #pragma GCC diagnostic ignored "-Wunknown-pragmas"
778 #pragma GCC diagnostic ignored "-Wunused-parameter"
779 #elif defined(_MSC_VER)
780 #pragma warning(push)
781 #pragma warning(disable:4100)
782 #endif
783
784 BOOL CSoundFile::ReadNote() { mpcpplog(); return 0; }
785 BOOL CSoundFile::ProcessRow() { mpcpplog(); return 0; }
786 BOOL CSoundFile::ProcessEffects() { mpcpplog(); return 0; }
787 UINT CSoundFile::GetNNAChannel(UINT nChn) const { mpcpplog(); return 0; }
788 void CSoundFile::CheckNNA(UINT nChn, UINT instr, int note, BOOL bForceCut) { mpcpplog(); }
789 void CSoundFile::NoteChange(UINT nChn, int note, BOOL bPorta, BOOL bResetEnv) { mpcpplog(); }
790 void CSoundFile::InstrumentChange(MODCHANNEL *pChn, UINT instr, BOOL bPorta,BOOL bUpdVol,BOOL bResetEnv) { mpcpplog(); }
791 void CSoundFile::PortamentoUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
792 void CSoundFile::PortamentoDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
793 void CSoundFile::FinePortamentoUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
794 void CSoundFile::FinePortamentoDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
795 void CSoundFile::ExtraFinePortamentoUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
796 void CSoundFile::ExtraFinePortamentoDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
797 void CSoundFile::TonePortamento(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
798 void CSoundFile::Vibrato(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
799 void CSoundFile::FineVibrato(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
800 void CSoundFile::VolumeSlide(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
801 void CSoundFile::PanningSlide(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
802 void CSoundFile::ChannelVolSlide(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
803 void CSoundFile::FineVolumeUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
804 void CSoundFile::FineVolumeDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
805 void CSoundFile::Tremolo(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
806 void CSoundFile::Panbrello(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
807 void CSoundFile::RetrigNote(UINT nChn, UINT param) { mpcpplog(); }
808 void CSoundFile::NoteCut(UINT nChn, UINT nTick) { mpcpplog(); }
809 void CSoundFile::KeyOff(UINT nChn) { mpcpplog(); }
810 int CSoundFile::PatternLoop(MODCHANNEL *, UINT param) { mpcpplog(); return 0; }
811 void CSoundFile::ExtendedMODCommands(UINT nChn, UINT param) { mpcpplog(); }
812 void CSoundFile::ExtendedS3MCommands(UINT nChn, UINT param) { mpcpplog(); }
813 void CSoundFile::ExtendedChannelEffect(MODCHANNEL *, UINT param) { mpcpplog(); }
814 void CSoundFile::ProcessMidiMacro(UINT nChn, LPCSTR pszMidiMacro, UINT param) { mpcpplog(); }
815 void CSoundFile::SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier) const { mpcpplog(); }
816 void CSoundFile::DoFreqSlide(MODCHANNEL *pChn, LONG nFreqSlide) { mpcpplog(); }
817 void CSoundFile::SetTempo(UINT param) { mpcpplog(); }
818 void CSoundFile::SetSpeed(UINT param) { mpcpplog(); }
819 void CSoundFile::GlobalVolSlide(UINT param) { mpcpplog(); }
820 DWORD CSoundFile::IsSongFinished(UINT nOrder, UINT nRow) const { mpcpplog(); return 0; }
821 BOOL CSoundFile::IsValidBackwardJump(UINT nStartOrder, UINT nStartRow, UINT nJumpOrder, UINT nJumpRow) const { mpcpplog(); return 0; }
822 UINT CSoundFile::PackSample(int &sample, int next) { mpcpplog(); return 0; }
823 BOOL CSoundFile::CanPackSample(LPSTR pSample, UINT nLen, UINT nPacking, BYTE *result) { mpcpplog(); return 0; }
824 UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR pMemFile, DWORD dwMemLength) { mpcpplog(); return 0; }
825 BOOL CSoundFile::DestroySample(UINT nSample) { mpcpplog(); return 0; }
826 BOOL CSoundFile::DestroyInstrument(UINT nInstr) { mpcpplog(); return 0; }
827 BOOL CSoundFile::IsSampleUsed(UINT nSample) { mpcpplog(); return 0; }
828 BOOL CSoundFile::IsInstrumentUsed(UINT nInstr) { mpcpplog(); return 0; }
829 BOOL CSoundFile::RemoveInstrumentSamples(UINT nInstr) { mpcpplog(); return 0; }
830 UINT CSoundFile::DetectUnusedSamples(BOOL *) { mpcpplog(); return 0; }
831 BOOL CSoundFile::RemoveSelectedSamples(BOOL *) { mpcpplog(); return 0; }
832 void CSoundFile::AdjustSampleLoop(MODINSTRUMENT *pIns) { mpcpplog(); }
833 BOOL CSoundFile::ReadInstrumentFromSong(UINT nInstr, CSoundFile *, UINT nSrcInstrument) { mpcpplog(); return 0; }
834 BOOL CSoundFile::ReadSampleFromSong(UINT nSample, CSoundFile *, UINT nSrcSample) { mpcpplog(); return 0; }
835 UINT CSoundFile::GetNoteFromPeriod(UINT period) const { mpcpplog(); return 0; }
836 UINT CSoundFile::GetPeriodFromNote(UINT note, int nFineTune, UINT nC4Speed) const { mpcpplog(); return 0; }
837 UINT CSoundFile::GetFreqFromPeriod(UINT period, UINT nC4Speed, int nPeriodFrac) const { mpcpplog(); return 0; }
838 void CSoundFile::ResetMidiCfg() { mpcpplog(); }
839 UINT CSoundFile::MapMidiInstrument(DWORD dwProgram, UINT nChannel, UINT nNote) { mpcpplog(); return 0; }
840 BOOL CSoundFile::ITInstrToMPT(const void *p, INSTRUMENTHEADER *penv, UINT trkvers) { mpcpplog(); return 0; }
841 UINT CSoundFile::SaveMixPlugins(FILE *f, BOOL bUpdate) { mpcpplog(); return 0; }
842 UINT CSoundFile::LoadMixPlugins(const void *pData, UINT nLen) { mpcpplog(); return 0; }
843 #ifndef NO_FILTER
844 DWORD CSoundFile::CutOffToFrequency(UINT nCutOff, int flt_modifier) const { mpcpplog(); return 0; }
845 #endif
846 DWORD CSoundFile::TransposeToFrequency(int transp, int ftune) { mpcpplog(); return 0; }
847 int CSoundFile::FrequencyToTranspose(DWORD freq) { mpcpplog(); return 0; }
848 void CSoundFile::FrequencyToTranspose(MODINSTRUMENT *psmp) { mpcpplog(); }
849 MODCOMMAND *CSoundFile::AllocatePattern(UINT rows, UINT nchns) { mpcpplog(); return 0; }
850 signed char* CSoundFile::AllocateSample(UINT nbytes) { mpcpplog(); return 0; }
851 void CSoundFile::FreePattern(LPVOID pat) { mpcpplog(); }
852 void CSoundFile::FreeSample(LPVOID p) { mpcpplog(); }
853 UINT CSoundFile::Normalize24BitBuffer(LPBYTE pbuffer, UINT cbsizebytes, DWORD lmax24, DWORD dwByteInc) { mpcpplog(); return 0; }
854
855 #if defined(__clang__)
856 #pragma clang diagnostic pop
857 #elif defined(__GNUC__)
858 #pragma GCC diagnostic pop
859 #elif defined(_MSC_VER)
860 #pragma warning(pop)
861 #endif
862
863
433864 #endif // NO_LIBMODPLUG
00 .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.46.4.
1 .TH OPENMPT123 "1" "November 2016" "openmpt123 v0.2" "User Commands"
1 .TH OPENMPT123 "1" "February 2017" "openmpt123 v0.2" "User Commands"
22 .SH NAME
33 openmpt123 - command line module music player based on libopenmpt
44 .SH SYNOPSIS
156156 \fB\-\-\fR
157157 Interpret further arguments as filenames
158158 .SH COPYRIGHT
159 Copyright \(co 2013\-2016 OpenMPT developers <https://lib.openmpt.org/>
159 Copyright \(co 2013\-2017 OpenMPT developers <https://lib.openmpt.org/>
10841084 LONG lAttn = lAttenuation;
10851085 pRgn->uUnityNote = 0xFF; // 0xFF means undefined -> use sample
10861086 pRgn->sFineTune = 0;
1087 pRgn->nWaveLink = Util::MaxValueOfType(pRgn->nWaveLink);
10871088 // Load Generators
10881089 SFINSTBAG *pbag = psf2->pInstBags + ibagcnt;
10891090 for (uint32 igenndx=pbag[0].wGenNdx; igenndx<pbag[1].wGenNdx; igenndx++)
16621663 bool CDLSBank::ExtractInstrument(CSoundFile &sndFile, INSTRUMENTINDEX nInstr, uint32 nIns, uint32 nDrumRgn)
16631664 //---------------------------------------------------------------------------------------------------------
16641665 {
1665 uint8 RgnToSmp[DLSMAXREGIONS];
1666 SAMPLEINDEX RgnToSmp[DLSMAXREGIONS];
16661667 DLSINSTRUMENT *pDlsIns;
16671668 ModInstrument *pIns;
16681669 uint32 nRgnMin, nRgnMax, nEnv;
1669 SAMPLEINDEX nSample;
16701670
16711671 if ((!m_pInstruments) || (nIns >= m_nInstruments)) return false;
16721672 pDlsIns = &m_pInstruments[nIns];
17571757 pIns->nDCT = DCT_NOTE;
17581758 pIns->nDNA = DNA_NOTEFADE;
17591759 sndFile.Instruments[nInstr] = pIns;
1760 nSample = 0;
17611760 uint32 nLoadedSmp = 0;
1761 SAMPLEINDEX nextSample = 0;
17621762 // Extract Samples
17631763 for (uint32 nRgn=nRgnMin; nRgn<nRgnMax; nRgn++)
17641764 {
1765 bool bDupRgn;
1766 uint32 nSmp;
1765 bool bDupRgn = false;
1766 SAMPLEINDEX nSmp = 0;
17671767 DLSREGION *pRgn = &pDlsIns->Regions[nRgn];
17681768 // Elimitate Duplicate Regions
1769 nSmp = 0;
1770 bDupRgn = false;
17711769 uint32 iDup;
17721770 for (iDup=nRgnMin; iDup<nRgn; iDup++)
17731771 {
17841782 }
17851783 }
17861784 // Create a new sample
1787 //if (pRgn->nWaveLink == 0) nSmp = 0; else
17881785 if (!bDupRgn)
17891786 {
17901787 uint32 nmaxsmp = (m_nType & MOD_TYPE_XM) ? 16 : 32;
17931790 nSmp = RgnToSmp[nRgn-1];
17941791 } else
17951792 {
1796 nSample = sndFile.GetNextFreeSample(nInstr, nSample + 1);
1797 if (nSample == SAMPLEINDEX_INVALID) break;
1798 if (nSample > sndFile.GetNumSamples()) sndFile.m_nSamples = nSample;
1799 nSmp = nSample;
1793 nextSample = sndFile.GetNextFreeSample(nInstr, nextSample + 1);
1794 if (nextSample == SAMPLEINDEX_INVALID) break;
1795 if (nextSample > sndFile.GetNumSamples()) sndFile.m_nSamples = nextSample;
1796 nSmp = nextSample;
18001797 nLoadedSmp++;
18011798 }
18021799 }
18031800
1804 RgnToSmp[nRgn] = (uint8)nSmp;
1801 RgnToSmp[nRgn] = nSmp;
18051802 // Map all notes to the right sample
18061803 if (nSmp)
18071804 {
18091806 {
18101807 if ((nRgn == nRgnMin) || ((iKey >= pRgn->uKeyMin) && (iKey <= pRgn->uKeyMax)))
18111808 {
1812 pIns->Keyboard[iKey] = (SAMPLEINDEX)nSmp;
1809 pIns->Keyboard[iKey] = nSmp;
18131810 }
18141811 }
18151812 // Load the sample
1816 if(!bDupRgn)
1817 {
1818 ExtractSample(sndFile, nSample, nIns, nRgn, nTranspose);
1819 } else if(sndFile.GetSample(nSample).GetNumChannels() == 1)
1813 if(!bDupRgn || sndFile.GetSample(nSmp).pSample == nullptr)
1814 {
1815 ExtractSample(sndFile, nSmp, nIns, nRgn, nTranspose);
1816 } else if(sndFile.GetSample(nSmp).GetNumChannels() == 1)
18201817 {
18211818 // Try to combine stereo samples
18221819 uint8 pan1 = GetPanning(nIns, nRgn), pan2 = GetPanning(nIns, iDup);
18231820 if((pan1 == 0 || pan1 == 255) && (pan2 == 0 || pan2 == 255))
18241821 {
1825 ModSample &sample = sndFile.GetSample(nSample);
1822 ModSample &sample = sndFile.GetSample(nSmp);
18261823 ctrlSmp::ConvertToStereo(sample, sndFile);
18271824 std::vector<uint8> pWaveForm;
18281825 uint32 dwLen = 0;
440440 const float FloatToInt = m_PlayConfig.getFloatToInt();
441441 #endif // MPT_INTMIXER
442442
443 // Setup float inputs
443 // Setup float inputs from samples
444444 for(PLUGINDEX plug = 0; plug < MAX_MIXPLUGINS; plug++)
445445 {
446446 SNDMIXPLUGIN &plugin = m_MixPlugins[plug];
596596 // Samples or plugins are being rendered, so turn off auto-bypass for this master effect.
597597 if(plugin.pMixPlugin != nullptr) plugin.pMixPlugin->ResetSilence();
598598 SNDMIXPLUGIN *chain = &plugin;
599 PLUGINDEX out = chain->GetOutputPlugin();
600 while(out > plug && out < MAX_MIXPLUGINS)
599 PLUGINDEX out = chain->GetOutputPlugin(), prevOut = plug;
600 while(out > prevOut && out < MAX_MIXPLUGINS)
601601 {
602602 chain = &m_MixPlugins[out];
603 prevOut = out;
603604 out = chain->GetOutputPlugin();
604605 if(chain->pMixPlugin)
605606 {
1515 #include "stdafx.h"
1616 #include "Loaders.h"
1717 #include "ChunkReader.h"
18 #include <stdexcept>
1819
1920 OPENMPT_NAMESPACE_BEGIN
2021
10861087 int bitnum;
10871088 int lastnode, nodecount;
10881089 DMFHNode nodes[256];
1090
1091 // DMF Huffman ReadBits
1092 uint8 DMFReadBits(int nbits)
1093 {
1094 if(bitnum < nbits)
1095 {
1096 if(ibuf < ibufmax)
1097 {
1098 bitbuf |= (((uint32)(*ibuf++)) << bitnum);
1099 bitnum += 8;
1100 } else
1101 {
1102 throw std::range_error("Truncated DMF sample block");
1103 }
1104 }
1105
1106 uint8 v = static_cast<uint8>(bitbuf & ((1 << nbits) - 1));
1107 bitbuf >>= nbits;
1108 bitnum -= nbits;
1109 return v;
1110 }
1111
1112
1113 //
1114 // tree: [8-bit value][12-bit index][12-bit index] = 32-bit
1115 //
1116
1117 void DMFNewNode()
1118 {
1119 uint8 isleft, isright;
1120 int actnode;
1121
1122 actnode = nodecount;
1123 if(actnode > 255) return;
1124 nodes[actnode].value = DMFReadBits(7);
1125 isleft = DMFReadBits(1);
1126 isright = DMFReadBits(1);
1127 actnode = lastnode;
1128 if(actnode > 255) return;
1129 nodecount++;
1130 lastnode = nodecount;
1131 if(isleft)
1132 {
1133 nodes[actnode].left = (int16)lastnode;
1134 DMFNewNode();
1135 } else
1136 {
1137 nodes[actnode].left = -1;
1138 }
1139 lastnode = nodecount;
1140 if(isright)
1141 {
1142 nodes[actnode].right = (int16)lastnode;
1143 DMFNewNode();
1144 } else
1145 {
1146 nodes[actnode].right = -1;
1147 }
1148 }
10891149 };
1090
1091
1092 // DMF Huffman ReadBits
1093 static uint8 DMFReadBits(DMFHTree *tree, uint32 nbits)
1094 //----------------------------------------------------
1095 {
1096 uint8 x = 0, bitv = 1;
1097 while(nbits--)
1098 {
1099 if (tree->bitnum)
1100 {
1101 tree->bitnum--;
1102 } else
1103 {
1104 tree->bitbuf = (tree->ibuf < tree->ibufmax) ? *(tree->ibuf++) : 0;
1105 tree->bitnum = 7;
1106 }
1107 if (tree->bitbuf & 1) x |= bitv;
1108 bitv <<= 1;
1109 tree->bitbuf >>= 1;
1110 }
1111 return x;
1112 }
1113
1114 //
1115 // tree: [8-bit value][12-bit index][12-bit index] = 32-bit
1116 //
1117
1118 static void DMFNewNode(DMFHTree *tree)
1119 //------------------------------------
1120 {
1121 uint8 isleft, isright;
1122 int actnode;
1123
1124 actnode = tree->nodecount;
1125 if (actnode > 255) return;
1126 tree->nodes[actnode].value = DMFReadBits(tree, 7);
1127 isleft = DMFReadBits(tree, 1);
1128 isright = DMFReadBits(tree, 1);
1129 actnode = tree->lastnode;
1130 if (actnode > 255) return;
1131 tree->nodecount++;
1132 tree->lastnode = tree->nodecount;
1133 if(isleft)
1134 {
1135 tree->nodes[actnode].left = (int16)tree->lastnode;
1136 DMFNewNode(tree);
1137 } else
1138 {
1139 tree->nodes[actnode].left = -1;
1140 }
1141 tree->lastnode = tree->nodecount;
1142 if(isright)
1143 {
1144 tree->nodes[actnode].right = (int16)tree->lastnode;
1145 DMFNewNode(tree);
1146 } else
1147 {
1148 tree->nodes[actnode].right = -1;
1149 }
1150 }
11511150
11521151
11531152 uintptr_t DMFUnpack(uint8 *psample, const uint8 *ibuf, const uint8 *ibufmax, uint32 maxlen)
11581157 MemsetZero(tree);
11591158 tree.ibuf = ibuf;
11601159 tree.ibufmax = ibufmax;
1161 DMFNewNode(&tree);
1160 tree.DMFNewNode();
11621161 uint8 value = 0, delta = 0;
11631162
1164 for(uint32 i = 0; i < maxlen; i++)
1165 {
1166 int actnode = 0;
1167 uint8 sign = DMFReadBits(&tree, 1);
1168 do
1169 {
1170 if(DMFReadBits(&tree, 1))
1171 actnode = tree.nodes[actnode].right;
1172 else
1173 actnode = tree.nodes[actnode].left;
1174 if(actnode > 255) break;
1175 delta = tree.nodes[actnode].value;
1176 if((tree.ibuf >= tree.ibufmax) && (!tree.bitnum)) break;
1177 } while ((tree.nodes[actnode].left >= 0) && (tree.nodes[actnode].right >= 0));
1178 if(sign) delta ^= 0xFF;
1179 value += delta;
1180 psample[i] = (i) ? value : 0;
1181 }
1182 #ifdef DMFLOG
1183 // Log("DMFUnpack: %d remaining bytes\n", tree.ibufmax-tree.ibuf);
1184 #endif
1163 try
1164 {
1165 for(uint32 i = 0; i < maxlen; i++)
1166 {
1167 int actnode = 0;
1168 uint8 sign = tree.DMFReadBits(1);
1169 do
1170 {
1171 if(tree.DMFReadBits(1))
1172 actnode = tree.nodes[actnode].right;
1173 else
1174 actnode = tree.nodes[actnode].left;
1175 if(actnode > 255) break;
1176 delta = tree.nodes[actnode].value;
1177 } while((tree.nodes[actnode].left >= 0) && (tree.nodes[actnode].right >= 0));
1178 if(sign) delta ^= 0xFF;
1179 value += delta;
1180 psample[i] = value;
1181 }
1182 } catch(const std::range_error &)
1183 {
1184 //AddToLog(LogWarning, "Truncated DMF sample block");
1185 }
11851186 return tree.ibuf - ibuf;
11861187 }
11871188
932932 // MDL Sample Unpacking
933933
934934 // MDL Huffman ReadBits compression
935 uint16 MDLReadBits(uint32 &bitbuf, uint32 &bitnum, const uint8 *(&ibuf), size_t &bytesLeft, int8 n)
936 //-------------------------------------------------------------------------------------------------
937 {
938 uint16 v = (uint16)(bitbuf & ((1 << n) - 1) );
935 uint8 MDLReadBits(uint32 &bitbuf, int32 &bitnum, const uint8 *(&ibuf), size_t &bytesLeft, int8 n)
936 //-----------------------------------------------------------------------------------------------
937 {
938 if(bitnum < n)
939 {
940 if(bytesLeft)
941 {
942 bitbuf |= (((uint32)(*ibuf++)) << bitnum);
943 bitnum += 8;
944 bytesLeft--;
945 } else
946 {
947 throw std::range_error("Truncated MDL sample block");
948 }
949 }
950
951 uint8 v = static_cast<uint8>(bitbuf & ((1 << n) - 1));
939952 bitbuf >>= n;
940953 bitnum -= n;
941 if (bitnum <= 24)
942 {
943 if(!bytesLeft)
944 {
945 bitnum += 8;
946 return uint16_max;
947 }
948 bitbuf |= (((uint32)(*ibuf++)) << bitnum);
949 bitnum += 8;
950 bytesLeft--;
951 }
952954 return v;
953955 }
954956
203203 }
204204
205205 InitializeGlobals(MOD_TYPE_S3M);
206 m_nMinPeriod = 64;
207 m_nMaxPeriod = 32767;
206208
207209 // ST3 ignored Zxx commands, so if we find that a file was made with ST3, we should erase all MIDI macros.
208210 bool keepMidiMacros = false;
240242 else
241243 m_madeWithTracker = mpt::String::Print("Impulse Tracker 2.14p%1", fileHeader.cwtv - S3MFileHeader::trkIT2_14);
242244 nonCompatTracker = true;
245 m_nMinPeriod = 1;
243246 break;
244247 case S3MFileHeader::trkSchismTracker:
245248 if(fileHeader.cwtv == S3MFileHeader::trkBeRoTrackerOld)
249 {
246250 m_madeWithTracker = "BeRoTracker";
247 else
251 m_playBehaviour.set(kST3LimitPeriod);
252 } else
253 {
248254 m_madeWithTracker = GetSchismTrackerVersion(fileHeader.cwtv);
255 m_nMinPeriod = 1;
256 }
249257 nonCompatTracker = true;
250258 break;
251259 case S3MFileHeader::trkOpenMPT:
254262 break;
255263 case S3MFileHeader::trkBeRoTracker:
256264 m_madeWithTracker = "BeRoTracker";
265 m_playBehaviour.set(kST3LimitPeriod);
257266 break;
258267 case S3MFileHeader::trkCreamTracker:
259268 m_madeWithTracker = "CreamTracker";
291300
292301 mpt::String::Read<mpt::String::nullTerminated>(m_songName, fileHeader.name);
293302
294 m_nMinPeriod = 64;
295 m_nMaxPeriod = 32767;
296303 if(fileHeader.flags & S3MFileHeader::amigaLimits) m_SongFlags.set(SONG_AMIGALIMITS);
297304 if(fileHeader.flags & S3MFileHeader::st2Vibrato) m_SongFlags.set(SONG_S3MOLDVIBRATO);
298305
326326 VolEnv.Sanitize();
327327 PanEnv.Sanitize();
328328 PitchEnv.Sanitize(range);
329
330 for(size_t i = 0; i < CountOf(NoteMap); i++)
331 {
332 if(NoteMap[i] < NOTE_MIN || NoteMap[i] > NOTE_MAX)
333 NoteMap[i] = static_cast<uint8>(i + NOTE_MIN);
334 }
329335 }
330336
331337
2828 TransposeToFrequency();
2929 RelativeTone = 0;
3030 nFineTune = 0;
31 // TransposeToFrequency assumes NTSC middle-C frequency like FT2, but we play MODs with PAL middle-C!
32 if(fromType == MOD_TYPE_MOD)
33 nC5Speed = Util::muldivr_unsigned(nC5Speed, 8272, 8363);
3134 } else if((toType & (MOD_TYPE_MOD | MOD_TYPE_XM)) && (!(fromType & (MOD_TYPE_MOD | MOD_TYPE_XM))))
3235 {
36 // FrequencyToTranspose assumes NTSC middle-C frequency like FT2, but we play MODs with PAL middle-C!
37 if(toType == MOD_TYPE_MOD)
38 nC5Speed = Util::muldivr_unsigned(nC5Speed, 8363, 8272);
3339 FrequencyToTranspose();
3440 }
3541
143149 rate = TransposeToFrequency(RelativeTone, nFineTune);
144150 else
145151 rate = nC5Speed;
152 // TransposeToFrequency assumes NTSC middle-C frequency like FT2, but we play MODs with PAL middle-C!
153 if(type == MOD_TYPE_MOD)
154 rate = Util::muldivr_unsigned(rate, 8272, 8363);
146155 return (rate > 0) ? rate : 8363;
147156 }
148157
1818 #ifndef MODPLUG_NO_FILESAVE
1919 #include "../common/mptFileIO.h"
2020 #endif
21 #include <stdexcept>
2122
2223
2324 OPENMPT_NAMESPACE_BEGIN
2425
2526 // Sample decompression routines in other source files
2627 void AMSUnpack(const int8 * const source, size_t sourceSize, void * const dest, const size_t destSize, char packCharacter);
27 uint16 MDLReadBits(uint32 &bitbuf, uint32 &bitnum, const uint8 *(&ibuf), size_t &bytesLeft, int8 n);
28 uint8 MDLReadBits(uint32 &bitbuf, int32 &bitnum, const uint8 *(&ibuf), size_t &bytesLeft, int8 n);
2829 uintptr_t DMFUnpack(uint8 *psample, const uint8 *ibuf, const uint8 *ibufmax, uint32 maxlen);
2930
3031
132133 } else if(GetEncoding() == MDL && GetChannelFormat() == mono && GetBitDepth() <= 16)
133134 {
134135 // Huffman MDL compressed samples
135 fileSize = file.ReadUint32LE();
136 FileReader chunk = file.ReadChunk(fileSize);
137 bytesRead = chunk.GetLength() + 4;
138 if(chunk.CanRead(4))
139 {
140 uint32 bitBuf = chunk.ReadUint32LE(), bitNum = 32;
136 if(file.CanRead(8) && (fileSize = file.ReadUint32LE()) >= 4)
137 {
138 FileReader chunk = file.ReadChunk(fileSize);
139 bytesRead = chunk.GetLength() + 4;
140 uint32 bitBuf = chunk.ReadUint32LE();
141 int32 bitNum = 32;
141142
142143 restrictedSampleDataView = chunk.GetPinnedRawDataView();
143144 sourceBuf = restrictedSampleDataView.data();
144145
145146 const uint8 *inBuf = reinterpret_cast<const uint8*>(sourceBuf);
146 size_t bytesLeft = chunk.GetLength() - 4;
147 size_t bytesLeft = chunk.BytesLeft();
147148
148149 uint8 dlt = 0, lowbyte = 0;
149 const bool _16bit = GetBitDepth() == 16;
150 for(SmpLength j = 0; j < sample.nLength; j++)
151 {
152 uint8 hibyte;
153 uint8 sign;
154 if(_16bit)
150 const bool is16bit = GetBitDepth() == 16;
151 try
152 {
153 for(SmpLength j = 0; j < sample.nLength; j++)
155154 {
156 lowbyte = static_cast<uint8>(MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 8));
155 uint8 hibyte;
156 if(is16bit)
157 {
158 lowbyte = MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 8);
159 }
160 bool sign = MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 1) != 0;
161 if(MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 1))
162 {
163 hibyte = MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 3);
164 } else
165 {
166 hibyte = 8;
167 while(!MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 1))
168 {
169 hibyte += 0x10;
170 }
171 hibyte += MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 4);
172 }
173 if(sign)
174 {
175 hibyte = ~hibyte;
176 }
177 dlt += hibyte;
178 if(!is16bit)
179 {
180 sample.pSample8[j] = dlt;
181 }
182 else
183 {
184 sample.pSample16[j] = lowbyte | (dlt << 8);
185 }
157186 }
158 sign = static_cast<uint8>(MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 1));
159 if (MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 1))
160 {
161 hibyte = static_cast<uint8>(MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 3));
162 } else
163 {
164 hibyte = 8;
165 while (!MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 1)) hibyte += 0x10;
166 hibyte += static_cast<uint8>(MDLReadBits(bitBuf, bitNum, inBuf, bytesLeft, 4));
167 }
168 if (sign) hibyte = ~hibyte;
169 dlt += hibyte;
170 if(!_16bit)
171 {
172 sample.pSample8[j] = dlt;
173 } else
174 {
175 sample.pSample16[j] = lowbyte | (dlt << 8);
176 }
187 } catch(const std::range_error &)
188 {
189 // Data is not sufficient to decode the whole sample
190 //AddToLog(LogWarning, "Truncated MDL sample block");
177191 }
178192 }
179193 } else if(GetEncoding() == DMF && GetChannelFormat() == mono && GetBitDepth() <= 16)
821835 if(sample.uFlags[CHN_STEREO])
822836 {
823837 // Downmix stereo
824 s_new = (s_new + (*p) + 1) >> 1;
838 s_new = (s_new + (*p) + 1) / 2;
825839 p++;
826840 }
827841 if(GetEncoding() == deltaPCM)
964978 p += sinc;
965979 if (sample.uFlags[CHN_STEREO])
966980 {
967 s_new = (s_new + ((int)*p) + 1) >> 1;
981 s_new = (s_new + ((int)*p) + 1) / 2;
968982 p += sinc;
969983 }
970984 if (GetEncoding() == deltaPCM)
480480
481481 public:
482482 static const size_t fractFact = FFact;
483 typedef T store_t;
483484
484485 FPInt() : v(0) { }
485486 FPInt(const FPInt<fractFact, T> &other) : v(other.v) { }
15091509 // Test case: emptyslot.it, PortaInsNum.it, gxsmp.it, gxsmp2.it
15101510 return;
15111511 }
1512 note = pIns->NoteMap[note-1];
1512 note = pIns->NoteMap[note - NOTE_MIN];
15131513 }
15141514 // Key Off
15151515 if(note > NOTE_MAX)
15651565 }
15661566 // IT Compatibility: Update multisample instruments frequency even if instrument is not specified (fixes the guitars in spx-shuttledeparture.it)
15671567 // Test case: freqreset-noins.it
1568 if(!bPorta && pSmp && m_playBehaviour[kITMultiSampleBehaviour]) pChn->nC5Speed = pSmp->nC5Speed;
1568 if(!bPorta && pSmp && m_playBehaviour[kITMultiSampleBehaviour])
1569 pChn->nC5Speed = pSmp->nC5Speed;
15691570
15701571 if(bPorta && pChn->nInc == 0)
15711572 {
35843585 {
35853586 if(m_SongFlags[SONG_LINEARSLIDES] && GetType() != MOD_TYPE_XM)
35863587 {
3587 int oldPeriod = pChn->nPeriod;
3588 const int32 oldPeriod = pChn->nPeriod;
35883589 pChn->nPeriod = Util::muldivr(pChn->nPeriod, GetLinearSlideUpTable(this, param & 0x0F), 65536);
3589 if(oldPeriod == pChn->nPeriod) pChn->nPeriod++;
3590 if(oldPeriod == pChn->nPeriod)
3591 {
3592 if(m_playBehaviour[kHertzInLinearMode] && pChn->nPeriod < Util::MaxValueOfType(pChn->nPeriod))
3593 pChn->nPeriod++;
3594 else if(!m_playBehaviour[kHertzInLinearMode] && pChn->nPeriod > 1)
3595 pChn->nPeriod--;
3596 }
35903597 } else
35913598 {
35923599 pChn->nPeriod -= (int)(param * 4);
36243631 {
36253632 if (m_SongFlags[SONG_LINEARSLIDES] && GetType() != MOD_TYPE_XM)
36263633 {
3627 int oldPeriod = pChn->nPeriod;
3634 const int32 oldPeriod = pChn->nPeriod;
36283635 pChn->nPeriod = Util::muldivr(pChn->nPeriod, GetLinearSlideDownTable(this, param & 0x0F), 65536);
3629 if(oldPeriod == pChn->nPeriod) pChn->nPeriod--;
3636 if(oldPeriod == pChn->nPeriod)
3637 {
3638 if(!m_playBehaviour[kHertzInLinearMode] && pChn->nPeriod < Util::MaxValueOfType(pChn->nPeriod))
3639 pChn->nPeriod++;
3640 else if(m_playBehaviour[kHertzInLinearMode] && pChn->nPeriod > 1)
3641 pChn->nPeriod--;
3642 }
36303643 } else
36313644 {
36323645 pChn->nPeriod += (int)(param * 4);
51735186 {
51745187 // IT Linear slides
51755188 const int32 nOldPeriod = pChn->nPeriod;
5176 if (nFreqSlide < 0)
5177 {
5178 uint32 n = (-nFreqSlide) / 4;
5179 if (n)
5180 {
5181 if (n > 255) n = 255;
5182 pChn->nPeriod = Util::muldivr(pChn->nPeriod, GetLinearSlideUpTable(this, n), 65536);
5183 if (pChn->nPeriod == nOldPeriod) pChn->nPeriod++;
5184 }
5185 } else
5186 {
5187 uint32 n = (nFreqSlide) / 4;
5188 if (n)
5189 {
5190 if (n > 255) n = 255;
5191 pChn->nPeriod = Util::muldivr(pChn->nPeriod, GetLinearSlideDownTable(this, n), 65536);
5192 if (pChn->nPeriod == nOldPeriod) pChn->nPeriod--;
5189 uint32 n = mpt::abs(nFreqSlide) / 4u;
5190 LimitMax(n, 255u);
5191 if(n != 0)
5192 {
5193 pChn->nPeriod = Util::muldivr(pChn->nPeriod, nFreqSlide < 0 ? GetLinearSlideUpTable(this, n) : GetLinearSlideDownTable(this, n), 65536);
5194 if(pChn->nPeriod == nOldPeriod)
5195 {
5196 const bool incPeriod = m_playBehaviour[kHertzInLinearMode] == (nFreqSlide < 0);
5197 if(incPeriod && pChn->nPeriod < Util::MaxValueOfType(pChn->nPeriod))
5198 pChn->nPeriod++;
5199 else if(!incPeriod && pChn->nPeriod > 1)
5200 pChn->nPeriod--;
51935201 }
51945202 }
51955203 } else
55945602 return (period + c5speed - 8363) << FREQ_FRACBITS;
55955603 } else if(GetType() == MOD_TYPE_MDL)
55965604 {
5605 LimitMax(period, Util::MaxValueOfType(period) >> 8);
55975606 if (!c5speed) c5speed = 8363;
5598 return Util::muldiv(c5speed, (1712L << 7) << FREQ_FRACBITS, (period << 8) + nPeriodFrac);
5607 return Util::muldiv_unsigned(c5speed, (1712L << 7) << FREQ_FRACBITS, (period << 8) + nPeriodFrac);
55995608 } else
56005609 {
56015610 LimitMax(period, Util::MaxValueOfType(period) >> 8);
56095618 } else
56105619 {
56115620 if (!c5speed) c5speed = 8363;
5612 return Util::muldiv(c5speed, (1712L << 8) << FREQ_FRACBITS, (period << 8) + nPeriodFrac);
5621 return Util::muldiv_unsigned(c5speed, (1712L << 8) << FREQ_FRACBITS, (period << 8) + nPeriodFrac);
56135622 }
56145623 } else
56155624 {
5616 return Util::muldiv(8363, (1712L << 8) << FREQ_FRACBITS, (period << 8) + nPeriodFrac);
5625 return Util::muldiv_unsigned(8363, (1712L << 8) << FREQ_FRACBITS, (period << 8) + nPeriodFrac);
56175626 }
56185627 }
56195628 }
15411541 {
15421542 case tempoModeClassic:
15431543 default:
1544 m_PlayState.m_nSamplesPerTick = Util::muldiv(m_MixerSettings.gdwMixingFreq, 5 * TEMPO::fractFact, m_PlayState.m_nMusicTempo.GetRaw() << 1);
1544 m_PlayState.m_nSamplesPerTick = Util::muldiv(m_MixerSettings.gdwMixingFreq, 5 * TEMPO::fractFact, std::max(TEMPO::store_t(1), m_PlayState.m_nMusicTempo.GetRaw() << 1));
15451545 break;
15461546
15471547 case tempoModeModern:
1548 m_PlayState.m_nSamplesPerTick = static_cast<uint32>((Util::mul32to64_unsigned(m_MixerSettings.gdwMixingFreq, 60 * TEMPO::fractFact) * Util::mul32to64_unsigned(m_PlayState.m_nMusicSpeed, m_PlayState.m_nCurrentRowsPerBeat)) / m_PlayState.m_nMusicTempo.GetRaw());
1548 m_PlayState.m_nSamplesPerTick = static_cast<uint32>((Util::mul32to64_unsigned(m_MixerSettings.gdwMixingFreq, 60 * TEMPO::fractFact) / std::max(uint64(1), Util::mul32to64_unsigned(m_PlayState.m_nMusicSpeed, m_PlayState.m_nCurrentRowsPerBeat) * m_PlayState.m_nMusicTempo.GetRaw())));
15491549 break;
15501550
15511551 case tempoModeAlternative:
1552 m_PlayState.m_nSamplesPerTick = Util::muldiv(m_MixerSettings.gdwMixingFreq, TEMPO::fractFact, m_PlayState.m_nMusicTempo.GetRaw());
1552 m_PlayState.m_nSamplesPerTick = Util::muldiv(m_MixerSettings.gdwMixingFreq, TEMPO::fractFact, std::max(TEMPO::store_t(1), m_PlayState.m_nMusicTempo.GetRaw()));
15531553 break;
15541554 }
15551555 #ifndef MODPLUG_TRACKER
15711571 {
15721572 case tempoModeClassic:
15731573 default:
1574 retval = Util::muldiv(m_MixerSettings.gdwMixingFreq, 5 * TEMPO::fractFact, playState.m_nMusicTempo.GetRaw() << 1);
1574 retval = Util::muldiv(m_MixerSettings.gdwMixingFreq, 5 * TEMPO::fractFact, std::max(TEMPO::store_t(1), playState.m_nMusicTempo.GetRaw() << 1));
15751575 break;
15761576
15771577 case tempoModeAlternative:
1578 retval = Util::muldiv(m_MixerSettings.gdwMixingFreq, TEMPO::fractFact, playState.m_nMusicTempo.GetRaw());
1578 retval = Util::muldiv(m_MixerSettings.gdwMixingFreq, TEMPO::fractFact, std::max(TEMPO::store_t(1), playState.m_nMusicTempo.GetRaw()));
15791579 break;
15801580
15811581 case tempoModeModern:
221221
222222 #ifdef MODPLUG_TRACKER
223223 if(m_SndFile.GetpModDoc())
224 m_SndFile.GetpModDoc()->UpdateAllViews(nullptr, PluginHint(m_nSlot).Info(), nullptr);
224 m_SndFile.GetpModDoc()->UpdateAllViews(nullptr, PluginHint(m_nSlot + 1).Info(), nullptr);
225225 #endif // MODPLUG_TRACKER
226226 }
227227
99 static const char * const license =
1010 "The OpenMPT code is licensed under the BSD license." "\n"
1111 "" "\n"
12 "Copyright (c) 2004-2016, OpenMPT contributors" "\n"
12 "Copyright (c) 2004-2017, OpenMPT contributors" "\n"
1313 "Copyright (c) 1997-2003, Olivier Lapicque" "\n"
1414 "All rights reserved." "\n"
1515 "" "\n"
364364
365365 static void show_info( std::ostream & log, bool verbose ) {
366366 log << "openmpt123" << " v" << OPENMPT123_VERSION_STRING << ", libopenmpt " << openmpt::string::get( "library_version" ) << " (" << "OpenMPT " << openmpt::string::get( "core_version" ) << ")" << std::endl;
367 log << "Copyright (c) 2013-2016 OpenMPT developers <https://lib.openmpt.org/>" << std::endl;
367 log << "Copyright (c) 2013-2017 OpenMPT developers <https://lib.openmpt.org/>" << std::endl;
368368 if ( !verbose ) {
369369 log << std::endl;
370370 return;
423423 static void show_man_version( textout & log ) {
424424 log << "openmpt123" << " v" << OPENMPT123_VERSION_STRING << std::endl;
425425 log << std::endl;
426 log << "Copyright (c) 2013-2016 OpenMPT developers <https://lib.openmpt.org/>" << std::endl;
426 log << "Copyright (c) 2013-2017 OpenMPT developers <https://lib.openmpt.org/>" << std::endl;
427427 }
428428
429429 static void show_short_version( textout & log ) {