/* * libopenmpt_modplug_cpp.cpp * -------------------------- * Purpose: libopenmpt emulation of the libmodplug c++ interface * Notes : WARNING! THIS IS A HACK! * Authors: OpenMPT Devs * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. */ #ifndef NO_LIBMODPLUG /* *********************************************************************** WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING *********************************************************************** This is a dirty hack to emulate just so much of the libmodplug c++ interface so that the current known users (mainly xmms-modplug itself, gstreamer modplug, audacious, and stuff based on those) work. This is neither a complete nor a correct implementation. Metadata and other state is not provided or updated. */ #ifdef UNICODE #undef UNICODE #endif #ifdef _UNICODE #undef _UNICODE #endif #ifdef _MSC_VER #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #endif #endif /* _MSC_VER */ #include #include #include #include #include #include #include #define MODPLUG_BUILD #ifdef _MSC_VER /* libmodplug C++ header is broken for MSVC DLL builds */ #define MODPLUG_STATIC #endif /* _MSC_VER */ #ifdef _MSC_VER #define LIBOPENMPT_MODPLUG_API #else /* !_MSC_VER */ #define LIBOPENMPT_MODPLUG_API LIBOPENMPT_API_HELPER_EXPORT #endif /* _MSC_VER */ class LIBOPENMPT_MODPLUG_API CSoundFile; #include "libmodplug/stdafx.h" #include "libmodplug/sndfile.h" namespace { template void Clear( T & x ) { std::memset( &x, 0, sizeof(T) ); } } //#define mpcpplog() fprintf(stderr, "%s %i\n", __func__, __LINE__) #define mpcpplog() do{}while(0) #define UNUSED(x) (void)((x)) union self_t { CHAR CompressionTable[16]; openmpt::module * self_; }; static void set_self( CSoundFile * that, openmpt::module * self_ ) { self_t self_union; Clear(self_union); self_union.self_ = self_; std::memcpy( that->CompressionTable, self_union.CompressionTable, sizeof( self_union.CompressionTable ) ); } static openmpt::module * get_self( const CSoundFile * that ) { self_t self_union; Clear(self_union); std::memcpy( self_union.CompressionTable, that->CompressionTable, sizeof( self_union.CompressionTable ) ); return self_union.self_; } #define mod ( get_self( this ) ) #define update_state() \ if ( mod ) m_nCurrentPattern = mod->get_current_order(); \ if ( mod ) m_nPattern = mod->get_current_pattern(); \ if ( mod ) m_nMusicSpeed = mod->get_current_speed(); \ if ( mod ) m_nMusicTempo = mod->get_current_tempo(); \ /**/ UINT CSoundFile::m_nXBassDepth = 0; UINT CSoundFile::m_nXBassRange = 0; UINT CSoundFile::m_nReverbDepth = 0; UINT CSoundFile::m_nReverbDelay = 0; UINT CSoundFile::gnReverbType = 0; UINT CSoundFile::m_nProLogicDepth = 0; UINT CSoundFile::m_nProLogicDelay = 0; UINT CSoundFile::m_nStereoSeparation = 128; UINT CSoundFile::m_nMaxMixChannels = 256; LONG CSoundFile::m_nStreamVolume = 0x8000; DWORD CSoundFile::gdwSysInfo = 0; DWORD CSoundFile::gdwSoundSetup = 0; DWORD CSoundFile::gdwMixingFreq = 44100; DWORD CSoundFile::gnBitsPerSample = 16; DWORD CSoundFile::gnChannels = 2; UINT CSoundFile::gnAGC = 0; UINT CSoundFile::gnVolumeRampSamples = 0; UINT CSoundFile::gnVUMeter = 0; UINT CSoundFile::gnCPUUsage = 0; LPSNDMIXHOOKPROC CSoundFile::gpSndMixHook = 0; PMIXPLUGINCREATEPROC CSoundFile::gpMixPluginCreateProc = 0; CSoundFile::CSoundFile() { mpcpplog(); Clear(Chn); Clear(ChnMix); Clear(Ins); Clear(Headers); Clear(ChnSettings); Clear(Patterns); Clear(PatternSize); Clear(Order); Clear(m_MidiCfg); Clear(m_MixPlugins); Clear(m_nDefaultSpeed); Clear(m_nDefaultTempo); Clear(m_nDefaultGlobalVolume); Clear(m_dwSongFlags); Clear(m_nChannels); Clear(m_nMixChannels); Clear(m_nMixStat); Clear(m_nBufferCount); Clear(m_nType); Clear(m_nSamples); Clear(m_nInstruments); Clear(m_nTickCount); Clear(m_nTotalCount); Clear(m_nPatternDelay); Clear(m_nFrameDelay); Clear(m_nMusicSpeed); Clear(m_nMusicTempo); Clear(m_nNextRow); Clear(m_nRow); Clear(m_nPattern); Clear(m_nCurrentPattern); Clear(m_nNextPattern); Clear(m_nRestartPos); Clear(m_nMasterVolume); Clear(m_nGlobalVolume); Clear(m_nSongPreAmp); Clear(m_nFreqFactor); Clear(m_nTempoFactor); Clear(m_nOldGlbVolSlide); Clear(m_nMinPeriod); Clear(m_nMaxPeriod); Clear(m_nRepeatCount); Clear(m_nInitialRepeatCount); Clear(m_nGlobalFadeSamples); Clear(m_nGlobalFadeMaxSamples); Clear(m_nMaxOrderPosition); Clear(m_nPatternNames); Clear(m_lpszSongComments); Clear(m_lpszPatternNames); Clear(m_szNames); Clear(CompressionTable); } CSoundFile::~CSoundFile() { mpcpplog(); Destroy(); } BOOL CSoundFile::Create( LPCBYTE lpStream, DWORD dwMemLength ) { mpcpplog(); try { openmpt::module * m = new openmpt::module( lpStream, dwMemLength ); set_self( this, m ); std::strncpy( m_szNames[0], mod->get_metadata("title").c_str(), sizeof( m_szNames[0] ) - 1 ); m_szNames[0][ sizeof( m_szNames[0] ) - 1 ] = '\0'; std::string type = mod->get_metadata("type"); m_nType = MOD_TYPE_NONE; if ( type == "mod" ) { m_nType = MOD_TYPE_MOD; } else if ( type == "s3m" ) { m_nType = MOD_TYPE_S3M; } else if ( type == "xm" ) { m_nType = MOD_TYPE_XM; } else if ( type == "med" ) { m_nType = MOD_TYPE_MED; } else if ( type == "mtm" ) { m_nType = MOD_TYPE_MTM; } else if ( type == "it" ) { m_nType = MOD_TYPE_IT; } else if ( type == "669" ) { m_nType = MOD_TYPE_669; } else if ( type == "ult" ) { m_nType = MOD_TYPE_ULT; } else if ( type == "stm" ) { m_nType = MOD_TYPE_STM; } else if ( type == "far" ) { m_nType = MOD_TYPE_FAR; } else if ( type == "s3m" ) { m_nType = MOD_TYPE_WAV; } else if ( type == "amf" ) { m_nType = MOD_TYPE_AMF; } else if ( type == "ams" ) { m_nType = MOD_TYPE_AMS; } else if ( type == "dsm" ) { m_nType = MOD_TYPE_DSM; } else if ( type == "mdl" ) { m_nType = MOD_TYPE_MDL; } else if ( type == "okt" ) { m_nType = MOD_TYPE_OKT; } else if ( type == "mid" ) { m_nType = MOD_TYPE_MID; } else if ( type == "dmf" ) { m_nType = MOD_TYPE_DMF; } else if ( type == "ptm" ) { m_nType = MOD_TYPE_PTM; } else if ( type == "dbm" ) { m_nType = MOD_TYPE_DBM; } else if ( type == "mt2" ) { m_nType = MOD_TYPE_MT2; } else if ( type == "amf0" ) { m_nType = MOD_TYPE_AMF0; } else if ( type == "psm" ) { m_nType = MOD_TYPE_PSM; } else if ( type == "j2b" ) { m_nType = MOD_TYPE_J2B; } else if ( type == "abc" ) { m_nType = MOD_TYPE_ABC; } else if ( type == "pat" ) { m_nType = MOD_TYPE_PAT; } else if ( type == "umx" ) { m_nType = MOD_TYPE_UMX; } else { m_nType = MOD_TYPE_IT; // fallback, most complex type } m_nChannels = mod->get_num_channels(); m_nMasterVolume = 128; m_nSamples = mod->get_num_samples(); update_state(); return TRUE; } catch ( ... ) { Destroy(); return FALSE; } } BOOL CSoundFile::Destroy() { mpcpplog(); if ( mod ) { delete mod; set_self( this, 0 ); } return TRUE; } UINT CSoundFile::GetNumChannels() const { mpcpplog(); return mod->get_num_channels(); } static std::int32_t vol128_To_millibel( unsigned int vol ) { return static_cast( 2000.0 * std::log10( static_cast( vol ) / 128.0 ) ); } BOOL CSoundFile::SetMasterVolume( UINT vol, BOOL bAdjustAGC ) { UNUSED(bAdjustAGC); mpcpplog(); m_nMasterVolume = vol; mod->set_render_param( openmpt::module::RENDER_MASTERGAIN_MILLIBEL, vol128_To_millibel( m_nMasterVolume ) ); return TRUE; } UINT CSoundFile::GetNumPatterns() const { mpcpplog(); return mod->get_num_patterns(); } UINT CSoundFile::GetNumInstruments() const { mpcpplog(); return mod->get_num_instruments(); } void CSoundFile::SetCurrentOrder( UINT nOrder ) { mpcpplog(); mod->set_position_order_row( nOrder, 0 ); update_state(); } UINT CSoundFile::GetSampleName( UINT nSample, LPSTR s ) const { mpcpplog(); char buf[32]; std::memset( buf, 0, 32 ); if ( mod ) { std::vector names = mod->get_sample_names(); if ( 1 <= nSample && nSample <= names.size() ) { std::strncpy( buf, names[ nSample - 1 ].c_str(), 31 ); } } if ( s ) { std::strncpy( s, buf, 32 ); } return static_cast( std::strlen( buf ) ); } UINT CSoundFile::GetInstrumentName( UINT nInstr, LPSTR s ) const { mpcpplog(); char buf[32]; std::memset( buf, 0, 32 ); if ( mod ) { std::vector names = mod->get_instrument_names(); if ( 1 <= nInstr && nInstr <= names.size() ) { std::strncpy( buf, names[ nInstr - 1 ].c_str(), 31 ); } } if ( s ) { std::strncpy( s, buf, 32 ); } return static_cast( std::strlen( buf ) ); } void CSoundFile::LoopPattern( int nPat, int nRow ) { UNUSED(nPat); UNUSED(nRow); mpcpplog(); // todo } void CSoundFile::CheckCPUUsage( UINT nCPU ) { UNUSED(nCPU); mpcpplog(); } BOOL CSoundFile::SetPatternName( UINT nPat, LPCSTR lpszName ) { UNUSED(nPat); mpcpplog(); if ( !lpszName ) { return FALSE; } // todo return TRUE; } BOOL CSoundFile::GetPatternName( UINT nPat, LPSTR lpszName, UINT cbSize ) const { UNUSED(nPat); mpcpplog(); if ( !lpszName || cbSize <= 0 ) { return FALSE; } std::memset( lpszName, 0, cbSize ); // todo return TRUE; } BOOL CSoundFile::ReadXM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadS3M(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadMod(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadMed(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadMTM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadSTM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadIT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::Read669(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadUlt(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadWav(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadDSM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadFAR(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadAMS(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadAMS2(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadMDL(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadOKT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadDMF(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadPTM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadDBM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadMT2(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadPSM(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadJ2B(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadUMX(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadABC(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::TestABC(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadMID(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::TestMID(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::ReadPAT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } BOOL CSoundFile::TestPAT(LPCBYTE lpStream, DWORD dwMemLength) { UNUSED(lpStream); UNUSED(dwMemLength); mpcpplog(); return FALSE; } #ifndef MODPLUG_NO_FILESAVE UINT CSoundFile::WriteSample( FILE * f, MODINSTRUMENT * pins, UINT nFlags, UINT nMaxLen ) { UNUSED(f); UNUSED(pins); UNUSED(nFlags); UNUSED(nMaxLen); mpcpplog(); return 0; } BOOL CSoundFile::SaveXM( LPCSTR lpszFileName, UINT nPacking ) { UNUSED(lpszFileName); UNUSED(nPacking); mpcpplog(); return FALSE; } BOOL CSoundFile::SaveS3M( LPCSTR lpszFileName, UINT nPacking ) { UNUSED(lpszFileName); UNUSED(nPacking); mpcpplog(); return FALSE; } BOOL CSoundFile::SaveMod( LPCSTR lpszFileName, UINT nPacking ) { UNUSED(lpszFileName); UNUSED(nPacking); mpcpplog(); return FALSE; } BOOL CSoundFile::SaveIT( LPCSTR lpszFileName, UINT nPacking ) { UNUSED(lpszFileName); UNUSED(nPacking); mpcpplog(); return FALSE; } #endif UINT CSoundFile::GetBestSaveFormat() const { mpcpplog(); return MOD_TYPE_IT; } UINT CSoundFile::GetSaveFormats() const { mpcpplog(); return MOD_TYPE_IT; } void CSoundFile::ConvertModCommand( MODCOMMAND * ) const { mpcpplog(); } void CSoundFile::S3MConvert( MODCOMMAND * m, BOOL bIT ) const { UNUSED(m); UNUSED(bIT); mpcpplog(); } void CSoundFile::S3MSaveConvert( UINT * pcmd, UINT * pprm, BOOL bIT ) const { UNUSED(pcmd); UNUSED(pprm); UNUSED(bIT); mpcpplog(); } WORD CSoundFile::ModSaveCommand( const MODCOMMAND * m, BOOL bXM ) const { UNUSED(m); UNUSED(bXM); mpcpplog(); return 0; } VOID CSoundFile::ResetChannels() { mpcpplog(); } UINT CSoundFile::CreateStereoMix( int count ) { UNUSED(count); mpcpplog(); return 0; } BOOL CSoundFile::FadeSong( UINT msec ) { UNUSED(msec); mpcpplog(); return TRUE; } BOOL CSoundFile::GlobalFadeSong( UINT msec ) { UNUSED(msec); mpcpplog(); return TRUE; } BOOL CSoundFile::InitPlayer( BOOL bReset ) { UNUSED(bReset); mpcpplog(); return TRUE; } BOOL CSoundFile::SetMixConfig( UINT nStereoSeparation, UINT nMaxMixChannels ) { UNUSED(nMaxMixChannels); mpcpplog(); m_nStereoSeparation = nStereoSeparation; return TRUE; } DWORD CSoundFile::InitSysInfo() { mpcpplog(); return 0; } void CSoundFile::SetAGC( BOOL b ) { UNUSED(b); mpcpplog(); } void CSoundFile::ResetAGC() { mpcpplog(); } void CSoundFile::ProcessAGC( int count ) { UNUSED(count); mpcpplog(); } BOOL CSoundFile::SetWaveConfig( UINT nRate, UINT nBits, UINT nChannels, BOOL bMMX ) { UNUSED(bMMX); mpcpplog(); gdwMixingFreq = nRate; gnBitsPerSample = nBits; gnChannels = nChannels; return TRUE; } BOOL CSoundFile::SetWaveConfigEx( BOOL bSurround, BOOL bNoOverSampling, BOOL bReverb, BOOL hqido, BOOL bMegaBass, BOOL bNR, BOOL bEQ ) { UNUSED(bSurround); UNUSED(bReverb); UNUSED(hqido); UNUSED(bMegaBass); UNUSED(bEQ); mpcpplog(); DWORD d = gdwSoundSetup & ~(SNDMIX_NORESAMPLING|SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE); if ( bNoOverSampling ) { d |= SNDMIX_NORESAMPLING; } else if ( !hqido ) { d |= 0; } else if ( !bNR ) { d |= SNDMIX_HQRESAMPLER; } else { d |= (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE); } gdwSoundSetup = d; return TRUE; } BOOL CSoundFile::SetResamplingMode( UINT nMode ) { mpcpplog(); DWORD d = gdwSoundSetup & ~(SNDMIX_NORESAMPLING|SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE); switch ( nMode ) { case SRCMODE_NEAREST: d |= SNDMIX_NORESAMPLING; break; case SRCMODE_LINEAR: break; case SRCMODE_SPLINE: d |= SNDMIX_HQRESAMPLER; break; case SRCMODE_POLYPHASE: d |= (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE); break; default: return FALSE; break; } gdwSoundSetup = d; return TRUE; } BOOL CSoundFile::SetReverbParameters( UINT nDepth, UINT nDelay ) { UNUSED(nDepth); UNUSED(nDelay); mpcpplog(); return TRUE; } BOOL CSoundFile::SetXBassParameters( UINT nDepth, UINT nRange ) { UNUSED(nDepth); UNUSED(nRange); mpcpplog(); return TRUE; } BOOL CSoundFile::SetSurroundParameters( UINT nDepth, UINT nDelay ) { UNUSED(nDepth); UNUSED(nDelay); mpcpplog(); return TRUE; } UINT CSoundFile::GetMaxPosition() const { mpcpplog(); // rows in original, just use seconds here if ( mod ) return static_cast( mod->get_duration_seconds() + 0.5 ); return 0; } DWORD CSoundFile::GetLength( BOOL bAdjust, BOOL bTotal ) { UNUSED(bAdjust); UNUSED(bTotal); mpcpplog(); if ( mod ) return static_cast( mod->get_duration_seconds() + 0.5 ); return 0; } UINT CSoundFile::GetSongComments( LPSTR s, UINT cbsize, UINT linesize ) { UNUSED(linesize); mpcpplog(); if ( !s ) { return 0; } if ( cbsize <= 0 ) { return 0; } if ( !mod ) { s[0] = '\0'; return 1; } std::strncpy( s, mod->get_metadata("message").c_str(), cbsize ); s[ cbsize - 1 ] = '\0'; return static_cast( std::strlen( s ) + 1 ); } UINT CSoundFile::GetRawSongComments( LPSTR s, UINT cbsize, UINT linesize ) { UNUSED(linesize); mpcpplog(); if ( !s ) { return 0; } if ( cbsize <= 0 ) { return 0; } if ( !mod ) { s[0] = '\0'; return 1; } std::strncpy( s, mod->get_metadata("message_raw").c_str(), cbsize ); s[ cbsize - 1 ] = '\0'; return static_cast( std::strlen( s ) + 1 ); } void CSoundFile::SetCurrentPos( UINT nPos ) { mpcpplog(); if ( mod ) mod->set_position_seconds( nPos ); update_state(); } UINT CSoundFile::GetCurrentPos() const { mpcpplog(); if ( mod ) return static_cast( mod->get_position_seconds() + 0.5 ); return 0; } static int get_stereo_separation() { mpcpplog(); return CSoundFile::m_nStereoSeparation * 100 / 128; } static int get_filter_length() { mpcpplog(); if ( ( CSoundFile::gdwSoundSetup & (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE) ) == (SNDMIX_HQRESAMPLER|SNDMIX_ULTRAHQSRCMODE) ) { return 8; } else if ( ( CSoundFile::gdwSoundSetup & SNDMIX_HQRESAMPLER ) == SNDMIX_HQRESAMPLER ) { return 4; } else if ( ( CSoundFile::gdwSoundSetup & SNDMIX_NORESAMPLING ) == SNDMIX_NORESAMPLING ) { return 1; } else { return 2; } } static std::size_t get_sample_size() { return (CSoundFile::gnBitsPerSample/8); } static std::size_t get_num_channels() { return CSoundFile::gnChannels; } static std::size_t get_frame_size() { return get_sample_size() * get_num_channels(); } static int get_samplerate() { return CSoundFile::gdwMixingFreq; } UINT CSoundFile::Read( LPVOID lpBuffer, UINT cbBuffer ) { mpcpplog(); if ( !mod ) { return 0; } mpcpplog(); if ( !lpBuffer ) { return 0; } mpcpplog(); if ( cbBuffer <= 0 ) { return 0; } mpcpplog(); if ( get_samplerate() <= 0 ) { return 0; } mpcpplog(); if ( get_sample_size() != 1 && get_sample_size() != 2 && get_sample_size() != 4 ) { return 0; } mpcpplog(); if ( get_num_channels() != 1 && get_num_channels() != 2 && get_num_channels() != 4 ) { return 0; } mpcpplog(); std::memset( lpBuffer, 0, cbBuffer ); const std::size_t frames_torender = cbBuffer / get_frame_size(); short * out = reinterpret_cast( lpBuffer ); std::vector tmpbuf; if ( get_sample_size() == 1 || get_sample_size() == 4 ) { tmpbuf.resize( frames_torender * get_num_channels() ); out = &tmpbuf[0]; } mod->set_render_param( openmpt::module::RENDER_STEREOSEPARATION_PERCENT, get_stereo_separation() ); mod->set_render_param( openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH, get_filter_length() ); std::size_t frames_rendered = 0; if ( get_num_channels() == 1 ) { frames_rendered = mod->read( get_samplerate(), frames_torender, out ); } else if ( get_num_channels() == 4 ) { frames_rendered = mod->read_interleaved_quad( get_samplerate(), frames_torender, out ); } else { frames_rendered = mod->read_interleaved_stereo( get_samplerate(), frames_torender, out ); } if ( get_sample_size() == 1 ) { unsigned char * dst = reinterpret_cast( lpBuffer ); for ( std::size_t sample = 0; sample < frames_rendered * get_num_channels(); ++sample ) { dst[sample] = ( tmpbuf[sample] / 0x100 ) + 0x80; } } else if ( get_sample_size() == 4 ) { int * dst = reinterpret_cast( lpBuffer ); for ( std::size_t sample = 0; sample < frames_rendered * get_num_channels(); ++sample ) { dst[sample] = tmpbuf[sample] << (32-16-1-MIXING_ATTENUATION); } } update_state(); return static_cast( frames_rendered ); } /* gstreamer modplug calls: mSoundFile->Create mSoundFile->Destroy mSoundFile->SetWaveConfig mSoundFile->SetWaveConfigEx mSoundFile->SetResamplingMode mSoundFile->SetSurroundParameters mSoundFile->SetXBassParameters mSoundFile->SetReverbParameters mSoundFile->GetMaxPosition (inline, -> GetLength) mSoundFile->GetSongTime mSoundFile->GetTitle (inline) mSoundFile->GetSongComments mSoundFile->SetCurrentPos mSoundFile->Read mSoundFile->GetCurrentPos mSoundFile->GetMusicTempo (inline) */ // really very internal symbols, probably nothing calls these directly #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunknown-pragmas" #pragma clang diagnostic ignored "-Wunused-parameter" #elif defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunknown-pragmas" #pragma GCC diagnostic ignored "-Wunused-parameter" #elif defined(_MSC_VER) #pragma warning(push) #pragma warning(disable:4100) #endif BOOL CSoundFile::ReadNote() { mpcpplog(); return 0; } BOOL CSoundFile::ProcessRow() { mpcpplog(); return 0; } BOOL CSoundFile::ProcessEffects() { mpcpplog(); return 0; } UINT CSoundFile::GetNNAChannel(UINT nChn) const { mpcpplog(); return 0; } void CSoundFile::CheckNNA(UINT nChn, UINT instr, int note, BOOL bForceCut) { mpcpplog(); } void CSoundFile::NoteChange(UINT nChn, int note, BOOL bPorta, BOOL bResetEnv) { mpcpplog(); } void CSoundFile::InstrumentChange(MODCHANNEL *pChn, UINT instr, BOOL bPorta,BOOL bUpdVol,BOOL bResetEnv) { mpcpplog(); } void CSoundFile::PortamentoUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::PortamentoDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::FinePortamentoUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::FinePortamentoDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::ExtraFinePortamentoUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::ExtraFinePortamentoDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::TonePortamento(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::Vibrato(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::FineVibrato(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::VolumeSlide(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::PanningSlide(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::ChannelVolSlide(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::FineVolumeUp(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::FineVolumeDown(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::Tremolo(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::Panbrello(MODCHANNEL *pChn, UINT param) { mpcpplog(); } void CSoundFile::RetrigNote(UINT nChn, UINT param) { mpcpplog(); } void CSoundFile::NoteCut(UINT nChn, UINT nTick) { mpcpplog(); } void CSoundFile::KeyOff(UINT nChn) { mpcpplog(); } int CSoundFile::PatternLoop(MODCHANNEL *, UINT param) { mpcpplog(); return 0; } void CSoundFile::ExtendedMODCommands(UINT nChn, UINT param) { mpcpplog(); } void CSoundFile::ExtendedS3MCommands(UINT nChn, UINT param) { mpcpplog(); } void CSoundFile::ExtendedChannelEffect(MODCHANNEL *, UINT param) { mpcpplog(); } void CSoundFile::ProcessMidiMacro(UINT nChn, LPCSTR pszMidiMacro, UINT param) { mpcpplog(); } void CSoundFile::SetupChannelFilter(MODCHANNEL *pChn, BOOL bReset, int flt_modifier) const { mpcpplog(); } void CSoundFile::DoFreqSlide(MODCHANNEL *pChn, LONG nFreqSlide) { mpcpplog(); } void CSoundFile::SetTempo(UINT param) { mpcpplog(); } void CSoundFile::SetSpeed(UINT param) { mpcpplog(); } void CSoundFile::GlobalVolSlide(UINT param) { mpcpplog(); } DWORD CSoundFile::IsSongFinished(UINT nOrder, UINT nRow) const { mpcpplog(); return 0; } BOOL CSoundFile::IsValidBackwardJump(UINT nStartOrder, UINT nStartRow, UINT nJumpOrder, UINT nJumpRow) const { mpcpplog(); return 0; } UINT CSoundFile::PackSample(int &sample, int next) { mpcpplog(); return 0; } BOOL CSoundFile::CanPackSample(LPSTR pSample, UINT nLen, UINT nPacking, BYTE *result) { mpcpplog(); return 0; } UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR pMemFile, DWORD dwMemLength) { mpcpplog(); return 0; } BOOL CSoundFile::DestroySample(UINT nSample) { mpcpplog(); return 0; } BOOL CSoundFile::DestroyInstrument(UINT nInstr) { mpcpplog(); return 0; } BOOL CSoundFile::IsSampleUsed(UINT nSample) { mpcpplog(); return 0; } BOOL CSoundFile::IsInstrumentUsed(UINT nInstr) { mpcpplog(); return 0; } BOOL CSoundFile::RemoveInstrumentSamples(UINT nInstr) { mpcpplog(); return 0; } UINT CSoundFile::DetectUnusedSamples(BOOL *) { mpcpplog(); return 0; } BOOL CSoundFile::RemoveSelectedSamples(BOOL *) { mpcpplog(); return 0; } void CSoundFile::AdjustSampleLoop(MODINSTRUMENT *pIns) { mpcpplog(); } BOOL CSoundFile::ReadInstrumentFromSong(UINT nInstr, CSoundFile *, UINT nSrcInstrument) { mpcpplog(); return 0; } BOOL CSoundFile::ReadSampleFromSong(UINT nSample, CSoundFile *, UINT nSrcSample) { mpcpplog(); return 0; } UINT CSoundFile::GetNoteFromPeriod(UINT period) const { mpcpplog(); return 0; } UINT CSoundFile::GetPeriodFromNote(UINT note, int nFineTune, UINT nC4Speed) const { mpcpplog(); return 0; } UINT CSoundFile::GetFreqFromPeriod(UINT period, UINT nC4Speed, int nPeriodFrac) const { mpcpplog(); return 0; } void CSoundFile::ResetMidiCfg() { mpcpplog(); } UINT CSoundFile::MapMidiInstrument(DWORD dwProgram, UINT nChannel, UINT nNote) { mpcpplog(); return 0; } BOOL CSoundFile::ITInstrToMPT(const void *p, INSTRUMENTHEADER *penv, UINT trkvers) { mpcpplog(); return 0; } UINT CSoundFile::SaveMixPlugins(FILE *f, BOOL bUpdate) { mpcpplog(); return 0; } UINT CSoundFile::LoadMixPlugins(const void *pData, UINT nLen) { mpcpplog(); return 0; } #ifndef NO_FILTER DWORD CSoundFile::CutOffToFrequency(UINT nCutOff, int flt_modifier) const { mpcpplog(); return 0; } #endif DWORD CSoundFile::TransposeToFrequency(int transp, int ftune) { mpcpplog(); return 0; } int CSoundFile::FrequencyToTranspose(DWORD freq) { mpcpplog(); return 0; } void CSoundFile::FrequencyToTranspose(MODINSTRUMENT *psmp) { mpcpplog(); } MODCOMMAND *CSoundFile::AllocatePattern(UINT rows, UINT nchns) { mpcpplog(); return 0; } signed char* CSoundFile::AllocateSample(UINT nbytes) { mpcpplog(); return 0; } void CSoundFile::FreePattern(LPVOID pat) { mpcpplog(); } void CSoundFile::FreeSample(LPVOID p) { mpcpplog(); } UINT CSoundFile::Normalize24BitBuffer(LPBYTE pbuffer, UINT cbsizebytes, DWORD lmax24, DWORD dwByteInc) { mpcpplog(); return 0; } #if defined(__clang__) #pragma clang diagnostic pop #elif defined(__GNUC__) #pragma GCC diagnostic pop #elif defined(_MSC_VER) #pragma warning(pop) #endif #endif // NO_LIBMODPLUG