libopenmpt_modplug_cpp.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  1. /*
  2. * libopenmpt_modplug_cpp.cpp
  3. * --------------------------
  4. * Purpose: libopenmpt emulation of the libmodplug c++ interface
  5. * Notes : WARNING! THIS IS A HACK!
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. #ifndef NO_LIBMODPLUG
  10. /*
  11. ***********************************************************************
  12. WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
  13. ***********************************************************************
  14. This is a dirty hack to emulate just so much of the libmodplug c++
  15. interface so that the current known users (mainly xmms-modplug itself,
  16. gstreamer modplug, audacious, and stuff based on those) work. This is
  17. neither a complete nor a correct implementation.
  18. Metadata and other state is not provided or updated.
  19. */
  20. #ifdef UNICODE
  21. #undef UNICODE
  22. #endif
  23. #ifdef _UNICODE
  24. #undef _UNICODE
  25. #endif
  26. #ifdef _MSC_VER
  27. #ifndef _CRT_SECURE_NO_WARNINGS
  28. #define _CRT_SECURE_NO_WARNINGS
  29. #endif
  30. #endif /* _MSC_VER */
  31. #include <libopenmpt/libopenmpt.hpp>
  32. #include <string>
  33. #include <vector>
  34. #include <cmath>
  35. #include <cstdio>
  36. #include <cstdlib>
  37. #include <cstring>
  38. #define MODPLUG_BUILD
  39. #ifdef _MSC_VER
  40. /* libmodplug C++ header is broken for MSVC DLL builds */
  41. #define MODPLUG_STATIC
  42. #endif /* _MSC_VER */
  43. #ifdef _MSC_VER
  44. #define LIBOPENMPT_MODPLUG_API
  45. #else /* !_MSC_VER */
  46. #define LIBOPENMPT_MODPLUG_API LIBOPENMPT_API_HELPER_EXPORT
  47. #endif /* _MSC_VER */
  48. class LIBOPENMPT_MODPLUG_API CSoundFile;
  49. #include "libmodplug/stdafx.h"
  50. #include "libmodplug/sndfile.h"
  51. namespace {
  52. template <class T>
  53. void Clear( T & x )
  54. {
  55. std::memset( &x, 0, sizeof(T) );
  56. }
  57. }
  58. //#define mpcpplog() fprintf(stderr, "%s %i\n", __func__, __LINE__)
  59. #define mpcpplog() do{}while(0)
  60. #define UNUSED(x) (void)((x))
  61. union self_t {
  62. CHAR CompressionTable[16];
  63. openmpt::module * self_;
  64. };
  65. static void set_self( CSoundFile * that, openmpt::module * self_ ) {
  66. self_t self_union;
  67. Clear(self_union);
  68. self_union.self_ = self_;
  69. std::memcpy( that->CompressionTable, self_union.CompressionTable, sizeof( self_union.CompressionTable ) );
  70. }
  71. static openmpt::module * get_self( const CSoundFile * that ) {
  72. self_t self_union;
  73. Clear(self_union);
  74. std::memcpy( self_union.CompressionTable, that->CompressionTable, sizeof( self_union.CompressionTable ) );
  75. return self_union.self_;
  76. }
  77. #define mod ( get_self( this ) )
  78. #define update_state() \
  79. if ( mod ) m_nCurrentPattern = mod->get_current_order(); \
  80. if ( mod ) m_nPattern = mod->get_current_pattern(); \
  81. if ( mod ) m_nMusicSpeed = mod->get_current_speed(); \
  82. if ( mod ) m_nMusicTempo = mod->get_current_tempo(); \
  83. /**/
  84. UINT CSoundFile::m_nXBassDepth = 0;
  85. UINT CSoundFile::m_nXBassRange = 0;
  86. UINT CSoundFile::m_nReverbDepth = 0;
  87. UINT CSoundFile::m_nReverbDelay = 0;
  88. UINT CSoundFile::gnReverbType = 0;
  89. UINT CSoundFile::m_nProLogicDepth = 0;
  90. UINT CSoundFile::m_nProLogicDelay = 0;
  91. UINT CSoundFile::m_nStereoSeparation = 128;
  92. UINT CSoundFile::m_nMaxMixChannels = 256;
  93. LONG CSoundFile::m_nStreamVolume = 0x8000;
  94. DWORD CSoundFile::gdwSysInfo = 0;
  95. DWORD CSoundFile::gdwSoundSetup = 0;
  96. DWORD CSoundFile::gdwMixingFreq = 44100;
  97. DWORD CSoundFile::gnBitsPerSample = 16;
  98. DWORD CSoundFile::gnChannels = 2;
  99. UINT CSoundFile::gnAGC = 0;
  100. UINT CSoundFile::gnVolumeRampSamples = 0;
  101. UINT CSoundFile::gnVUMeter = 0;
  102. UINT CSoundFile::gnCPUUsage = 0;
  103. LPSNDMIXHOOKPROC CSoundFile::gpSndMixHook = 0;
  104. PMIXPLUGINCREATEPROC CSoundFile::gpMixPluginCreateProc = 0;
  105. CSoundFile::CSoundFile() {
  106. mpcpplog();
  107. Clear(Chn);
  108. Clear(ChnMix);
  109. Clear(Ins);
  110. Clear(Headers);
  111. Clear(ChnSettings);
  112. Clear(Patterns);
  113. Clear(PatternSize);
  114. Clear(Order);
  115. Clear(m_MidiCfg);
  116. Clear(m_MixPlugins);
  117. Clear(m_nDefaultSpeed);
  118. Clear(m_nDefaultTempo);
  119. Clear(m_nDefaultGlobalVolume);
  120. Clear(m_dwSongFlags);
  121. Clear(m_nChannels);
  122. Clear(m_nMixChannels);
  123. Clear(m_nMixStat);
  124. Clear(m_nBufferCount);
  125. Clear(m_nType);
  126. Clear(m_nSamples);
  127. Clear(m_nInstruments);
  128. Clear(m_nTickCount);
  129. Clear(m_nTotalCount);
  130. Clear(m_nPatternDelay);
  131. Clear(m_nFrameDelay);
  132. Clear(m_nMusicSpeed);
  133. Clear(m_nMusicTempo);
  134. Clear(m_nNextRow);
  135. Clear(m_nRow);
  136. Clear(m_nPattern);
  137. Clear(m_nCurrentPattern);
  138. Clear(m_nNextPattern);
  139. Clear(m_nRestartPos);
  140. Clear(m_nMasterVolume);
  141. Clear(m_nGlobalVolume);
  142. Clear(m_nSongPreAmp);
  143. Clear(m_nFreqFactor);
  144. Clear(m_nTempoFactor);
  145. Clear(m_nOldGlbVolSlide);
  146. Clear(m_nMinPeriod);
  147. Clear(m_nMaxPeriod);
  148. Clear(m_nRepeatCount);
  149. Clear(m_nInitialRepeatCount);
  150. Clear(m_nGlobalFadeSamples);
  151. Clear(m_nGlobalFadeMaxSamples);
  152. Clear(m_nMaxOrderPosition);
  153. Clear(m_nPatternNames);
  154. Clear(m_lpszSongComments);
  155. Clear(m_lpszPatternNames);
  156. Clear(m_szNames);
  157. Clear(CompressionTable);
  158. }
  159. CSoundFile::~CSoundFile() {
  160. mpcpplog();
  161. Destroy();
  162. }
  163. BOOL CSoundFile::Create( LPCBYTE lpStream, DWORD dwMemLength ) {
  164. mpcpplog();
  165. try {
  166. openmpt::module * m = new openmpt::module( lpStream, dwMemLength );
  167. set_self( this, m );
  168. std::strncpy( m_szNames[0], mod->get_metadata("title").c_str(), sizeof( m_szNames[0] ) - 1 );
  169. m_szNames[0][ sizeof( m_szNames[0] ) - 1 ] = '\0';
  170. std::string type = mod->get_metadata("type");
  171. m_nType = MOD_TYPE_NONE;
  172. if ( type == "mod" ) {
  173. m_nType = MOD_TYPE_MOD;
  174. } else if ( type == "s3m" ) {
  175. m_nType = MOD_TYPE_S3M;
  176. } else if ( type == "xm" ) {
  177. m_nType = MOD_TYPE_XM;
  178. } else if ( type == "med" ) {
  179. m_nType = MOD_TYPE_MED;
  180. } else if ( type == "mtm" ) {
  181. m_nType = MOD_TYPE_MTM;
  182. } else if ( type == "it" ) {
  183. m_nType = MOD_TYPE_IT;
  184. } else if ( type == "669" ) {
  185. m_nType = MOD_TYPE_669;
  186. } else if ( type == "ult" ) {
  187. m_nType = MOD_TYPE_ULT;
  188. } else if ( type == "stm" ) {
  189. m_nType = MOD_TYPE_STM;
  190. } else if ( type == "far" ) {
  191. m_nType = MOD_TYPE_FAR;
  192. } else if ( type == "s3m" ) {
  193. m_nType = MOD_TYPE_WAV;
  194. } else if ( type == "amf" ) {
  195. m_nType = MOD_TYPE_AMF;
  196. } else if ( type == "ams" ) {
  197. m_nType = MOD_TYPE_AMS;
  198. } else if ( type == "dsm" ) {
  199. m_nType = MOD_TYPE_DSM;
  200. } else if ( type == "mdl" ) {
  201. m_nType = MOD_TYPE_MDL;
  202. } else if ( type == "okt" ) {
  203. m_nType = MOD_TYPE_OKT;
  204. } else if ( type == "mid" ) {
  205. m_nType = MOD_TYPE_MID;
  206. } else if ( type == "dmf" ) {
  207. m_nType = MOD_TYPE_DMF;
  208. } else if ( type == "ptm" ) {
  209. m_nType = MOD_TYPE_PTM;
  210. } else if ( type == "dbm" ) {
  211. m_nType = MOD_TYPE_DBM;
  212. } else if ( type == "mt2" ) {
  213. m_nType = MOD_TYPE_MT2;
  214. } else if ( type == "amf0" ) {
  215. m_nType = MOD_TYPE_AMF0;
  216. } else if ( type == "psm" ) {
  217. m_nType = MOD_TYPE_PSM;
  218. } else if ( type == "j2b" ) {
  219. m_nType = MOD_TYPE_J2B;
  220. } else if ( type == "abc" ) {
  221. m_nType = MOD_TYPE_ABC;
  222. } else if ( type == "pat" ) {
  223. m_nType = MOD_TYPE_PAT;
  224. } else if ( type == "umx" ) {
  225. m_nType = MOD_TYPE_UMX;
  226. } else {
  227. m_nType = MOD_TYPE_IT; // fallback, most complex type
  228. }
  229. m_nChannels = mod->get_num_channels();
  230. m_nMasterVolume = 128;
  231. m_nSamples = mod->get_num_samples();
  232. update_state();
  233. return TRUE;
  234. } catch ( ... ) {
  235. Destroy();
  236. return FALSE;
  237. }
  238. }
  239. BOOL CSoundFile::Destroy() {
  240. mpcpplog();
  241. if ( mod ) {
  242. delete mod;
  243. set_self( this, 0 );
  244. }
  245. return TRUE;
  246. }
  247. UINT CSoundFile::GetNumChannels() const {
  248. mpcpplog();
  249. return mod->get_num_channels();
  250. }
  251. static std::int32_t vol128_To_millibel( unsigned int vol ) {
  252. return static_cast<std::int32_t>( 2000.0 * std::log10( static_cast<int>( vol ) / 128.0 ) );
  253. }
  254. BOOL CSoundFile::SetMasterVolume( UINT vol, BOOL bAdjustAGC ) {
  255. UNUSED(bAdjustAGC);
  256. mpcpplog();
  257. m_nMasterVolume = vol;
  258. mod->set_render_param( openmpt::module::RENDER_MASTERGAIN_MILLIBEL, vol128_To_millibel( m_nMasterVolume ) );
  259. return TRUE;
  260. }
  261. UINT CSoundFile::GetNumPatterns() const {
  262. mpcpplog();
  263. return mod->get_num_patterns();
  264. }
  265. UINT CSoundFile::GetNumInstruments() const {
  266. mpcpplog();
  267. return mod->get_num_instruments();
  268. }
  269. void CSoundFile::SetCurrentOrder( UINT nOrder ) {
  270. mpcpplog();
  271. mod->set_position_order_row( nOrder, 0 );
  272. update_state();
  273. }
  274. UINT CSoundFile::GetSampleName( UINT nSample, LPSTR s ) const {
  275. mpcpplog();
  276. char buf[32];
  277. std::memset( buf, 0, 32 );
  278. if ( mod ) {
  279. std::vector<std::string> names = mod->get_sample_names();
  280. if ( 1 <= nSample && nSample <= names.size() ) {
  281. std::strncpy( buf, names[ nSample - 1 ].c_str(), 31 );
  282. }
  283. }
  284. if ( s ) {
  285. std::strncpy( s, buf, 32 );
  286. }
  287. return static_cast<UINT>( std::strlen( buf ) );
  288. }
  289. UINT CSoundFile::GetInstrumentName( UINT nInstr, LPSTR s ) const {
  290. mpcpplog();
  291. char buf[32];
  292. std::memset( buf, 0, 32 );
  293. if ( mod ) {
  294. std::vector<std::string> names = mod->get_instrument_names();
  295. if ( 1 <= nInstr && nInstr <= names.size() ) {
  296. std::strncpy( buf, names[ nInstr - 1 ].c_str(), 31 );
  297. }
  298. }
  299. if ( s ) {
  300. std::strncpy( s, buf, 32 );
  301. }
  302. return static_cast<UINT>( std::strlen( buf ) );
  303. }
  304. void CSoundFile::LoopPattern( int nPat, int nRow ) {
  305. UNUSED(nPat);
  306. UNUSED(nRow);
  307. mpcpplog();
  308. // todo
  309. }
  310. void CSoundFile::CheckCPUUsage( UINT nCPU ) {
  311. UNUSED(nCPU);
  312. mpcpplog();
  313. }
  314. BOOL CSoundFile::SetPatternName( UINT nPat, LPCSTR lpszName ) {
  315. UNUSED(nPat);
  316. mpcpplog();
  317. if ( !lpszName ) {
  318. return FALSE;
  319. }
  320. // todo
  321. return TRUE;
  322. }
  323. BOOL CSoundFile::GetPatternName( UINT nPat, LPSTR lpszName, UINT cbSize ) const {
  324. UNUSED(nPat);
  325. mpcpplog();
  326. if ( !lpszName || cbSize <= 0 ) {
  327. return FALSE;
  328. }
  329. std::memset( lpszName, 0, cbSize );
  330. // todo
  331. return TRUE;
  332. }
  333. BOOL CSoundFile::ReadXM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  334. BOOL CSoundFile::ReadS3M(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  335. BOOL CSoundFile::ReadMod(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  336. BOOL CSoundFile::ReadMed(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  337. BOOL CSoundFile::ReadMTM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  338. BOOL CSoundFile::ReadSTM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  339. BOOL CSoundFile::ReadIT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  340. BOOL CSoundFile::Read669(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  341. BOOL CSoundFile::ReadUlt(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  342. BOOL CSoundFile::ReadWav(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  343. BOOL CSoundFile::ReadDSM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  344. BOOL CSoundFile::ReadFAR(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  345. BOOL CSoundFile::ReadAMS(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  346. BOOL CSoundFile::ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  347. BOOL CSoundFile::ReadMDL(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  348. BOOL CSoundFile::ReadOKT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  349. BOOL CSoundFile::ReadDMF(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  350. BOOL CSoundFile::ReadPTM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  351. BOOL CSoundFile::ReadDBM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  352. BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  353. BOOL CSoundFile::ReadMT2(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  354. BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  355. BOOL CSoundFile::ReadJ2B(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  356. BOOL CSoundFile::ReadUMX(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  357. BOOL CSoundFile::ReadABC(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  358. BOOL CSoundFile::TestABC(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  359. BOOL CSoundFile::ReadMID(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  360. BOOL CSoundFile::TestMID(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  361. BOOL CSoundFile::ReadPAT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  362. BOOL CSoundFile::TestPAT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; }
  363. #ifndef MODPLUG_NO_FILESAVE
  364. UINT CSoundFile::WriteSample( FILE * f, MODINSTRUMENT * pins, UINT nFlags, UINT nMaxLen ) {
  365. UNUSED(f);
  366. UNUSED(pins);
  367. UNUSED(nFlags);
  368. UNUSED(nMaxLen);
  369. mpcpplog();
  370. return 0;
  371. }
  372. BOOL CSoundFile::SaveXM( LPCSTR lpszFileName, UINT nPacking ) {
  373. UNUSED(lpszFileName);
  374. UNUSED(nPacking);
  375. mpcpplog();
  376. return FALSE;
  377. }
  378. BOOL CSoundFile::SaveS3M( LPCSTR lpszFileName, UINT nPacking ) {
  379. UNUSED(lpszFileName);
  380. UNUSED(nPacking);
  381. mpcpplog();
  382. return FALSE;
  383. }
  384. BOOL CSoundFile::SaveMod( LPCSTR lpszFileName, UINT nPacking ) {
  385. UNUSED(lpszFileName);
  386. UNUSED(nPacking);
  387. mpcpplog();
  388. return FALSE;
  389. }
  390. BOOL CSoundFile::SaveIT( LPCSTR lpszFileName, UINT nPacking ) {
  391. UNUSED(lpszFileName);
  392. UNUSED(nPacking);
  393. mpcpplog();
  394. return FALSE;
  395. }
  396. #endif
  397. UINT CSoundFile::GetBestSaveFormat() const {
  398. mpcpplog();
  399. return MOD_TYPE_IT;
  400. }
  401. UINT CSoundFile::GetSaveFormats() const {
  402. mpcpplog();
  403. return MOD_TYPE_IT;
  404. }
  405. void CSoundFile::ConvertModCommand( MODCOMMAND * ) const {
  406. mpcpplog();
  407. }
  408. void CSoundFile::S3MConvert( MODCOMMAND * m, BOOL bIT ) const {
  409. UNUSED(m);
  410. UNUSED(bIT);
  411. mpcpplog();
  412. }
  413. void CSoundFile::S3MSaveConvert( UINT * pcmd, UINT * pprm, BOOL bIT ) const {
  414. UNUSED(pcmd);
  415. UNUSED(pprm);
  416. UNUSED(bIT);
  417. mpcpplog();
  418. }
  419. WORD CSoundFile::ModSaveCommand( const MODCOMMAND * m, BOOL bXM ) const {
  420. UNUSED(m);
  421. UNUSED(bXM);
  422. mpcpplog();
  423. return 0;
  424. }
  425. VOID CSoundFile::ResetChannels() {
  426. mpcpplog();
  427. }
  428. UINT CSoundFile::CreateStereoMix( int count ) {
  429. UNUSED(count);
  430. mpcpplog();
  431. return 0;
  432. }
  433. BOOL CSoundFile::FadeSong( UINT msec ) {
  434. UNUSED(msec);
  435. mpcpplog();
  436. return TRUE;
  437. }
  438. BOOL CSoundFile::GlobalFadeSong( UINT msec ) {
  439. UNUSED(msec);
  440. mpcpplog();
  441. return TRUE;
  442. }
  443. BOOL CSoundFile::InitPlayer( BOOL bReset ) {
  444. UNUSED(bReset);
  445. mpcpplog();
  446. return TRUE;
  447. }
  448. BOOL CSoundFile::SetMixConfig( UINT nStereoSeparation, UINT nMaxMixChannels ) {
  449. UNUSED(nMaxMixChannels);
  450. mpcpplog();
  451. m_nStereoSeparation = nStereoSeparation;
  452. return TRUE;
  453. }
  454. DWORD CSoundFile::InitSysInfo() {
  455. mpcpplog();
  456. return 0;
  457. }
  458. void CSoundFile::SetAGC( BOOL b ) {
  459. UNUSED(b);
  460. mpcpplog();
  461. }
  462. void CSoundFile::ResetAGC() {
  463. mpcpplog();
  464. }
  465. void CSoundFile::ProcessAGC( int count ) {
  466. UNUSED(count);
  467. mpcpplog();
  468. }
  469. BOOL CSoundFile::SetWaveConfig( UINT nRate, UINT nBits, UINT nChannels, BOOL bMMX ) {
  470. UNUSED(bMMX);
  471. mpcpplog();
  472. gdwMixingFreq = nRate;
  473. gnBitsPerSample = nBits;
  474. gnChannels = nChannels;
  475. return TRUE;
  476. }
  477. BOOL CSoundFile::SetWaveConfigEx( BOOL bSurround, BOOL bNoOverSampling, BOOL bReverb, BOOL hqido, BOOL bMegaBass, BOOL bNR, BOOL bEQ ) {
  478. UNUSED(bSurround);
  479. UNUSED(bReverb);
  480. UNUSED(hqido);
  481. UNUSED(bMegaBass);
  482. UNUSED(bEQ);
  483. mpcpplog();
  484. DWORD d = gdwSoundSetup & ~(SNDMIX_NORESAMPLING|SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE);
  485. if ( bNoOverSampling ) {
  486. d |= SNDMIX_NORESAMPLING;
  487. } else if ( !hqido ) {
  488. d |= 0;
  489. } else if ( !bNR ) {
  490. d |= SNDMIX_HQRESAMPLER;
  491. } else {
  492. d |= (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE);
  493. }
  494. gdwSoundSetup = d;
  495. return TRUE;
  496. }
  497. BOOL CSoundFile::SetResamplingMode( UINT nMode ) {
  498. mpcpplog();
  499. DWORD d = gdwSoundSetup & ~(SNDMIX_NORESAMPLING|SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE);
  500. switch ( nMode ) {
  501. case SRCMODE_NEAREST:
  502. d |= SNDMIX_NORESAMPLING;
  503. break;
  504. case SRCMODE_LINEAR:
  505. break;
  506. case SRCMODE_SPLINE:
  507. d |= SNDMIX_HQRESAMPLER;
  508. break;
  509. case SRCMODE_POLYPHASE:
  510. d |= (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE);
  511. break;
  512. default:
  513. return FALSE;
  514. break;
  515. }
  516. gdwSoundSetup = d;
  517. return TRUE;
  518. }
  519. BOOL CSoundFile::SetReverbParameters( UINT nDepth, UINT nDelay ) {
  520. UNUSED(nDepth);
  521. UNUSED(nDelay);
  522. mpcpplog();
  523. return TRUE;
  524. }
  525. BOOL CSoundFile::SetXBassParameters( UINT nDepth, UINT nRange ) {
  526. UNUSED(nDepth);
  527. UNUSED(nRange);
  528. mpcpplog();
  529. return TRUE;
  530. }
  531. BOOL CSoundFile::SetSurroundParameters( UINT nDepth, UINT nDelay ) {
  532. UNUSED(nDepth);
  533. UNUSED(nDelay);
  534. mpcpplog();
  535. return TRUE;
  536. }
  537. UINT CSoundFile::GetMaxPosition() const {
  538. mpcpplog();
  539. // rows in original, just use seconds here
  540. if ( mod ) return static_cast<UINT>( mod->get_duration_seconds() + 0.5 );
  541. return 0;
  542. }
  543. DWORD CSoundFile::GetLength( BOOL bAdjust, BOOL bTotal ) {
  544. UNUSED(bAdjust);
  545. UNUSED(bTotal);
  546. mpcpplog();
  547. if ( mod ) return static_cast<DWORD>( mod->get_duration_seconds() + 0.5 );
  548. return 0;
  549. }
  550. UINT CSoundFile::GetSongComments( LPSTR s, UINT cbsize, UINT linesize ) {
  551. UNUSED(linesize);
  552. mpcpplog();
  553. if ( !s ) {
  554. return 0;
  555. }
  556. if ( cbsize <= 0 ) {
  557. return 0;
  558. }
  559. if ( !mod ) {
  560. s[0] = '\0';
  561. return 1;
  562. }
  563. std::strncpy( s, mod->get_metadata("message").c_str(), cbsize );
  564. s[ cbsize - 1 ] = '\0';
  565. return static_cast<UINT>( std::strlen( s ) + 1 );
  566. }
  567. UINT CSoundFile::GetRawSongComments( LPSTR s, UINT cbsize, UINT linesize ) {
  568. UNUSED(linesize);
  569. mpcpplog();
  570. if ( !s ) {
  571. return 0;
  572. }
  573. if ( cbsize <= 0 ) {
  574. return 0;
  575. }
  576. if ( !mod ) {
  577. s[0] = '\0';
  578. return 1;
  579. }
  580. std::strncpy( s, mod->get_metadata("message_raw").c_str(), cbsize );
  581. s[ cbsize - 1 ] = '\0';
  582. return static_cast<UINT>( std::strlen( s ) + 1 );
  583. }
  584. void CSoundFile::SetCurrentPos( UINT nPos ) {
  585. mpcpplog();
  586. if ( mod ) mod->set_position_seconds( nPos );
  587. update_state();
  588. }
  589. UINT CSoundFile::GetCurrentPos() const {
  590. mpcpplog();
  591. if ( mod ) return static_cast<UINT>( mod->get_position_seconds() + 0.5 );
  592. return 0;
  593. }
  594. static int get_stereo_separation() {
  595. mpcpplog();
  596. return CSoundFile::m_nStereoSeparation * 100 / 128;
  597. }
  598. static int get_filter_length() {
  599. mpcpplog();
  600. if ( ( CSoundFile::gdwSoundSetup & (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE) ) == (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE) ) {
  601. return 8;
  602. } else if ( ( CSoundFile::gdwSoundSetup & SNDMIX_HQRESAMPLER ) == SNDMIX_HQRESAMPLER ) {
  603. return 4;
  604. } else if ( ( CSoundFile::gdwSoundSetup & SNDMIX_NORESAMPLING ) == SNDMIX_NORESAMPLING ) {
  605. return 1;
  606. } else {
  607. return 2;
  608. }
  609. }
  610. static std::size_t get_sample_size() {
  611. return (CSoundFile::gnBitsPerSample/8);
  612. }
  613. static std::size_t get_num_channels() {
  614. return CSoundFile::gnChannels;
  615. }
  616. static std::size_t get_frame_size() {
  617. return get_sample_size() * get_num_channels();
  618. }
  619. static int get_samplerate() {
  620. return CSoundFile::gdwMixingFreq;
  621. }
  622. UINT CSoundFile::Read( LPVOID lpBuffer, UINT cbBuffer ) {
  623. mpcpplog();
  624. if ( !mod ) {
  625. return 0;
  626. }
  627. mpcpplog();
  628. if ( !lpBuffer ) {
  629. return 0;
  630. }
  631. mpcpplog();
  632. if ( cbBuffer <= 0 ) {
  633. return 0;
  634. }
  635. mpcpplog();
  636. if ( get_samplerate() <= 0 ) {
  637. return 0;
  638. }
  639. mpcpplog();
  640. if ( get_sample_size() != 1 && get_sample_size() != 2 && get_sample_size() != 4 ) {
  641. return 0;
  642. }
  643. mpcpplog();
  644. if ( get_num_channels() != 1 && get_num_channels() != 2 && get_num_channels() != 4 ) {
  645. return 0;
  646. }
  647. mpcpplog();
  648. std::memset( lpBuffer, 0, cbBuffer );
  649. const std::size_t frames_torender = cbBuffer / get_frame_size();
  650. short * out = reinterpret_cast<short*>( lpBuffer );
  651. std::vector<short> tmpbuf;
  652. if ( get_sample_size() == 1 || get_sample_size() == 4 ) {
  653. tmpbuf.resize( frames_torender * get_num_channels() );
  654. out = &tmpbuf[0];
  655. }
  656. mod->set_render_param( openmpt::module::RENDER_STEREOSEPARATION_PERCENT, get_stereo_separation() );
  657. mod->set_render_param( openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH, get_filter_length() );
  658. std::size_t frames_rendered = 0;
  659. if ( get_num_channels() == 1 ) {
  660. frames_rendered = mod->read( get_samplerate(), frames_torender, out );
  661. } else if ( get_num_channels() == 4 ) {
  662. frames_rendered = mod->read_interleaved_quad( get_samplerate(), frames_torender, out );
  663. } else {
  664. frames_rendered = mod->read_interleaved_stereo( get_samplerate(), frames_torender, out );
  665. }
  666. if ( get_sample_size() == 1 ) {
  667. unsigned char * dst = reinterpret_cast<unsigned char*>( lpBuffer );
  668. for ( std::size_t sample = 0; sample < frames_rendered * get_num_channels(); ++sample ) {
  669. dst[sample] = ( tmpbuf[sample] / 0x100 ) + 0x80;
  670. }
  671. } else if ( get_sample_size() == 4 ) {
  672. int * dst = reinterpret_cast<int*>( lpBuffer );
  673. for ( std::size_t sample = 0; sample < frames_rendered * get_num_channels(); ++sample ) {
  674. dst[sample] = tmpbuf[sample] << (32-16-1-MIXING_ATTENUATION);
  675. }
  676. }
  677. update_state();
  678. return static_cast<UINT>( frames_rendered );
  679. }
  680. /*
  681. gstreamer modplug calls:
  682. mSoundFile->Create
  683. mSoundFile->Destroy
  684. mSoundFile->SetWaveConfig
  685. mSoundFile->SetWaveConfigEx
  686. mSoundFile->SetResamplingMode
  687. mSoundFile->SetSurroundParameters
  688. mSoundFile->SetXBassParameters
  689. mSoundFile->SetReverbParameters
  690. mSoundFile->GetMaxPosition (inline, -> GetLength)
  691. mSoundFile->GetSongTime
  692. mSoundFile->GetTitle (inline)
  693. mSoundFile->GetSongComments
  694. mSoundFile->SetCurrentPos
  695. mSoundFile->Read
  696. mSoundFile->GetCurrentPos
  697. mSoundFile->GetMusicTempo (inline)
  698. */
  699. // really very internal symbols, probably nothing calls these directly
  700. #if defined(__clang__)
  701. #pragma clang diagnostic push
  702. #pragma clang diagnostic ignored "-Wunknown-pragmas"
  703. #pragma clang diagnostic ignored "-Wunused-parameter"
  704. #elif defined(__GNUC__)
  705. #pragma GCC diagnostic push
  706. #pragma GCC diagnostic ignored "-Wunknown-pragmas"
  707. #pragma GCC diagnostic ignored "-Wunused-parameter"
  708. #elif defined(_MSC_VER)
  709. #pragma warning(push)
  710. #pragma warning(disable:4100)
  711. #endif
  712. BOOL CSoundFile::ReadNote() { mpcpplog(); return 0; }
  713. BOOL CSoundFile::ProcessRow() { mpcpplog(); return 0; }
  714. BOOL CSoundFile::ProcessEffects() { mpcpplog(); return 0; }
  715. UINT CSoundFile::GetNNAChannel(UINT nChn) const { mpcpplog(); return 0; }
  716. void CSoundFile::CheckNNA(UINT nChn, UINT instr, int note, BOOL bForceCut) { mpcpplog(); }
  717. void CSoundFile::NoteChange(UINT nChn, int note, BOOL bPorta, BOOL bResetEnv) { mpcpplog(); }
  718. void CSoundFile::InstrumentChange(MODCHANNEL *pChn, UINT instr, BOOL bPorta,BOOL bUpdVol,BOOL bResetEnv) { mpcpplog(); }
  719. void CSoundFile::PortamentoUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  720. void CSoundFile::PortamentoDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  721. void CSoundFile::FinePortamentoUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  722. void CSoundFile::FinePortamentoDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  723. void CSoundFile::ExtraFinePortamentoUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  724. void CSoundFile::ExtraFinePortamentoDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  725. void CSoundFile::TonePortamento(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  726. void CSoundFile::Vibrato(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  727. void CSoundFile::FineVibrato(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  728. void CSoundFile::VolumeSlide(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  729. void CSoundFile::PanningSlide(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  730. void CSoundFile::ChannelVolSlide(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  731. void CSoundFile::FineVolumeUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  732. void CSoundFile::FineVolumeDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  733. void CSoundFile::Tremolo(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  734. void CSoundFile::Panbrello(MODCHANNEL *pChn, UINT param) { mpcpplog(); }
  735. void CSoundFile::RetrigNote(UINT nChn, UINT param) { mpcpplog(); }
  736. void CSoundFile::NoteCut(UINT nChn, UINT nTick) { mpcpplog(); }
  737. void CSoundFile::KeyOff(UINT nChn) { mpcpplog(); }
  738. int CSoundFile::PatternLoop(MODCHANNEL *, UINT param) { mpcpplog(); return 0; }
  739. void CSoundFile::ExtendedMODCommands(UINT nChn, UINT param) { mpcpplog(); }
  740. void CSoundFile::ExtendedS3MCommands(UINT nChn, UINT param) { mpcpplog(); }
  741. void CSoundFile::ExtendedChannelEffect(MODCHANNEL *, UINT param) { mpcpplog(); }
  742. void CSoundFile::ProcessMidiMacro(UINT nChn, LPCSTR pszMidiMacro, UINT param) { mpcpplog(); }
  743. void CSoundFile::SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier) const { mpcpplog(); }
  744. void CSoundFile::DoFreqSlide(MODCHANNEL *pChn, LONG nFreqSlide) { mpcpplog(); }
  745. void CSoundFile::SetTempo(UINT param) { mpcpplog(); }
  746. void CSoundFile::SetSpeed(UINT param) { mpcpplog(); }
  747. void CSoundFile::GlobalVolSlide(UINT param) { mpcpplog(); }
  748. DWORD CSoundFile::IsSongFinished(UINT nOrder, UINT nRow) const { mpcpplog(); return 0; }
  749. BOOL CSoundFile::IsValidBackwardJump(UINT nStartOrder, UINT nStartRow, UINT nJumpOrder, UINT nJumpRow) const { mpcpplog(); return 0; }
  750. UINT CSoundFile::PackSample(int &sample, int next) { mpcpplog(); return 0; }
  751. BOOL CSoundFile::CanPackSample(LPSTR pSample, UINT nLen, UINT nPacking, BYTE *result) { mpcpplog(); return 0; }
  752. UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR pMemFile, DWORD dwMemLength) { mpcpplog(); return 0; }
  753. BOOL CSoundFile::DestroySample(UINT nSample) { mpcpplog(); return 0; }
  754. BOOL CSoundFile::DestroyInstrument(UINT nInstr) { mpcpplog(); return 0; }
  755. BOOL CSoundFile::IsSampleUsed(UINT nSample) { mpcpplog(); return 0; }
  756. BOOL CSoundFile::IsInstrumentUsed(UINT nInstr) { mpcpplog(); return 0; }
  757. BOOL CSoundFile::RemoveInstrumentSamples(UINT nInstr) { mpcpplog(); return 0; }
  758. UINT CSoundFile::DetectUnusedSamples(BOOL *) { mpcpplog(); return 0; }
  759. BOOL CSoundFile::RemoveSelectedSamples(BOOL *) { mpcpplog(); return 0; }
  760. void CSoundFile::AdjustSampleLoop(MODINSTRUMENT *pIns) { mpcpplog(); }
  761. BOOL CSoundFile::ReadInstrumentFromSong(UINT nInstr, CSoundFile *, UINT nSrcInstrument) { mpcpplog(); return 0; }
  762. BOOL CSoundFile::ReadSampleFromSong(UINT nSample, CSoundFile *, UINT nSrcSample) { mpcpplog(); return 0; }
  763. UINT CSoundFile::GetNoteFromPeriod(UINT period) const { mpcpplog(); return 0; }
  764. UINT CSoundFile::GetPeriodFromNote(UINT note, int nFineTune, UINT nC4Speed) const { mpcpplog(); return 0; }
  765. UINT CSoundFile::GetFreqFromPeriod(UINT period, UINT nC4Speed, int nPeriodFrac) const { mpcpplog(); return 0; }
  766. void CSoundFile::ResetMidiCfg() { mpcpplog(); }
  767. UINT CSoundFile::MapMidiInstrument(DWORD dwProgram, UINT nChannel, UINT nNote) { mpcpplog(); return 0; }
  768. BOOL CSoundFile::ITInstrToMPT(const void *p, INSTRUMENTHEADER *penv, UINT trkvers) { mpcpplog(); return 0; }
  769. UINT CSoundFile::SaveMixPlugins(FILE *f, BOOL bUpdate) { mpcpplog(); return 0; }
  770. UINT CSoundFile::LoadMixPlugins(const void *pData, UINT nLen) { mpcpplog(); return 0; }
  771. #ifndef NO_FILTER
  772. DWORD CSoundFile::CutOffToFrequency(UINT nCutOff, int flt_modifier) const { mpcpplog(); return 0; }
  773. #endif
  774. DWORD CSoundFile::TransposeToFrequency(int transp, int ftune) { mpcpplog(); return 0; }
  775. int CSoundFile::FrequencyToTranspose(DWORD freq) { mpcpplog(); return 0; }
  776. void CSoundFile::FrequencyToTranspose(MODINSTRUMENT *psmp) { mpcpplog(); }
  777. MODCOMMAND *CSoundFile::AllocatePattern(UINT rows, UINT nchns) { mpcpplog(); return 0; }
  778. signed char* CSoundFile::AllocateSample(UINT nbytes) { mpcpplog(); return 0; }
  779. void CSoundFile::FreePattern(LPVOID pat) { mpcpplog(); }
  780. void CSoundFile::FreeSample(LPVOID p) { mpcpplog(); }
  781. UINT CSoundFile::Normalize24BitBuffer(LPBYTE pbuffer, UINT cbsizebytes, DWORD lmax24, DWORD dwByteInc) { mpcpplog(); return 0; }
  782. #if defined(__clang__)
  783. #pragma clang diagnostic pop
  784. #elif defined(__GNUC__)
  785. #pragma GCC diagnostic pop
  786. #elif defined(_MSC_VER)
  787. #pragma warning(pop)
  788. #endif
  789. #endif // NO_LIBMODPLUG